Pregunta

I am trying to use Criteria API from Hibernate by getting hibernate session from EntityManager as following

public org.hibernate.Criteria getCriteria() {
    HibernateEntityManager hem = em.unwrap(HibernateEntityManager.class);
    org.hibernate.Session session = hem.getSession();
    return session.createCriteria(getEntityBeanType());
}

In createCriteria return I am getting "session is closed error".

From the same point of code where I call getCriteria if I call createQuery method as

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

It is working fine and I can do select on database.

I want to use Hibernate Criteria API becuase I am comfortable with it.

¿Fue útil?

Solución 2

Make sure if your session is open before you create criteria

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;
}

Check your log for more information and share the same here and it will be helpful for us to debug...

Otros consejos

The point here is that Criteria object exists only when Session object is open, if the Session object has been closed Criteria object won't work, there is a class named DetachedCriteria that allows the developer create Criteria queries outside of Session object then attach them to it and be able to run. Read more about Detached here

Detached criteria is very good alternate when the hibernate session is not present

You can use something like this.

//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();

I've been seeing the same problem. It comes out of the improper use of the @Transactional annotation. Here's what I was doing:

doStuff(String[] ids) {
  Criteria criteria = dao.createCriteria(Widget.class); // Session still open here.
  criteria.add(Restrictions.in("widgetId", ids)); // This closed the session!
  ...
}

It turns out that my dao class was annotated with the @Transactional annotation. So as soon as I tried to do something with my Criteria, it first closed the transaction, which closes the session. The solution was get rid of the dao's createCriteria() method and to add a method to the dao that does all the work with that uses the Criteria instance.

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
  ...
}

The way I've structured my code, the Criteria should be an internal implmentation detail of the DAO, and shouldn't be visible to the calling methods.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top