我试图通过从EntityManager获取hibernate会话来使用来自Hibernate的Criteria API,如下所示
public org.hibernate.Criteria getCriteria() {
HibernateEntityManager hem = em.unwrap(HibernateEntityManager.class);
org.hibernate.Session session = hem.getSession();
return session.createCriteria(getEntityBeanType());
}
在createCriteria返回时,我收到“会话已关闭错误”。
从我调用getCriteria的代码的相同点,如果我将createQuery方法称为
getEntityManager().createQuery(".....");
它工作正常,我可以在数据库上选择。
我想使用Hibernate Criteria API,因为我很满意。
答案 0 :(得分:1)
这里的重点是Criteria对象仅在Session对象打开时存在,如果Session对象已经关闭Criteria对象不起作用,有一个名为DetachedCriteria
的类允许开发人员创建Criteria在Session对象之外的查询然后将它们附加到它并能够运行。阅读有关已分离here
当休眠会话不存在时,分离标准是非常好的替代
你可以使用这样的东西。
//Not required a session open
DetachedCriteria query = DetachedCriteria.forClass(Employee.class);
query.add(Property.forName("name").eq("Som"));
//Here we open the session
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
List<Employee> employeeList = new ArrayList<Employee>();
//Then we associate the criteria query with the session and run it
employeeList = query.getExecutableCriteria(session).list();
Iterator it = employeeList.iterator();
答案 1 :(得分:0)
在创建条件之前确保您的会话已打开
public org.hibernate.Criteria getCriteria() {
HibernateEntityManager hem = em.unwrap(HibernateEntityManager.class);
org.hibernate.Session session = hem.getSession();
if(session.isOpen())
{
return session.createCriteria(getEntityBeanType())
}
return null;
}
检查您的日志以获取更多信息,并在此处共享相同内容,这将有助于我们调试...
答案 2 :(得分:0)
我一直在看同样的问题。它来自于@Transactional注释的不当使用。这就是我在做的事情:
doStuff(String[] ids) {
Criteria criteria = dao.createCriteria(Widget.class); // Session still open here.
criteria.add(Restrictions.in("widgetId", ids)); // This closed the session!
...
}
事实证明,我的dao类使用@Transactional
注释进行了注释。因此,只要我尝试使用我的Criteria执行某些操作,它就会先关闭事务,然后关闭会话。解决方案是摆脱dao的createCriteria()
方法并向dao添加一个方法,该方法使用Criteria实例完成所有工作。
doStuff(String[] ids) {
List<Widget> = dao.getWidgetsFromIds(ids); // Do everything inside the transaction
...
}
----
// This is in the DAO:
public List<Widget> getWidgetsFromIds(String[] ids) {
Criteria criteria = dao.createCriteria(Widget.class); // Session is open here.
criteria.add(Restrictions.in("widgetId", ids)); // Session still open
...
}
我构建代码的方式,标准应该是DAO的内部细节,并且不应该对调用方法可见。