I have a REST API and when I make a POST and a GET nearly the same time I get this exception:
SEVERE: The RuntimeException could not be mapped to a response, re-throwing to the HTTP container
java.lang.IllegalStateException: Transaction already active
at org.hibernate.engine.transaction.internal.TransactionImpl.begin(TransactionImpl.java:52)
at org.hibernate.internal.AbstractSharedSessionContract.beginTransaction(AbstractSharedSessionContract.java:409)
at sun.reflect.GeneratedMethodAccessor89.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:355)
at com.sun.proxy.$Proxy58.beginTransaction(Unknown Source)
at utils.HibernateSession.createTransaction(HibernateSession.java:15)
at api.ConversationsREST.getMessages(ConversationsREST.java:128)
They are on different classes so no global attributes implied.
The line which fails is this one:
HibernateSession hs = new HibernateSession();
hs.createTransaction(); // Crash
Which refers to my class HibernateSession:
public class HibernateSession {
public Session session;
public void createTransaction() {
session = HibernateUtil.getSessionFactory().getCurrentSession(); //THIS WAS WRONG
//EDIT:session = HibernateUtil.getSessionFactory().openSession(); //THIS IS RIGHT
session.beginTransaction();
}
public void commitclose() {
session.getTransaction().commit();
session.close();
}
public void rollbackclose() {
try {
session.getTransaction().rollback();
session.close();
} catch (Exception hibernateexception) {
hibernateexception.printStackTrace();
}
}
}
The exception is actually on the line session.beginTransaction()
I always make a hs.commitclose() and in the catch() blocks and the 404s I always make a rollbackclose();
The problem is that when I make a POST messages like this:
HibernateSession hs = new HibernateSession();
hs.createTransaction();
hs.session.save(whatever);
hs.commitclose();
Returns 200 and it's ok but then the GET may crash with the exception above. As I am making a new instance of HibernateSession, why Hibernate seems to be trying to share that transaction?
This only happens when I make both queries in a very short time (I guess starting a transaction between the beginning and the commit of another one). So I guess Hibernate is thinking that session attribute is static or something like that...
Thank you in advance for your help!
EDIT: As requested, HibernateUtil.java
(the problem must not be here but may help to understand):
package utils;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static SessionFactory sessionFactory;
public static SessionFactory getSessionFactory() {
if (sessionFactory == null) {
sessionFactory = build();
}
return sessionFactory;
}
private static SessionFactory build() {
try {
return new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed: " + ex);
throw new ExceptionInInitializerError(ex);
}
}
}