2012-06-03 15 views
8

Cuando se ejecuta el método removeUserFromConference conseguir esta excepción: MétodoPrimeros "org.hibernate.TransactionException: anidado transacciones no se admite" error al borrar

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 

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 clase del modelo:

@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; 
    } 
} 
+0

Actualice la base de datos de destino utilizada (sin necesidad de buscar en la publicación para encontrarla), p. etiquetas y posiblemente título. –

Respuesta

21

Probablemente haya comenzado una transacción y tratando de comenzar otra sin t haber cometido o revertido el anterior. La expresión cuando se utiliza la demarcación de transacción programática es la siguiente:

try { 
    sess.getTransaction().begin(); 

    // do some work 

    sess.getTransaction().commit() 
} 
catch (RuntimeException e) { 
    sess.getTransaction().rollback(); 
    throw e; 
} 

Esto es engorroso y propenso a errores, y esto es una de las razones por las que usar EJBs o resorte tener transacciones declarativa es tan útil.

+0

Encontré que el problema allí era comenzar -> comenzar ... TNX – alonp

+0

@JB Nizet Enfrentando problemas de pareja como Transacción anidada no es compatible, aunque he cambiado a sus sugerencias pero no funcionó para mí. ¿Puedes ayudarme por favor en esto? – gks

+0

@Stranger: ¿Por qué no haces una pregunta en lugar de publicar un comentario? –

4

Tengo el mismo problema antes. Primera carrera:

session.beginTransaction(); 
session.save(something); 
session.getTransaction().commit(); 

cuando la consulta algo por:

session.beginTransaction(); 
session.query ... 

la misma excepción se lanza en segunda beginTranscation. Lo resuelto mediante el uso de

session.getTransaction().begin(); 

en lugar de

session.beginTransaction(); 

tanto en consulta y guardar.

7

En primer lugar, debe inyectarse la 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> 

continuación, puede utilizar getCurrentSession() para obtener el 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(); 
+0

o: sesión = sessionFactory.openSession(); session.beginTransaction(); ... hacer algo ... session.getTransaction(). commit(); session.close(); – user2204125

0

Lo que has hecho aquí:

Session session = HibernateUtil.getSessionFactory().getCurrentSession(); 

que realmente está tratando de usar una sesión abierta sin cerrarla.

A mí me pasó y yo estaba enfrentando el mismo problema, y ​​lo que hice es:

Session session = HibernateUtil.getSessionFactory().openSession(); 

// Hibernate bla bla bla transaction or rollback 
// then always close your session : 

if (session.isOpen()) { 
      session.close(); 
     } 

y no había "Hibernate anidados transacción de error no compatible" levantado de nuevo ...

0

pude resolverlo con el siguiente código:

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

... 

} 
0

pruebe a utilizar finalmente para cerrar la sesión de Hibernate, como esto:

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(); 
    } 
} 
0

puedo solucionar este problema al crear diferentes sesiones con

Session session = factory.openSession(); 
session.beginTransaction(); 

//your code here 

session.getTransaction().commit(); 
0

esta línea "session.beginTransaction();" previene las transacciones múltiples, por lo tanto, elimine esta línea e intente, porque en la consulta de selección no es necesario, pero el código no funciona después de eliminarlo; al final de este código, agregue "session.rollback();".

Cuestiones relacionadas