2010-10-21 117 views
0

从我读到目前为止,我有一个理解,使用事务将是解决休眠的延迟加载问题。该会话将在服务层的整个事务期间可用,而不会有进一步的争议。春季交易和休眠:延迟初始化

所以,也许我错误配置了我的事务管理?当谈到春季和冬眠时,我其实是一个新手,但也许你们可以帮助我。

我的配置:

<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" /> 

我的DAO实现只会有一个@Repository注释和使用自动装配一个Hibernate-template豆注入。

服务实现的一个典型的头应该是:

@Service 
@Transactional(readOnly=true) 
public class LeerlingServiceImpl implements LeerlingService { 

    @Autowired 
    LeerlingDAO leerlingDAO; 
    @Autowired 
    LeerplanDAO leerplanDAO; 

随着@Service(readOnly=false)注释如果有什么实际保存/更新,在那个特定的方法。

我需要配置别的东西来确保我可以在我的服务中加载正确的关联,或者通常是通过事务处理吗?

现在我只是有点困惑的是我应该做其实所以请帮我:)

回答

1

延迟加载问题和交易并没有真正涉及到一个其他。但这是另一个故事:) 除了在bean中访问会话之外,你已经做得很好。不知道你将如何去做这件事。标准解决方案(在Spring 2.x中,不确定关于3.x,还没有看过)是使用HibernateDaoSupport作为类的基类,你将有权访问会话。但个人来说,这看起来有点狡猾,因为它增加了对Spring特定类的依赖。更好的方法是将会话注入到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> 

然后就使用它。

下面是详细介绍:

http://stas-blogspot.blogspot.com/2009/10/hibernate-spring-in-standalone.html

+0

使用模板是不是“标准”的解决方案,这其中是不是真的建议自2007年以来就注入'sessionFactory'和使用'sessionFactory.getCurrentSession()'如果你想要去的模板只是一个选项-减。看[所以你应该仍然使用Spring的HibernateTemplate和/或JpaTemplate ??](http://blog.springsource.com/2007/06/26/so-should-you-still-use-springs-hibernatetemplate-andor-jpatemplate /)。 – 2010-10-22 00:13:24

+0

为了避免调用sessionFactory.getCurrentSession(),这是一个相当惊人的间接量。不知道在Session上的每个方法调用中插入getBean()会带来怎样的性能影响。 – Affe 2010-10-22 00:27:45

+0

我一直在我的DAO中使用“hibernateDAOSupport”类的扩展(并注入它)。但是,如何让我的会话在我的服务和DAO中可用或者这是一件不自然的事情?其他人建议使用:http://community.jboss.org/wiki/OpenSessioninView;因为这会将会话绑定到每个请求的线程(所以是:我正在制作一个web应用程序) – toomuchcs 2010-10-22 06:35:26

1

我想我春的认识只是坏到现在为止;我们的会议管理确实没有真正的管理。基本上现在发生的事情是:你可以从DAO获取数据,但是在收到它之后,你甚至无法加载懒惰的集合,因为会话已关闭。

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

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

本文还帮了我很多:http://www.jroller.com/kbaum/entry/orm_lazy_initialization_with_dao

对于那些感兴趣的是:这里是我不得不补充:在Spring MVC的3.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>