Java 春季交易及;休眠:延迟初始化

Java 春季交易及;休眠:延迟初始化,java,hibernate,spring,transactions,lazy-initialization,Java,Hibernate,Spring,Transactions,Lazy Initialization,从我目前所读到的内容来看,我理解使用事务将是解决hibernate延迟加载问题的方法。会话将在服务层中的整个事务期间可用,无需进一步的adue 那么,也许我错误地配置了我的事务管理?说到春天和冬眠,我其实是个新手,但也许你们可以帮我 我的配置: <bean class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" id="sessionFactory"> <property name="

从我目前所读到的内容来看,我理解使用事务将是解决hibernate延迟加载问题的方法。会话将在服务层中的整个事务期间可用,无需进一步的adue

那么,也许我错误地配置了我的事务管理?说到春天和冬眠,我其实是个新手,但也许你们可以帮我

我的配置:

<bean class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
    id="sessionFactory">
    <property name="configLocation">
        <value>classpath:hibernate.cfg.xml</value>
    </property>
</bean>
<!-- Hibernate Template bean that will be assigned to DAOs. -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
    <property name="sessionFactory">
        <ref bean="sessionFactory" />
    </property>
</bean>

<!--
    Transaction manager for a single Hibernate SessionFactory (alternative
    to JTA)
-->
<bean id="transactionManager"
    class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory">
        <ref local="sessionFactory" />
    </property>
</bean>

<tx:annotation-driven transaction-manager="transactionManager" />
使用
@Service(readOnly=false)
注释,如果在该特定方法中实际保存/更新了任何内容

我是否需要配置其他配置以确保我可以在服务中加载正确的关联,或者这通常由事务处理?


现在我只是有点困惑我到底应该做什么,所以请帮助我:)

延迟加载问题和事务之间并没有真正的联系。但这是另一个故事:) 除了访问bean中的会话之外,您已经做得很好了。不知道你要怎么做。标准解决方案(在Spring2.x中,对3.x不太清楚,还没有找到)是使用HibernateDaoSupport作为基类,用于您将要访问会话的类。但就我个人而言,这看起来有点可疑,因为它增加了对特定于Spring的类的依赖。更好的方法是将会话注入到bean中。要做到这一点,您需要使用与该会话bean类似的定义声明会话bean:

<bean name="hibernateSession" class="org.springframework.orm.hibernate3.SessionFactoryUtils" factory-method="getSession"
  scope="prototype">
    <constructor-arg index="0" ref="hibernateSessionFactory"/>
    <constructor-arg index="1" value="false"/>
    <aop:scoped-proxy/>
</bean>


我想我对春天的理解到现在还很糟糕;我们的会话管理确实没有真正的管理。基本上现在发生的是:您可以从DAO获取数据,但是在收到数据之后,您甚至无法加载惰性集合,因为会话已关闭

现在我们使用hibernate拦截器,它在每个请求开始时将会话附加到线程,并在请求结束时关闭会话。这并不总是最理想的解决方案,但对于一个学校项目,我不会太费心

另一种解决方案似乎是:添加AOP的方式是使用
@around
,该会话仅在服务方法调用期间可用。我认为这是最好的解决方案,不过,我现在不打算为这个项目深入挖掘。好在我知道它的存在

这篇文章也给了我很多帮助:

对于那些感兴趣的人:这里是我必须补充的:在SpringMVC3.0中有一个名为
MVC:intereceptors
的新特性,它使我可以输入更少的xml

<!-- WEB-INF/applicationContext.xml or your own XML config file -->
<mvc:interceptors>
    <bean
        class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
        <property name="sessionFactory">
            <ref local="sessionFactory" />
        </property>
    </bean>
</mvc:interceptors>


使用模板不是“标准”解决方案,它只是自2007年以来不被真正推荐的一个选项。只要插入
sessionFactory
并使用
sessionFactory.getCurrentSession()
就可以了。请参阅。仅为了避开调用sessionFactory.getCurrentSession()的麻烦,这是一个相当惊人的间接过程。我不知道在会话的每个方法调用中插入getBean()会对性能产生什么影响。我一直在DAO中使用“HibernateDataOSupport”类的扩展(并将其注入)。但是我如何让我的会话在我的服务和DAO中可用,或者这是一件不自然的事情?其他人建议使用:;由于这会在每次请求时将会话绑定到线程上。(所以是的:我正在制作一个webapp)@toomuchcs,您发布的配置没有任何明显的问题。也许会发布一些实际不起作用的代码?扩展事务范围并不是一个灵丹妙药,您仍然可能会犯很多错误。OSIV通常是针对延迟加载异常的全面修复程序,但它确实需要程序员真正了解ORM的工作原理以及连接到会话的含义,否则最终会出现意外的版本号突变和数据库中的瞬态数据。@Pascal Thivent。谢谢你的链接。除了需要手动调用getCurrentSession来获取会话之外,我的方法与本文中描述的几乎相同。同意,这并没有什么区别:)我之所以称之为“标准”,是因为Spring2.x文档引用了它。
<!-- WEB-INF/applicationContext.xml or your own XML config file -->
<mvc:interceptors>
    <bean
        class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
        <property name="sessionFactory">
            <ref local="sessionFactory" />
        </property>
    </bean>
</mvc:interceptors>