Spring中的Hibernate事务管理器配置

use*_*512 11 java spring hibernate spring-transactions

在我的项目中,我使用Hibernate进行程序化事务划分.每次在我的服务方法中,我都会写一些类似的东西.

Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
.. perform operation here
session.getTransaction().commit();
Run Code Online (Sandbox Code Playgroud)

现在,我将使用声明式事务管理来重构我的代码.我现在得到了什么......

  <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>
Run Code Online (Sandbox Code Playgroud)

服务类:

@Service
public class TransactionalService {

    @Autowired
    private SessionFactory factory;

    @Transactional
    public User performSimpleOperation() {
        return (User)factory.getCurrentSession().load(User.class, 1L);
    }
}
Run Code Online (Sandbox Code Playgroud)

而且简单的测试 -

@Test
public void useDeclarativeDem() {
    FileSystemXmlApplicationContext ctx = new FileSystemXmlApplicationContext("spring-config.xml");
    TransactionalService b = (TransactionalService)ctx.getBean("transactionalService");
     User op = b.performSimpleOperation();
     op.getEmail();
Run Code Online (Sandbox Code Playgroud)

当我尝试在Transactional方法之外获取用户电子邮件时,我得到了Lazy初始化异常,电子邮件是我的情况是一个简单的字符串.Hibernate甚至不执行sql查询,直到我在我的POJO上调用任何getter.

1)我在这里做错了什么?

2)这种方法有效吗?

3)您能否建议任何基于注释的配置在spring/hibernate上工作的开源项目?

更新

出于某种原因,如果我用openSession替换getCurrentSession,这段代码工作正常.有人可以解释一下吗?

谢谢

use*_*512 11

好的,最后我意识到问题是什么.在上面的代码中,我使用load而不是get.Session.load实际上没有击中数据库.这就是为什么我在@Transactional方法之外得到延迟初始化异常的原因

如果我使用openSession而不是getCurrentSession,则会在范围弹簧容器之外打开会话.结果会话没有关闭,它允许我读取@Transactional方法之外的对象属性