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.