Я пытаюсь реализовать шаблон entitymanager для разговора на проприетарной веб-платформе с сохранением состояния с помощью JBoss 4.3.0 и Hibernate 4.3.5. Короче говоря, цель:Контекст сохранения JPA 2 (Hibernate) для разговора - закрытое соединение
- Первого HTTP запрос загружает объект А с отложенной загрузкой объектами из базы данных
- Во втором запросе, свойство отложенной загрузки сущностей А доступны без, например, создание нового EntityManager и вызов, например. entityManager.merge (entityA).
Entitymanager-per-conversation кажется идеальным выбором. Вот моя попытка:
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);
}
}
}
}
persistence.xml:
<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>
Когда новый запрос HTTP поступает через рамку, я называю EntityManagerHolder.createEntityManagerIfNeeded(). На втором запросе HTTP, соединение JDBC из EntityManager закрыло и попытка оживить его с помощью Session.reconnect() приводит к исключению:
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)
Я понимаю, что я, вероятно, делать вещи в очень назад путь, но было бы неплохо понять, как должен реализовываться интерфейс entitymanager для разговора. Я нашел на основе фильтра Hibernate-specific sample implementation этого шаблона, но до сих пор не смог его свернуть.