Advertisement
lharpf

Reconnect JPA (Hibernate) EntityManager to JDBC connection

Jun 10th, 2014
781
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 3.07 KB | None | 0 0
  1. package org.hibernate.jpa.internal;
  2.  
  3. import org.hibernate.Session;
  4. import org.hibernate.SessionFactory;
  5. import org.hibernate.internal.SessionImpl;
  6.  
  7. import javax.annotation.Nonnull;
  8. import javax.persistence.EntityManager;
  9. import javax.persistence.EntityManagerFactory;
  10. import java.sql.Connection;
  11. import java.sql.SQLException;
  12.  
  13. /**
  14.  * Manipulates Hibernate internals to allow connecting an {@link EntityManager}
  15.  * to a new JDBC connection when the old connection of the EntityManager has died.
  16.  *
  17.  * @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>
  18.  *
  19.  */
  20. public class EntityManagerFactoryAdapter {
  21.  
  22.     private final EntityManagerFactoryImpl entityManagerFactory;
  23.  
  24.     public EntityManagerFactoryAdapter(EntityManagerFactory entityManagerFactory) {
  25.         this.entityManagerFactory = (EntityManagerFactoryImpl)entityManagerFactory;
  26.     }
  27.  
  28.     /**
  29.      * Reconnects given {@code entityManager} to the given {@code connection}
  30.      * if the database connection of the EntityManager has been closed.
  31.      * Does nothing if the EntityManager already has an open connection.
  32.      *
  33.      * @param entityManager The EntityManager to reconnect
  34.      * @param connection The connection to connect the EntityManager to
  35.      */
  36.     public void reconnect(@Nonnull EntityManager entityManager, @Nonnull Connection connection) {
  37.         SessionImpl existingSession = entityManager.unwrap(SessionImpl.class);
  38.  
  39.         try {
  40.             if (existingSession.connection().isClosed()) {
  41.                 existingSession.disconnect();
  42.                 existingSession.reconnect(connection);
  43.             }
  44.         } catch (SQLException e) {
  45.             throw new RuntimeException("Failed reconnecting EntityManager to given JDBC connection.", e);
  46.         }
  47.     }
  48.  
  49.     /**
  50.      * Creates a new EntityManager that uses the given JDBC connection
  51.      * for database access.
  52.      *
  53.      * @param connection The JDBC connection to use in the EntityManager
  54.      * @return The created EntityManager
  55.      */
  56.     @Nonnull
  57.     public EntityManager createEntityManager(@Nonnull Connection connection) {
  58.         // Create new EntityManager & close the session attached to it.
  59.         // Otherwise the original session is left open.
  60.         EntityManagerImpl entityManager = (EntityManagerImpl)entityManagerFactory.createEntityManager();
  61.         entityManager.unwrap(Session.class).close();
  62.  
  63.         // Replace EntityManager session with session created with
  64.         // specified JDBC connection. Necessary to be able to
  65.         // later call .reconnect(connection) on the session.
  66.         SessionFactory sessionFactory = entityManagerFactory.getSessionFactory();
  67.         entityManager.session = sessionFactory.withOptions()
  68.                                               .connection(connection)
  69.                                               .openSession();
  70.  
  71.         entityManager.getTransaction().begin();
  72.  
  73.         return entityManager;
  74.     }
  75. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement