春季交易&休眠:延迟初始化
从到目前为止我所读到的内容来看,我了解到使用事务将是解决 hibernate 延迟加载问题的方法。会话将在服务层的整个事务期间可用,无需进一步等待。
那么也许我错误地配置了我的事务管理?对于 Spring 和 Hibernate,我实际上是一个新手,但也许你们可以帮助我。
我的配置:
<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
bean。
服务实现的典型标头如下:
@Service
@Transactional(readOnly=true)
public class LeerlingServiceImpl implements LeerlingService {
@Autowired
LeerlingDAO leerlingDAO;
@Autowired
LeerplanDAO leerplanDAO;
如果在该特定方法中实际保存/更新了任何内容,则使用 @Service(readOnly=false)
注释。
我是否需要配置其他内容以确保我可以在我的服务中加载正确的关联,或者这通常由事务处理?
现在我对我实际应该做什么有点困惑,所以请帮助我:)
From what I've read so far I had the understanding that using transactions would be the solution to hibernate's lazy loading problems. The session would be available during the whole transaction in the service layer without further adue.
So maybe I misconfigured my transaction management? I'm actually a newb when it comes to spring and hibernate, but maybe you guys could help me out.
My configuration:
<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" />
My DAO implementation would simply have a @Repository
annotation and a Hibernate-template
bean injected using autowiring.
A typical header of a service Implementation would be:
@Service
@Transactional(readOnly=true)
public class LeerlingServiceImpl implements LeerlingService {
@Autowired
LeerlingDAO leerlingDAO;
@Autowired
LeerplanDAO leerplanDAO;
With a @Service(readOnly=false)
annotation if anything is actually saved/updated in that particular method.
Do I need to configure something else to make sure that I can load the right associations in my Service, or is this normally handled by transactions?
Right now I am just a bit confused of what I should actually do, so please help me:)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
延迟加载问题和事务并没有真正相关。但这是另一个故事了:)
除了访问 Bean 中的会话之外,您已经做得很好了。不知道你将如何做到这一点。标准解决方案(在 spring 2.x 中,不确定 3.x,还没有看过)是使用 HibernateDaoSupport 作为您要访问会话的类的基类。但就我个人而言,这对我来说看起来有点狡猾,因为增加了对 Spring 特定类的依赖。更好的方法是将会话注入到您的 bean 中。为此,您需要使用类似于该定义的会话 bean 来声明:
然后使用它。
以下是详细信息:
http://stas-blogspot.blogspot .com/2009/10/hibernate-spring-in-standalone.html
Lazy-loading problems and transactions are not really related one to other. But that's another story :)
You've done all well, apart from the access to session in your beans. No sure how you are going to do this. The standard solution (in spring 2.x, not sure about 3.x, haven't looked yet) is to use HibernateDaoSupport as base class for classes were you are going to have an access to session. But personally that looks a little dodgy to me, because adds dependency on Spring-specific classes. Better way is to inject session into your beans. To do this you need to declare your session bean with definition similar to that one:
and then just use it.
Here are details:
http://stas-blogspot.blogspot.com/2009/10/hibernate-spring-in-standalone.html
我认为到目前为止我对 Spring 的理解还很差;我们的会话管理确实没有真正的管理。基本上现在发生的情况是:您可以从 DAO 获取数据,但在收到数据后,您甚至无法加载惰性集合,因为会话已关闭。
现在我们使用 hibernate 拦截器,它在每个请求开始时将会话附加到线程,并在请求结束时将其关闭。这并不总是最理想的解决方案,但对于学校项目我不会太担心。
另一种解决方案似乎是:以使用
@around
的方式添加 AOP,会话仅在服务方法调用期间可用。我认为这是最好的解决方案,但我现在不打算深入研究这个项目。好消息是我知道它的存在。这篇文章也对我有很大帮助: http://www.jroller.com/kbaum/entry/orm_lazy_initialization_with_dao
对于那些感兴趣的人:这是我必须添加的内容:在 Spring MVC 3.0 中,有一个名为
mvc:intereceptors
的新功能,它使我输入的 xml 更少。I think my understanding of Spring was just bad till now; there was indeed no real management for our session management. Basically what now happened was: you could get data from the DAO, but right after you received it you couldn't even get lazy collections loaded because the session was closed.
Now we are using the hibernate interceptor, which attaches the session to the thread at the beginning of each request and closes it when it ends. This is not always the most ideal solution, but for a school project I wouldn't bother too much.
The other solution seems to be: add AOP in a way that
@around
is used that the session is only available during a service method call. I think this is the best solution, though, I'm not going to dig that deeply right now for this project. The good thing is that I know it exists.This article also helped me a lot: http://www.jroller.com/kbaum/entry/orm_lazy_initialization_with_dao
To those interested: here is what I had to add: In Spring MVC 3.0 there is a new feature called
mvc:intereceptors
which made me type less xml.