1

我让 Hibernate 使用单个 Tomcat 节点,但是当我尝试在集群中运行时,我收到此错误:

SEVERE: IOException while loading persisted sessions: java.io.InvalidObjectException: Could not find a SessionFactory [uuid=158c1e24-039b-4406-9a9b-cebb836100d1,name=null]
java.io.InvalidObjectException: Could not find a SessionFactory [uuid=158c1e24-039b-4406-9a9b-cebb836100d1,name=null]
at org.hibernate.internal.SessionFactoryImpl.locateSessionFactoryOnDeserialization(SessionFactoryImpl.java:1767)
at org.hibernate.internal.SessionFactoryImpl.readResolve(SessionFactoryImpl.java:1747)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at java.io.ObjectStreamClass.invokeReadResolve(ObjectStreamClass.java:1091)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1786)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1970)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1894)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1777)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1970)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1894)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1777)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1970)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1894)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1777)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1970)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1894)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1777)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
at org.apache.catalina.session.StandardSession.readObject(StandardSession.java:1485)
at org.apache.catalina.session.StandardSession.readObjectData(StandardSession.java:987)
at org.apache.catalina.session.StandardManager.doLoad(StandardManager.java:394)
at org.apache.catalina.session.StandardManager.load(StandardManager.java:321)
at org.apache.catalina.session.StandardManager.start(StandardManager.java:648)
at org.apache.catalina.core.ContainerBase.setManager(ContainerBase.java:446)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4630)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:799)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:779)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:601)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:943)
at org.mobicents.servlet.sip.startup.SipHostConfig.deployWAR(SipHostConfig.java:134)
at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:778)
at org.mobicents.servlet.sip.startup.SipHostConfig.deployWARs(SipHostConfig.java:205)
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:504)
at org.mobicents.servlet.sip.startup.SipHostConfig.deployApps(SipHostConfig.java:55)
at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1315)
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:324)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:142)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1061)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:840)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463)
at org.mobicents.servlet.sip.startup.SipStandardEngine.start(SipStandardEngine.java:98)
at org.apache.catalina.core.StandardService.start(StandardService.java:525)
at org.mobicents.servlet.sip.startup.SipStandardService.start(SipStandardService.java:290)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:754)
at org.apache.catalina.startup.Catalina.start(Catalina.java:595)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)

这是我的 HibernateUtil 类,称为 RecordingHibernateUtil:

public class RecordingHibernateUtil {

public static final String CONFIG_FILENAME = "hibernate-recording.cfg.xml";
public static final String RECORDING_DB_URL = "recording.db.url";
public static final String RECORDING_DB_DRIVER = "recording.db.driver";
public static final String RECORDING_DB_USERNAME = "recording.db.username";
public static final String RECORDING_DB_PASSWORD = "recording.db.password";

private static SessionFactory sessionFactory = null;

public static void buildSessionFactory() {
    if (sessionFactory != null) {
        //Already configured
        return;
    }
    Properties props;
    try {
        props = DBConfiguration.getInstance().getProperties();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
    Configuration config = new Configuration().configure(CONFIG_FILENAME);
    config.setProperty("hibernate.connection.url", 
            props.getProperty(RECORDING_DB_URL, 
                    props.getProperty(DBConfiguration.DB_URL)));
    config.setProperty("hibernate.connection.driver_class", 
            props.getProperty(RECORDING_DB_DRIVER, 
                    props.getProperty(DBConfiguration.DB_DRIVER)));
    config.setProperty("hibernate.connection.username", 
            props.getProperty(RECORDING_DB_USERNAME, 
                    props.getProperty(DBConfiguration.DB_USERNAME)));
    config.setProperty("hibernate.connection.password", 
            props.getProperty(RECORDING_DB_PASSWORD, 
                    props.getProperty(DBConfiguration.DB_PASSWORD)));
    try {
        sessionFactory = config.buildSessionFactory();
    } catch (Throwable ex) {
        // Make sure you log the exception, as it might be swallowed
        System.err.println("Initial SessionFactory creation failed." + ex);
        throw new ExceptionInInitializerError(ex);
    }
}

public static SessionFactory getSessionFactory() {
    return sessionFactory;
}

public static void shutdown() {
    // Close caches and connection pools
    getSessionFactory().close();
}
}

从互联网搜索来看,它听起来像是在尝试序列化 Hibernate SessionFactory,为了防止这种情况,建议使用 JNDI 查找来获取 SessionFactory。这个对吗?我不知道它为什么要序列化 ​​SessionFactory 。(现在我将 SessionFactory 存储在 HibernateUtil 类的静态变量中......我更愿意保持这种方式。)

真的有必要使用JNDI吗?我该怎么做呢?我需要一个适用于 Tomcat 和 JBoss(最好)的解决方案,或者分别适用于每个解决方案。

4

1 回答 1

2

问题是,在某些时候,您的 http-session 会保留对 SessionFactory 的引用,但它没有意义。SessionFactory 是从每个 Hibernate Session 中引用的,所以我猜你在你的 http-session 中引用了一个 Hibernate Session ......这很糟糕。

请记住:

  • http-session 是一个长期存在的对象(多个请求-响应循环)
  • hibernate session 是短时间的活动对象(即使可以做到:在多个请求期间尝试重用同一个 Hibernate Session 是相当复杂的)。

所以你必须在 Http Session 中找到对 Hibernate Session 的引用:使用你的调试器并探索你的 http-session 的内容

于 2013-09-12T20:25:34.617 回答