Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA 2(Hibernate)每个会话的持久性上下文-关闭连接_Java_Hibernate_Jpa_Jdbc_Jboss - Fatal编程技术网

Java JPA 2(Hibernate)每个会话的持久性上下文-关闭连接

Java JPA 2(Hibernate)每个会话的持久性上下文-关闭连接,java,hibernate,jpa,jdbc,jboss,Java,Hibernate,Jpa,Jdbc,Jboss,我试图在JBoss4.3.0和Hibernate4.3.5的有状态专有web框架上实现entitymanager-per-conversation模式。简言之,目标是: 第一个HTTP请求从数据库加载具有延迟加载属性的实体A 在第二个请求中,可以访问实体A的延迟加载属性,而无需创建新的EntityManager并调用EntityManager.merge(entityA) 每次对话的Entitymanager似乎是完美的选择。以下是我的尝试: public class EntityManag

我试图在JBoss4.3.0和Hibernate4.3.5的有状态专有web框架上实现entitymanager-per-conversation模式。简言之,目标是:

  • 第一个HTTP请求从数据库加载具有延迟加载属性的实体A
  • 在第二个请求中,可以访问实体A的延迟加载属性,而无需创建新的EntityManager并调用EntityManager.merge(entityA)
每次对话的Entitymanager似乎是完美的选择。以下是我的尝试:

public class EntityManagerHolder {
    private static ThreadLocal<EntityManager> entityManager = new ThreadLocal<EntityManager>();        
    private static EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myPersistence");
    private static ConnectionProvider connectionProvider = new MyConnectionProvider();

    public static synchronized EntityManager getEntityManager() {
        createEntityManagerIfNeeded();
        return entityManager.get();
    }

    public static synchronized void createEntityManagerIfNeeded() {
        if (entityManager.get() == null) {
            // Start the conversation
            EntityManager newEntityManager = entityManagerFactory.createEntityManager();
            entityManager.set(newEntityManager);
            newEntityManager.getTransaction().begin();
        } else {
            // Entitymanager is alive but may have lost its connection
            EntityManager existingEntityManager = entityManager.get();
            SessionImpl session = existingEntityManager.unwrap(SessionImpl.class);

            try {
                if (session.connection() == null || session.connection().isClosed()) {
                    session.reconnect(connectionProvider.getConnection());
                }
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
我意识到我可能在以一种非常落后的方式做事情,但了解每个对话的entitymanager应该如何实现会很好。我已经找到了基于这种模式的过滤器,但还没有根据我的需要调整它。

结果是。如果禁用JBoss以关闭JDBC连接,则可以解决此问题。但是,我们希望避免长时间保持大量JDBC连接打开

迄今为止找到的最佳解决方案是恢复EntityManager的JDBC连接,前提是旧连接已关闭。我写了一个粗略的实现:

-用于将EntityManager重新连接到新的JDBC连接

-每个线程保留一个EntityManager

在每个HTTP请求的开始,我们调用EntityManagerHolder.initializeEntityManager(freshJDBCConnectionFromFramework)。当该状态从服务器中删除时,我们调用EntityManagerHolder.closeEntityManager()。Persistence.xml不再具有hibernate.connection.provider_类-我们正在手动传递连接

我发布这篇文章只是为了防止有人遇到类似的问题。这个解决方案是非常非正统的,我希望以后用一个更好的方案来代替它

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
             version="2.0">
  <persistence-unit name="myEntityManagerFactory">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <properties>
      <!-- Scan for annotated classes and Hibernate mapping XML files from this JAR -->
      <property name="hibernate.archive.autodetection" value="class, hbm" />
      <!-- Database connection settings: Use framework connections for database connectivity -->
      <property name="hibernate.connection.provider_class" value="foo.bar.MyConnectionProvider"/>
    </properties>
  </persistence-unit>
</persistence>
java.lang.IllegalStateException: cannot manually reconnect unless Connection was originally supplied

org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.manualReconnect(LogicalConnectionImpl.java:296)
org.hibernate.internal.SessionImpl.reconnect(SessionImpl.java:478)