1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
/*
* Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021 IBM Corporation. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Guy Pelletier - initial API and implementation
package org.eclipse.persistence.jpa.config;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.EntityManagerFactory;
import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.exceptions.PersistenceUnitLoadingException;
import org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl;
import org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider;
import org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl;
import org.eclipse.persistence.internal.jpa.config.persistenceunit.MetadataSource;
import org.eclipse.persistence.internal.jpa.deployment.JPAInitializer;
import org.eclipse.persistence.internal.jpa.deployment.SEPersistenceUnitInfo;
import org.eclipse.persistence.jpa.PersistenceProvider;
// TODO: JPA RS
//import org.eclipse.persistence.jpa.rs.PersistenceContextFactory;
//import org.eclipse.persistence.jpa.rs.PersistenceContextFactoryProvider;
//import org.eclipse.persistence.jpa.rs.PersistenceFactoryBase;
import org.eclipse.persistence.sessions.factories.SessionManager;
/**
* JPA scripting API implementation.
*
* @author Guy Pelletier
* @since EclipseLink 2.5.1
*/
public class RuntimeFactory {
public EntityManagerFactory createEntityManagerFactory(PersistenceUnit pu) {
EntityManagerSetupImpl emSetupImpl = null;
boolean isNew = false;
// the name that uniquely defines persistence unit
String name = pu.getName();
pu.setProperty(PersistenceUnitProperties.METADATA_SOURCE, new MetadataSource(pu));
SEPersistenceUnitInfo puInfo = (SEPersistenceUnitInfo) pu.getPersistenceUnitInfo();
JPAInitializer initializer = new PersistenceProvider().getInitializer(name, null);
Map<String, Object> props = new HashMap<String, Object>();
String uniqueName = initializer.createUniquePersistenceUnitName(puInfo);
String sessionName = EntityManagerSetupImpl.getOrBuildSessionName(props, puInfo, uniqueName);
try {
synchronized (EntityManagerFactoryProvider.emSetupImpls) {
emSetupImpl = EntityManagerFactoryProvider.getEntityManagerSetupImpl(sessionName);
if (emSetupImpl != null) {
if (puInfo.getClassLoader() != emSetupImpl.getPersistenceUnitInfo().getClassLoader()) {
emSetupImpl.undeploy();
EntityManagerFactoryProvider.emSetupImpls.remove(sessionName);
SessionManager manager = SessionManager.getManager();
if (manager.getSessions().containsKey(sessionName)) {
manager.destroySession(sessionName);
}
manager.destroy();
emSetupImpl = null;
}
}
if (emSetupImpl == null) {
// there may be initial emSetupImpl cached in Initializer - remove it and use.
emSetupImpl = initializer.extractInitialEmSetupImpl(name);
if (emSetupImpl == null) {
// create and predeploy a new emSetupImpl
emSetupImpl = initializer.callPredeploy(puInfo, props, uniqueName, sessionName);
} else {
// change the name
emSetupImpl.changeSessionName(sessionName);
}
// emSetupImpl has been already predeployed, predeploy will just increment factoryCount.
emSetupImpl.predeploy(emSetupImpl.getPersistenceUnitInfo(), props);
EntityManagerFactoryProvider.addEntityManagerSetupImpl(sessionName, emSetupImpl);
isNew = true;
}
}
} catch (Exception e) {
throw PersistenceUnitLoadingException.exceptionSearchingForPersistenceResources(initializer.getInitializationClassLoader(), 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(), props);
}
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(pu);
}
}
EntityManagerFactoryImpl factory = null;
try {
factory = new EntityManagerFactoryImpl(emSetupImpl, props);
// This code has been added to allow validation to occur without
// actually calling createEntityManager
if (emSetupImpl.shouldGetSessionOnCreateFactory(props)) {
factory.getDatabaseSession();
}
} catch (RuntimeException ex) {
if (factory != null) {
factory.close();
} else {
emSetupImpl.undeploy();
}
throw ex;
}
return factory;
}
public static RuntimeFactory getInstance() {
return new RuntimeFactory();
}
}
|