Lors de l'exécution de la méthode removeUserFromConference, obtention de cette exception:
04/06/2012 00:20:48 org.Apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [ConferenceServlet] in context with path [/conf4u] threw exception
org.hibernate.TransactionException: nested transactions not supported
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.Java:152)
at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.Java:1396)
at Sun.reflect.GeneratedMethodAccessor39.invoke(Unknown Source)
at Sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at Java.lang.reflect.Method.invoke(Unknown Source)
at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.Java:352)
at $Proxy12.beginTransaction(Unknown Source)
at daos.ConferenceDao.isConferenceNameExists(ConferenceDao.Java:129)
at servlets.ConferenceServlet.removeUser(ConferenceServlet.Java:232)
at servlets.ConferenceServlet.processRequest(ConferenceServlet.Java:79)
at servlets.ConferenceServlet.doPost(ConferenceServlet.Java:433)
at javax.servlet.http.HttpServlet.service(HttpServlet.Java:641)
at javax.servlet.http.HttpServlet.service(HttpServlet.Java:722)
at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:305)
at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:210)
at org.Apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.Java:224)
at org.Apache.catalina.core.StandardContextValve.invoke(StandardContextValve.Java:169)
at org.Apache.catalina.core.StandardHostValve.invoke(StandardHostValve.Java:168)
at org.Apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.Java:98)
at org.Apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.Java:928)
at org.Apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.Java:118)
at org.Apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.Java:407)
at org.Apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.Java:987)
at org.Apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.Java:539)
at org.Apache.Tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.Java:298)
at Java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at Java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at Java.lang.Thread.run(Unknown Source)
04/06/2012 00:27:15 org.Apache.catalina.core.StandardContext reload
INFO: Reloading Context with name [/conf4u] has started
04/06/2012 00:27:15 org.Apache.catalina.loader.WebappClassLoader clearReferencesJdbc
SEVERE: The web application [/conf4u] registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
04/06/2012 00:27:15 org.Apache.catalina.core.StandardContext reload
INFO: Reloading Context with name [/conf4u] is completed
Méthode Dao:
public void removeUserFromConference(Conference conference, User user) {
ConferencesUsers conferenceUser = getConferenceUser(conference, user);
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
session.delete(conferenceUser);
session.getTransaction().commit();
}
La classe de modèle:
@Entity
@Table( name = "Conferences_Users" )
public class ConferencesUsers implements Serializable {
private static final long serialVersionUID = -3401337605668111437L;
private Conference conference;
private User user;
private int userRole;
private UserAttendanceStatus attendanceStatus;
private boolean notifiedByMail;
ConferencesUsers() {} //not public on purpose!
public ConferencesUsers(Conference conf, User user, int userRole) {
this.conference = conf;
this.user = user;
this.userRole = userRole;
this.attendanceStatus = null;
this.notifiedByMail = false;
}
public ConferencesUsers(Conference conf, User user, int userRole, UserAttendanceStatus attendanceStatus, boolean notifiedByMail) {
this.conference = conf;
this.user = user;
this.userRole = userRole;
this.attendanceStatus = attendanceStatus;
this.notifiedByMail = notifiedByMail;
}
@Id
@ManyToOne(cascade = CascadeType.ALL)
public Conference getConference() {
return conference;
}
public void setConference(Conference conference) {
this.conference = conference;
}
@Id
@ManyToOne(cascade = CascadeType.ALL)
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Enumerated(EnumType.STRING)
public int getUserRole() {
return userRole;
}
public void setUserRole(int userRole) {
this.userRole = userRole;
}
@Nullable
public boolean isNotifiedByMail() {
return notifiedByMail;
}
public void setNotifiedByMail(boolean notifiedByMail) {
this.notifiedByMail = notifiedByMail;
}
public UserAttendanceStatus getAttendanceStatus() {
return attendanceStatus;
}
public ConferencesUsers setAttendanceStatus(UserAttendanceStatus attendanceStatus) {
this.attendanceStatus = attendanceStatus;
return this;
}
}
Vous avez probablement déjà commencé une transaction et essayé d'en commencer une autre sans avoir validé ou annulé la précédente. L'idiome utilisé lors de l'utilisation de la démarcation programmatique de transaction est le suivant:
try {
sess.getTransaction().begin();
// do some work
sess.getTransaction().commit()
}
catch (RuntimeException e) {
sess.getTransaction().rollback();
throw e;
}
C'est une tâche lourde et sujette aux erreurs, et c'est l'une des raisons pour lesquelles utiliser des EJB ou Spring pour effectuer des transactions déclaratives est si utile.
Tout d’abord, vous devez injecter hibernateProperties, hibernate.current_session_context_class,
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.current_session_context_class">thread</prop>
</props>
</property>
ensuite, vous pouvez utiliser getCurrentSession () pour obtenir la CurrentSession.
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
long count = (Long) session
.createQuery("select count(*) from User u where u.name = :name")
.setString("name", name).uniqueResult();
session.getTransaction().commit();
J'ai le même problème avant. Première exécution:
session.beginTransaction();
session.save(something);
session.getTransaction().commit();
quand interroger quelque chose par:
session.beginTransaction();
session.query ...
la même exception est levée à la deuxième beginTranscation
. Je l'ai résolu en utilisant
session.getTransaction().begin();
au lieu de
session.beginTransaction();
à la fois dans la requête et enregistrer.
Qu'est-ce que vous avez fait ici:
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
essaie actuellement d’utiliser une session ouverte sans la fermer.
C'est ce qui m'est arrivé et j'ai rencontré le même problème. Ce que j'ai fait est:
Session session = HibernateUtil.getSessionFactory().openSession();
// Hibernate bla bla bla transaction or rollback
// then always close your session :
if (session.isOpen()) {
session.close();
}
et il n'y a pas eu d'erreur "Erreur de transaction imbriquée imbriquée dans Hibernate" qui a de nouveau été soulevée ...
Essayez enfin de fermer votre session Hibernate, comme ceci:
try {
session.getTransaction().begin();
// YOUR CODE
session.getTransaction().commit();
} catch (RuntimeException e) {
try{
session.getTransaction().rollback();
} catch(RuntimeException rbe) {
log.error("Couldn’t roll back transaction", rbe);
}
throw e;
} finally {
if (session != null && session.isOpen()) {
session.close();
}
}
Je résous ce problème en créant différentes sessions avec
Session session = factory.openSession();
session.beginTransaction();
//your code here
session.getTransaction().commit();
Je pourrais le résoudre avec le code suivant:
public class UserDaoImpl implements UserDao {
Session session = null;
public UserDaoImpl() {
this.session = HibernateUtil.getSessionFactory().openSession();
}
@Override
public List<TblUsuario> getAllUsers() {
List<TblUsuario> listUsuarios = null;
try {
org.hibernate.Transaction tx = this.session.getTransaction();
Query query = this.session.createQuery("....");
listUsuarios = query.list();
} catch (Exception e) {
e.printStackTrace();
}
return listUsuarios;
}
...
}
cette ligne "session.beginTransaction ();" empêchez plusieurs transactions, alors supprimez cette ligne et essayez car, dans la requête select, ce n'est pas nécessaire, mais le code ne fonctionne pas après la suppression de cette requête, puis ajoutez "session.rollback ();" à la fin de ce code.