Hibernate非法状态异常

时间:2013-05-14 12:14:56

标签: java hibernate servlets

我是 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。 另外,我每次在 dao's 中使用 closeSession()时都会检查我的代码,这些代码在内部使用 Hibernate api。

这是我的 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>

提前致谢。

1 个答案:

答案 0 :(得分:1)

我认为问题在于你没有关闭SessonFactory。会话工厂正在创建连接池。当sessionFactory关闭时,这将被关闭(连接已释放)。由于您没有明确地关闭它,因此在对象被垃圾回收时调用close(finalize方法)。这是在取消部署webapp之后。

快速解决方法是添加ServletContextListener并在destroy方法中关闭会话工厂。

您的代码看起来也非常复杂,您将遇到很多问题。最好使用spring或EJB会话bean之类的东西来处理这个问题。