private EntityManager getEM ( ) throws IllegalStateException { if ( ! open ) { throw new IllegalStateException ( "The JPA bridge has closed" ) ; } try { // Do we already have one on this thread? EntityManager em = perThreadEntityManager . get ( ) ; if ( em != null ) { return em ; } // Nope, so we need to check if there actually is a transaction final Transaction transaction = transactionManager . getTransaction ( ) ; if ( transaction == null ) { throw new TransactionRequiredException ( "Cannot create an EM since no transaction active" ) ; } em = entityManagerFactory . createEntityManager ( ) ; try { // Register a callback at the end of the transaction transaction . registerSynchronization ( new Synchronization ( ) { @ Override public void beforeCompletion ( ) { if ( ! open ) { throw new IllegalStateException ( "The Transaction Entity Manager was closed in the mean time" ) ; } } @ Override public void afterCompletion ( int arg0 ) { EntityManager em = perThreadEntityManager . get ( ) ; perThreadEntityManager . set ( null ) ; em . close ( ) ; } } ) ; } catch ( Exception e ) { em . close ( ) ; throw new IllegalStateException ( "Registering synchronization to close EM" , e ) ; } // Make it available for later calls on this thread perThreadEntityManager . set ( em ) ; // And make sure it joins the current transaction. em . joinTransaction ( ) ; return em ; } catch ( Exception e ) { throw new IllegalStateException ( "Error while retrieving entity manager" , e ) ; } }
The delegated methods call this method to get the delegate . This method verifies if we re still open if there already is an Entity Manager for this thread and otherwise creates it and enlists it for auto close at the current transaction .