在我的项目中,我使用带有程序化事务划分的 Hibernate。 每次在我的 Service 方法中,我都会写一些类似的东西。
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
.. perform operation here
session.getTransaction().commit();
现在我将使用声明式事务管理重构我的代码。我现在得到了什么......
<context:component-scan base-package="package.*"/>
<bean id="mySessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
</bean>
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="mySessionFactory"/>
</property>
</bean>
服务类:
@Service
public class TransactionalService {
@Autowired
private SessionFactory factory;
@Transactional
public User performSimpleOperation() {
return (User)factory.getCurrentSession().load(User.class, 1L);
}
}
还有简单的测试-
@Test
public void useDeclarativeDem() {
FileSystemXmlApplicationContext ctx = new FileSystemXmlApplicationContext("spring-config.xml");
TransactionalService b = (TransactionalService)ctx.getBean("transactionalService");
User op = b.performSimpleOperation();
op.getEmail();
当我尝试在 Transactional 方法之外获取用户电子邮件时,我遇到了延迟初始化异常,我的情况是电子邮件是一个简单的字符串。在我调用 POJO 上的任何 getter 之前,Hibernate 甚至不执行 sql 查询。
我在这里做错了什么?
这种方法有效吗?
您能否推荐任何可在 spring/hibernate 上使用基于注释的配置的开源项目?
更新
出于某种原因,如果我将 getCurrentSession 替换为 openSession,则此代码可以正常工作。谁能解释一下?
最佳答案
好吧,我终于意识到问题所在了。在上面的代码中,我使用加载而不是获取。 Session.load 实际上并没有命中数据库。这就是我在@Transactional 方法之外得到延迟初始化异常的原因
如果我使用 openSession 而不是 getCurrentSession, session 将在 spring 容器范围之外打开。结果 session 没有关闭,它允许我读取 @Transactional 方法之外的对象属性
关于java - Spring 中的 Hibernate 事务管理器配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5135204/