Java hibernate jpa:会话已关闭!
该应用程序基于Spring2.5.5和Hibernate3.2.0GA 我的DAO中有以下方法,用于获取附加到指定用户的MessageEntities: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
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)