Advertisement
lharpf

Reconnect JPA (Hibernate) EntityManager to JDBC connection

Jun 10th, 2014
630
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 3.12 KB | None | 0 0
  1. package com.foo.bar;
  2.  
  3. import org.hibernate.jpa.internal.EntityManagerFactoryAdapter;
  4.  
  5. import javax.annotation.Nonnull;
  6. import javax.persistence.EntityManager;
  7. import javax.persistence.EntityManagerFactory;
  8. import javax.persistence.Persistence;
  9. import java.sql.Connection;
  10. import java.util.HashMap;
  11. import java.util.Map;
  12.  
  13. /**
  14.  * <p>
  15.  *      Holds one {@link EntityManager} for every Thread to allow lazy-loading.
  16.  * </p>
  17.  * <p>
  18.  *      This is an implementation of the <em>persistence context per conversation</em> strategy. See
  19.  *      "Java Persistence with Hibernate, Second Edition" (ISBN 9781617290459), chapter 11 for details.
  20.  *
  21.  * </p>
  22.  * @see <a href="http://stackoverflow.com/questions/24060782/jpa-2-hibernate-persistence-context-per-conversation-closed-connection">JPA 2 (Hibernate) persistence context per conversation - closed connection</a>
  23.  * @see <a href="http://www.manning.com/bauer3/">Java Persistence with Hibernate, Second Edition</a>
  24.  */
  25. public class EntityManagerHolder {
  26.     private static final ThreadLocal<EntityManager> entityManager = new ThreadLocal<EntityManager>();
  27.     private static EntityManagerFactoryAdapter entityManagerFactoryAdapter;
  28.  
  29.     /**
  30.      * @return The {@link EntityManager} linked to this thread
  31.      */
  32.     public static EntityManager getEntityManager() {
  33.         return entityManager.get();
  34.     }
  35.  
  36.     /**
  37.      * If the invoking thread does not have an associated {@link EntityManager} yet,
  38.      * creates a new one and associates it with the thread. Otherwise, reconnects
  39.      * the existing EntityManager to a JDBC connection (if the connection has been closed).
  40.      *
  41.      * @param connection An active JDBC connection to use for the EntityManager
  42.      */
  43.     public static synchronized void initializeEntityManager(@Nonnull Connection connection) {
  44.         EntityManager currentEntityManager = entityManager.get();
  45.  
  46.         if (currentEntityManager == null || !currentEntityManager.isOpen()) {
  47.  
  48.             if (entityManagerFactoryAdapter == null) {
  49.                 // First invocation ever; create a factory to produce EntityManagers from a JDBC connection
  50.                 EntityManagerFactory entityManagerFactory =
  51.                         Persistence.createEntityManagerFactory("myPersistenceUnit");
  52.                 entityManagerFactoryAdapter = new EntityManagerFactoryAdapter(entityManagerFactory);
  53.             }
  54.  
  55.             // Start the conversation by creating the EntityManager for this thread
  56.             EntityManager newEntityManager = entityManagerFactoryAdapter.createEntityManager(connection);
  57.             entityManager.set(newEntityManager);
  58.         } else {
  59.             // Continuing conversation; ensure the connection of the EntityManager is alive
  60.             entityManagerFactoryAdapter.reconnect(currentEntityManager, connection);
  61.         }
  62.     }
  63.  
  64.     /**
  65.      * Conversation has been finished; close the EntityManager linked to this thread.
  66.      */
  67.     public static synchronized void closeEntityManager() {
  68.         if (entityManager.get() != null && entityManager.get().isOpen()) {
  69.             entityManager.get().close();
  70.         }
  71.     }
  72. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement