8

removeUserFromConferenceメソッドを実行すると、次の例外が発生します。

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

モデルクラス:

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

8 に答える 8

22

おそらくトランザクションを開始し、前のトランザクションをコミットまたはロールバックせずに別のトランザクションを開始しようとしています。プログラムによるトランザクション境界を使用する場合のイディオムは次のとおりです。

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

    // do some work

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

これは面倒でエラーが発生しやすく、EJBまたはSpringを使用して宣言型トランザクションを実行することが非常に役立つ理由の1つです。

于 2012-06-03T21:46:13.093 に答える
7

まず、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>

次に、getCurrentSession()を使用して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();
于 2013-03-25T11:42:42.480 に答える
4

以前も同じ問題がありました。ファーストラン:

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

次の方法でクエリを実行する場合:

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

同じ例外が2番目に発生しbeginTranscationます。使って解決しました

session.getTransaction().begin();

それ以外の

session.beginTransaction();

クエリと保存の両方で。

于 2012-07-06T04:04:15.887 に答える
0

ここで何をしましたか:

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

実際には、開いているセッションを閉じずに使用しようとしています。

それは私に起こりました、そして私は同じ問題に直面していました、そして私がしたことは:

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

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

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

また、「Hibernate Nested TransactionNotSupportedError」が再度発生することはありませんでした...

于 2014-07-02T07:58:26.370 に答える
0

次のように、finallyを使用してHibernateセッションを閉じてみてください。

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();
    }
}
于 2016-07-22T12:32:17.820 に答える
0

私はこの問題を解決し、さまざまなセッションを作成します

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

//your code here

session.getTransaction().commit();
于 2017-02-01T19:21:54.823 に答える
0

この行「session.beginTransaction();」複数のトランザクションを防ぐため、この行を削除して試してください。selectクエリでは必要ありませんが、これを削除するとコードが機能しなくなり、このコードの最後に「session.rollback();」を追加します。

于 2017-11-22T09:07:08.793 に答える
-1

私は次のコードでそれを解決することができます:

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

...

}
于 2015-02-01T15:01:02.137 に答える