使用Hibernate 4和Spring 3.1。刚开始运行它,所以这可能是我缺乏理解。我在Service类中有一个方法,它调用DAO类中的方法以使用Hibernate检索一些数据。我使用@Transactional注释Service方法,但在DAO方法中调用getCurrentSession时出错。如果我使用@Transactional注释DAO方法,则成功检索数据。我不明白为什么 - 我会想到Service方法上的@Transactional注释会创建一个Hibernate会话,将它绑定到线程,并且当调用getCurrentSession时,会话将在DAO类中返回。任何人都可以解释为什么会这样,或者我做错了什么,谢谢?
根的context.xml:
<tx:annotation-driven transaction-manager="transactionManager"/>
服务类:
public class BlahServiceImpl implements BlahService {
@Transactional
public Blah GetMostRecentBlah() {
BlahDAO blahDAO = DAOFactory.GetBlahDAO();
return blahDAO.GetMostRecentBlah();
}
}
DAO课程:
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public Blah GetMostRecentBlah() {
return (Blah)sessionFactory.getCurrentSession().createQuery("from Blah where blahID = (select max(blahID) from Blah)").uniqueResult();
}
错误:
org.hibernate.HibernateException: No Session found for current thread
org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)
org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1039)
com.blah.blah.DAO.BlahDAOImpl.GetMostRecentBlah(BlahDAOImpl.java:18)
就像我说的,如果我使用@Transactioanl(以及Service方法)注释DAO函数,这可行,但我不明白为什么。
答案 0 :(得分:3)
两个可能的原因表明了自己。
1)您的服务bean位于单独的ApplicationContext中,该ApplicationContext没有启用注释驱动的事务。
2)您正在获取对您的服务实例的引用,该实例是原始实例,而不是代理的,因此是事务性实例。
要确定哪个是您的问题,或确定是否存在其他问题,请显示导致您的服务bean创建的上下文文件,并显示您获取服务实例的代码。
答案 1 :(得分:1)
解决方案可能是:
<tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager" />
因为没有代理类。
否则,如果你必须将私有方法代理为事务性(就像我所面对的那样),你最终可能会添加aspectj而不是cglib,然后配置可能有帮助
<!-- switches on the load-time weaving -->
<context:load-time-weaver />
<!-- proxies classes with aspectj and you may have @Transaction annotations for managing transactions-->
<tx:annotation-driven proxy-target-class="true" mode="aspectj" transaction-manager="transactionManager" />
之后用jvm参数启动服务器
-javaagent:/path-to/spring-instrument-{spring-version}.jar