0

我正在尝试通过从 EntityManager 获取休眠会话来使用 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 返回中,我收到“会话已关闭错误”。

如果我调用 createQuery 方法,则从我调用 getCriteria 的同一代码点

getEntityManager().createQuery(".....");

它工作正常,我可以在数据库上进行选择。

我想使用 Hibernate Criteria API,因为我对它很满意。

4

3 回答 3

1

这里的重点是 Criteria 对象仅在 Session 对象打开时存在,如果 Session 对象已关闭 Criteria 对象将不起作用,有一个名为的类DetachedCriteria允许开发人员在 Session 对象之外创建 Criteria 查询然后将它们附加到它并且能够运行。在此处阅读有关分离的更多信息

当休眠会话不存在时,分离标准是非常好的替代

你可以使用这样的东西。

//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();
于 2014-03-13T06:26:35.647 回答
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;
}

检查您的日志以获取更多信息并在此处分享,这将有助于我们调试...

于 2014-03-13T06:17:59.093 回答
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
  ...
}

按照我构建代码的方式,Criteria 应该是 DAO 的内部实现细节,并且不应该对调用方法可见。

于 2017-05-02T02:15:36.150 回答