簡體   English   中英

休眠非法狀態異常

[英]Hibernate Illegal State Exception

我是Hibernate的新手,在使用Hibernate時 ,遇到了幾次IllegaStateException ,該異常不一致,因為我不知道它在什么特定條件下發生,有時不會發生,但是有時會發生,我無法弄清楚如何解決,請對此有所說明。

May 14, 2013 5:32:40 PM org.apache.catalina.loader.WebappClassLoader loadClass
INFO: Illegal access: this web application instance has been stopped already.  Could not load com.mysql.jdbc.ProfilerEventHandlerFactory.  The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact.

java.lang.IllegalStateException
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1600)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559)
    at com.mysql.jdbc.ConnectionImpl.realClose(ConnectionImpl.java:4412)
    at com.mysql.jdbc.ConnectionImpl.close(ConnectionImpl.java:1564)
    at org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl.stop(DriverManagerConnectionProviderImpl.java:160)
    at org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl.finalize(DriverManagerConnectionProviderImpl.java:229)
    at java.lang.ref.Finalizer.invokeFinalizeMethod(Native Method)
    at java.lang.ref.Finalizer.runFinalizer(Finalizer.java:101)
    at java.lang.ref.Finalizer.access$100(Finalizer.java:32)
    at java.lang.ref.Finalizer$FinalizerThread.run

(Finalizer.java:178)

這非常令人沮喪。 另外,我正在使用我創建的包裝之一來與Sessions和SessionFactory一起使用。 另外,我每次在內部使用Hibernate api的dao中使用代碼時,都會檢查使用closeSession()的代碼。

這是我的ManagerSessionFactory (包裝器)

public class ManagerSessionFactory {

private static SessionFactory sessionFactory;
private static Configuration configuration;
protected static ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();

static void initializeSessionFactory(String configFilePath) {
    try {
        // Create the SessionFactory from standard (hibernate.cfg.xml) 
        // config file.
        configuration = new Configuration();
        sessionFactory = configuration.configure(configFilePath).buildSessionFactory();
    } catch (Throwable ex) {
        // Log the exception. 
        System.err.println("Initial SessionFactory creation failed." + ex.getMessage());
        throw new ExceptionInInitializerError(ex);
    }
}

private static SessionFactory getSessionFactory() {
    return sessionFactory;
}

public static Session createSession() {
    return createSession(null);
}

public static Session createSession(String configFilePath) {

    if (configFilePath == null || configFilePath.trim().equals("")) {
        configFilePath = "/hibernate.cfg.xml";
    }
    SessionFactory localSessionFactory = ManagerSessionFactory.getSessionFactory();
    Session session = ManagerSessionFactory.threadLocal.get();

    if (session == null || !session.isOpen()) {

        if (localSessionFactory == null) {
            try {
                ManagerSessionFactory.initializeSessionFactory(configFilePath);
                localSessionFactory = ManagerSessionFactory.getSessionFactory();
            } catch (Exception e) {
                System.err.println("%%%% Error Creating SessionFactory %%%% " + e.getMessage());
            }
        }
        session = localSessionFactory.getCurrentSession();
        System.out.println("Session Opened......");
        ManagerSessionFactory.threadLocal.set(session);
    }



    return session;
}

public static void closeSession(){
    closeSession((Session)ManagerSessionFactory.threadLocal.get());
    return;
}

public static void closeSession(Session session){

    if (session != null && session.isOpen()) {
        session.close();
        //ManagerSessionFactory.threadLocal.
    }
    session = null;

    return;
}
}

這是ManageTransaction ,它擴展了上一類的功能:

public class ManageTransaction extends ManagerSessionFactory {

private Session session;
private Transaction transaction;
private String configFilePath;
private boolean toStartTransaction;

public ManageTransaction() {

    this.session = ManagerSessionFactory.createSession();
    initManagerTransaction("", false, session);
}

public ManageTransaction(boolean toStartTransaction) {
    this.session = ManagerSessionFactory.createSession();
    if (toStartTransaction) {
        this.transaction = this.session.getTransaction();
        this.transaction = this.transaction.isActive() ? this.transaction : this.session.beginTransaction();
    }
    initManagerTransaction("", toStartTransaction, session);
}

public ManageTransaction(boolean toStartTransaction, String configFilePath) {

    if (toStartTransaction) {
        this.session = ManagerSessionFactory.createSession();
        this.transaction = this.transaction.isActive() ? this.transaction : this.session.beginTransaction();
    }
    initManagerTransaction(configFilePath, toStartTransaction, this.session);

}

public ManageTransaction(String configFilePath, boolean toStartTransaction) {

    ManagerSessionFactory.initializeSessionFactory(configFilePath);
    if (toStartTransaction) {
        this.session = ManagerSessionFactory.createSession();
        this.transaction = this.transaction.isActive() ? this.transaction : this.session.beginTransaction();
    }
    initManagerTransaction(configFilePath, toStartTransaction, this.session);
}

public ThreadLocal<Session> getThreadLocal() {
    return threadLocal;
}

private void initManagerTransaction(String configFilePath, boolean toStartTransaction, Session session) {
    this.configFilePath = configFilePath == null ? "" : configFilePath;
    this.toStartTransaction = toStartTransaction;
    ManageTransaction.threadLocal.set(session);
}
public void closeManageTransaction() {
        afterEveryOperation(true);
        ManagerSessionFactory.closeSession(this.getSession());
    }

}

這是我的hibernate.cfg.xml

<hibernate-configuration>
<session-factory>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/befundo?zeroDateTimeBehavior=convertToNull</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">root</property>
    <property name="hibernate.show_sql">false</property>
    <property name="hibernate.hbm2ddl.auto">update</property>
    <property name="hibernate.current_session_context_class">thread</property>
    <!--mapping classes -->
</session-factory>
</hibernate-configuration>

提前致謝。

我認為問題在於您沒有關閉SessonFactory。 會話工廠正在創建連接池。 sessionFactory關閉時,它將關閉(釋放連接)。 由於沒有顯式關閉它,因此在對象被垃圾回收時(finalize方法)將調用close。 這是在取消部署webapp之后。

一個快速的解決方法是添加一個ServletContextListener並在destroy方法中關閉會話工廠。

您的代碼看起來也非常復雜,您將遇到很多問題。 最好使用spring或EJB會話Bean之類的東西來處理此問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM