if (name == null){
name = "";
}
JPAInitializer initializer = initializationHelper.getInitializer(classLoader, nonNullProperties);
EntityManagerSetupImpl emSetupImpl = null;
boolean isNew = false;
// the name that uniquely defines persistence unit
String uniqueName;
String sessionName;
try {
SEPersistenceUnitInfo puInfo;
puInfo = initializer.findPersistenceUnitInfo(name, nonNullProperties, initializationHelper);
// either persistence unit not found or provider not supported
if(puInfo == null) {
return null;
}
if(initializer.isPersistenceUnitUniquelyDefinedByName()) {
uniqueName = name;
} else {
uniqueName = initializer.createUniquePersistenceUnitName(puInfo);
}
sessionName = EntityManagerSetupImpl.getOrBuildSessionName(nonNullProperties, puInfo, uniqueName);
synchronized (EntityManagerFactoryProvider.emSetupImpls) {
emSetupImpl = EntityManagerFactoryProvider.getEntityManagerSetupImpl(sessionName);
if(emSetupImpl == null) {
if(EntityManagerFactoryProvider.initialEmSetupImpls != null) {
// there may be initial emSetupImpl (possible only in SE that uses agent) remove it and use.
emSetupImpl = EntityManagerFactoryProvider.initialEmSetupImpls.remove(uniqueName);
if(emSetupImpl != null) {
// change the name
emSetupImpl.changeSessionName(sessionName);
}
}
if(emSetupImpl == null) {
// create and predeploy a new emSetupImpl
emSetupImpl = initializer.callPredeploy(puInfo, nonNullProperties, initializationHelper, uniqueName, sessionName);
}
// emSetupImpl has been already predeployed, predeploy will just increment factoryCount.
emSetupImpl.predeploy(emSetupImpl.getPersistenceUnitInfo(), nonNullProperties);
EntityManagerFactoryProvider.addEntityManagerSetupImpl(sessionName, emSetupImpl);
isNew = true;
}
}
} catch (Exception e) {
throw PersistenceUnitLoadingException.exceptionSearchingForPersistenceResources(classLoader, e);
}
if(!isNew) {
if(!uniqueName.equals(emSetupImpl.getPersistenceUnitUniqueName())) {
throw PersistenceUnitLoadingException.sessionNameAlreadyInUse(sessionName, uniqueName, emSetupImpl.getPersistenceUnitUniqueName());
}
// synchronized to prevent undeploying by other threads.
boolean undeployed = false;
synchronized(emSetupImpl) {
if(emSetupImpl.isUndeployed()) {
undeployed = true;
}
// emSetupImpl has been already predeployed, predeploy will just increment factoryCount.
emSetupImpl.predeploy(emSetupImpl.getPersistenceUnitInfo(), nonNullProperties);
}
if(undeployed) {
// after the emSetupImpl has been obtained from emSetupImpls
// it has been undeployed by factory.close() in another thread - start all over again.
return createEntityManagerFactory(emName, properties, classLoader);
}
}
EntityManagerFactoryImpl factory = null;
try {
factory = new EntityManagerFactoryImpl(emSetupImpl, nonNullProperties);
// This code has been added to allow validation to occur without actually calling createEntityManager
if (emSetupImpl.shouldGetSessionOnCreateFactory(nonNullProperties)) {
factory.getServerSession();
}
return factory;
} catch (RuntimeException ex) {
if(factory != null) {
factory.close();
} else {
emSetupImpl.undeploy();
}
throw ex;
}
}