Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java hibernate jpa:会话已关闭!_Java_Hibernate_Spring_Jpa_Transactions - Fatal编程技术网

Java hibernate jpa:会话已关闭!

Java hibernate jpa:会话已关闭!,java,hibernate,spring,jpa,transactions,Java,Hibernate,Spring,Jpa,Transactions,该应用程序基于Spring2.5.5和Hibernate3.2.0GA 我的DAO中有以下方法,用于获取附加到指定用户的MessageEntities: public MessageEntity findByUserId(int userId) { List<MessageEntity> result = (List<MessageEntity>) em.createNamedQuery(MessageEntity.Q_BY_USER_ID).setParam

该应用程序基于Spring2.5.5和Hibernate3.2.0GA

我的DAO中有以下方法,用于获取附加到指定用户的MessageEntities:

public MessageEntity findByUserId(int userId) {
      List<MessageEntity> result = (List<MessageEntity>) em.createNamedQuery(MessageEntity.Q_BY_USER_ID).setParameter("userId", userId).getResultList();
      if (!result.isEmpty()) {
         return result.get(0);
      } else {
         return null;
     }
}
我需要在集成测试中调用此方法,以检查系统的行为是否有效。只要这个方法不是事务性的,我得到的就是org.hibernate.SessionException:会话已关闭!。避免这种情况的最简单方法是使用@TransactionalreadOnly=true标记findByUserId方法。但据我所知,事务管理应该是服务层的职责,以避免不必要的事务创建。因此,我的问题是:如何才能正确地避开SessionException?

您需要在事务范围内执行所有数据库操作。正如您所确定的,它通常被认为是让数据库模型的服务层处理事务的好设计。唯一的约束是,您必须调用您的服务模型才能进入事务范围,这在测试期间可能是不需要的

我建议使用spring提供的测试fascilite。看

您还可以在测试方法之前手动创建事务,例如

Session sess = factory.openSession();
Transaction tx = null;
// try catch 
tx = sess.beginTransaction();
findByUserId(userId);
tx.commit();
tx.rollBack();

将以下注释放在测试类的顶部

@RunWith(SpringJUnit4ClassRunner.class)
@Transactional
@ContextConfiguration(locations = "classpath:/META-INF/spring/applicationContext.xml")
此外,我也不担心在DAO中添加额外的@Transactional。 Spring在创建另一个线程之前,通常会检查您是否已经在同一线程中的事务中

但据我所知,交易 管理是企业的职责 服务层,以避免不必要的 事务创建


例如,Spring Roo违反了这一点

您可以在控制器方法上使用此注释:

@Transactional(readOnly = true)