//As a result, it is only the outer map that needs to be thread safe.
//Throw the error on to the client
if(!!!isTransactionActive()) {
if(jtaIntegrationAvailable())
throw new TransactionRequiredException("No transaction currently active");
else {
throw new TransactionRequiredException("No JTA transaction services implementation is currently available. As a result the" +
" JPA container cannot integrate with JTA transactions.");
}
}
EntityManager toReturn = null;
//Get hold of the Map. If there is no Map already registered then add one.
//We don't need to worry about a race condition, as no other thread will
//share our transaction and be able to access our Map
Map<EntityManagerFactory, EntityManager> contextsForTransaction = (Map<EntityManagerFactory, EntityManager>) tranRegistry.getResource(EMF_MAP_KEY);
//If we have a map then find an EntityManager, else create a new Map add it to the registry, and register for cleanup
if(contextsForTransaction != null) {
toReturn = contextsForTransaction.get(persistenceUnit);
} else {
contextsForTransaction = new IdentityHashMap<EntityManagerFactory, EntityManager>();
try {
tranRegistry.putResource(EMF_MAP_KEY, contextsForTransaction);
} catch (IllegalStateException e) {
_logger.warn("Unable to create a persistence context for the transaction {} because the is not active", new Object[] {tranRegistry.getTransactionKey()});
throw new TransactionRequiredException("Unable to assiociate resources with transaction " + tranRegistry.getTransactionKey());
}
}
//If we have no previously created EntityManager
if(toReturn == null) {
toReturn = (properties == null) ? persistenceUnit.createEntityManager() : persistenceUnit.createEntityManager(properties);
if(_logger.isDebugEnabled())
_logger.debug("Created a new persistence context {} for transaction {}.", new Object[] {toReturn, tranRegistry.getTransactionKey()});
try {
tranRegistry.registerInterposedSynchronization(new EntityManagerClearUp(toReturn));
} catch (IllegalStateException e) {
_logger.warn("No persistence context could be created as the JPA container could not register a synchronization with the transaction {}.", new Object[] {tranRegistry.getTransactionKey()});
toReturn.close();
throw new TransactionRequiredException("Unable to synchronize with transaction " + tranRegistry.getTransactionKey());
}
contextsForTransaction.put(persistenceUnit, toReturn);
} else {
if(_logger.isDebugEnabled())
_logger.debug("Re-using a persistence context for transaction " + tranRegistry.getTransactionKey());