0

私は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)

これは非常に腹立たしいです。また、作成したラッパーの 1 つを使用して、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>

前もって感謝します。

4

1 に答える 1

1

問題は、SessonFactory を閉じていないことだと思います。セッション ファクトリが接続プールを作成しています。sessionFactory が閉じられると、これは閉じられます (接続が解放されます)。オブジェクトを明示的に閉じていないため、オブジェクトがガベージ コレクション (finalize メソッド) されるときに close が呼び出されます。これは、webapp がアンデプロイされた後です。

簡単な修正は、ServletContextListener を追加し、destroy メソッドでセッション ファクトリを閉じることです。

コードも非常に複雑に見え、多くの問題が発生します。これを処理するには、Spring または EJB セッション Bean のようなものを使用することをお勧めします。

于 2013-05-14T12:56:07.297 に答える