1

I have just learnt how to use Hibernate today, and I am messing with a small database.

public class HibernateQuery {

    private static final SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
    private static final Session session = sessionFactory.getCurrentSession();

    public static void main(String[] args) {
        queryA();
        queryB();
        session.close();
        sessionFactory.close();
    }

    public static void queryA() {
        Transaction tx = session.beginTransaction();
        List<GradesJPA> lst = session.createQuery("from GradesJPA", GradesJPA.class).list();
        for(GradesJPA each : lst) {
            System.out.println(each);
        }
        tx.commit();
    }

    public static void queryB() {
        Transaction tx = session.beginTransaction();
        List<String> lst = session.createQuery("select g.className from GradesJPA g", String.class).list();
        for(String each : lst) {
            System.out.println(each);
        }
        tx.commit();
    }
}

I get the error Session/EntityManager is closed, after successfully finishing the first query. The solution to the problem is simple. Declare a session for each query(), instead of for the class. However, can someone please explain to me why? (Also, can you please tell me if I need to close the individual sessions created in each method?)

From what I have read, committing a transaction does not close the session: Does committing transaction close session?

From the docs, the only thing I understand is the session-per-operation anti-pattern, but somehow, I am forced to open a new session after each query().

There is also this suggestion, session/entitymanager is closed, and another on the Hibernate forum that advises against class-wide session because of concurrency problems. But I suspect that my code is not running in parallel with anything else.

This is the whole error printed:

Exception in thread "main" java.lang.IllegalStateException: Session/EntityManager is closed
    at org.hibernate.internal.AbstractSharedSessionContract.checkOpen(AbstractSharedSessionContract.java:360)
    at org.hibernate.engine.spi.SharedSessionContractImplementor.checkOpen(SharedSessionContractImplementor.java:139)
    at org.hibernate.internal.AbstractSharedSessionContract.beginTransaction(AbstractSharedSessionContract.java:465)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:350)
    at com.sun.proxy.$Proxy33.beginTransaction(Unknown Source)
    at hibernate.HibernateQuery.queryB(HibernateQuery.java:38)
    at hibernate.HibernateQuery.main(HibernateQuery.java:18)

Thank you.

Biliking
  • 136
  • 1
  • 10
  • 1
    `getCurrentSession()` produces a `Session` that closes automatically once the transaction is commited. You want `openSession()` instead – crizzis Oct 25 '20 at 19:57
  • 1
    Alternatively, if you insist on using `getCurrentSession()`, see [this answer](https://stackoverflow.com/a/45733794/1092818) – crizzis Oct 25 '20 at 20:09

0 Answers0