/*
* JBoss, Home of Professional Open Source.
* Copyright 2011, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.as.jpa.config;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.EntityManagerFactory;
import org.jipijapa.plugin.spi.PersistenceUnitMetadata;
/**
* configuration properties that may appear in persistence.xml
*
* @author Scott Marlow
*/
public class Configuration {
/**
* name of the AS module that contains the persistence provider
*/
public static final String PROVIDER_MODULE = "jboss.as.jpa.providerModule";
/**
* Hibernate 4.3.x (default) persistence provider
*/
public static final String PROVIDER_MODULE_HIBERNATE4_3 = "org.hibernate";
/**
* Hibernate 4.1.x persistence provider, note that Hibernate 4.1.x is expected to be in the 4.1 slot
*/
public static final String PROVIDER_MODULE_HIBERNATE4_1 = "org.hibernate:4.1";
/**
* Hibernate OGM persistence provider
*/
public static final String PROVIDER_MODULE_HIBERNATE_OGM = "org.hibernate.ogm";
public static final String PROVIDER_MODULE_ECLIPSELINK = "org.eclipse.persistence";
public static final String PROVIDER_MODULE_TOPLINK = "oracle.toplink";
public static final String PROVIDER_MODULE_DATANUCLEUS = "org.datanucleus";
public static final String PROVIDER_MODULE_DATANUCLEUS_GAE = "org.datanucleus:appengine";
public static final String PROVIDER_MODULE_OPENJPA = "org.apache.openjpa";
/**
* default if no PROVIDER_MODULE is specified.
*/
public static final String PROVIDER_MODULE_DEFAULT = PROVIDER_MODULE_HIBERNATE4_3;
/**
* Hibernate 4.1.x persistence provider class
*/
public static final String PROVIDER_CLASS_HIBERNATE4_1 = "org.hibernate.ejb.HibernatePersistence";
/**
* Hibernate 4.3.x persistence provider class
*/
public static final String PROVIDER_CLASS_HIBERNATE = "org.hibernate.jpa.HibernatePersistenceProvider";
/**
* Hibernate OGM persistence provider class
*/
public static final String PROVIDER_CLASS_HIBERNATE_OGM = "org.hibernate.ogm.jpa.HibernateOgmPersistence";
/**
* TopLink provider class names
*/
public static final String PROVIDER_CLASS_TOPLINK_ESSENTIALS = "oracle.toplink.essentials.PersistenceProvider";
public static final String PROVIDER_CLASS_TOPLINK = "oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider";
/**
* EclipseLink provider class name
*/
public static final String PROVIDER_CLASS_ECLIPSELINK = "org.eclipse.persistence.jpa.PersistenceProvider";
/**
* DataNucleus provider
*/
public static final String PROVIDER_CLASS_DATANUCLEUS = "org.datanucleus.api.jpa.PersistenceProviderImpl";
/**
* DataNucleus provider GAE
*/
public static final String PROVIDER_CLASS_DATANUCLEUS_GAE = "org.datanucleus.store.appengine.jpa.DatastorePersistenceProvider";
public static final String PROVIDER_CLASS_OPENJPA = "org.apache.openjpa.persistence.PersistenceProviderImpl";
/**
* default provider class
*/
public static final String PROVIDER_CLASS_DEFAULT = PROVIDER_CLASS_HIBERNATE;
/**
* if the PROVIDER_MODULE is this value, it is expected that the application has its own provider
* in the deployment.
*/
public static final String PROVIDER_MODULE_APPLICATION_SUPPLIED = "application";
public static final String ADAPTER_MODULE_OPENJPA = "org.jboss.as.jpa.openjpa";
/**
* name of the AS module that contains the persistence provider adapter
*/
public static final String ADAPTER_MODULE = "jboss.as.jpa.adapterModule";
/**
* defaults to true, if changed to false (in the persistence.xml),
* the JPA container will not start the persistence unit service.
*/
public static final String JPA_CONTAINER_MANAGED = "jboss.as.jpa.managed";
public static final String JPA_DEFAULT_PERSISTENCE_UNIT = "wildfly.jpa.default-unit";
/**
* defaults to true, if false, persistence unit will not support javax.persistence.spi.ClassTransformer Interface
* which means no application class rewriting
*/
public static final String JPA_CONTAINER_CLASS_TRANSFORMER = "jboss.as.jpa.classtransformer";
private static final String HIBERNATE_USE_CLASS_ENHANCER = "hibernate.ejb.use_class_enhancer";
private static final String HIBERNATE_ENABLE_DIRTY_TRACKING = "hibernate.enhancer.enableDirtyTracking";
private static final String HIBERNATE_ENABLE_LAZY_INITIALIZATION = "hibernate.enhancer.enableLazyInitialization";
private static final String HIBERNATE_ENABLE_ASSOCIATION_MANAGEMENT = "hibernate.enhancer.enableAssociationManagement";
/**
* set to false to force a single phase persistence unit bootstrap to be used (default is true
* which uses two phases to start the persistence unit).
*/
public static final String JPA_ALLOW_TWO_PHASE_BOOTSTRAP = "wildfly.jpa.twophasebootstrap";
/**
* set to false to ignore default data source (defaults to true)
*/
private static final String JPA_ALLOW_DEFAULT_DATA_SOURCE_USE = "wildfly.jpa.allowdefaultdatasourceuse";
/**
* set to true to defer detaching entities until persistence context is closed (WFLY-3674)
*/
private static final String JPA_DEFER_DETACH = "jboss.as.jpa.deferdetach";
/**
* unique name for the persistence unit that is unique across all deployments (
* defaults to include the application name prepended to the persistence unit name)
*/
private static final String JPA_SCOPED_PERSISTENCE_UNIT_NAME = "jboss.as.jpa.scopedname";
/**
* name of the persistence provider adapter class
*/
public static final String ADAPTER_CLASS = "jboss.as.jpa.adapterClass";
public static final String ALLOWJOINEDUNSYNCPC = "wildfly.jpa.allowjoinedunsync";
public static final String SKIPMIXEDSYNCTYPECHECKING = "wildfly.jpa.skipmixedsynctypechecking";
/**
* name of the Hibernate Search module name configuration setting in persistence unit definition
*/
public static final String HIBERNATE_SEARCH_MODULE = "wildfly.jpa.hibernate.search.module";
/**
* name of the Hibernate Search module name
*/
public static final String PROVIDER_MODULE_HIBERNATE_SEARCH = "org.hibernate.search.orm:main";
private static final String EE_DEFAULT_DATASOURCE = "java:comp/DefaultDataSource";
// key = provider class name, value = module name
private static final Map<String, String> providerClassToModuleName = new HashMap<String, String>();
static {
// always choose the default hibernate version for the Hibernate provider class mapping
// if the user wants a different version. they can specify the provider module name
providerClassToModuleName.put(PROVIDER_CLASS_HIBERNATE, PROVIDER_MODULE_HIBERNATE4_3);
// WFLY-2136/HHH-8543 to make migration to Hibernate 4.3.x easier, we also map the (now)
// deprecated PROVIDER_CLASS_HIBERNATE4_1 to the org.hibernate:main module
// when PROVIDER_CLASS_HIBERNATE4_1 is no longer in a future Hibernate version (5.x?)
// we can map PROVIDER_CLASS_HIBERNATE4_1 to org.hibernate:4.3 at that time.
// persistence units can set "jboss.as.jpa.providerModule=org.hibernate:4.1" to use Hibernate 4.1.x/4.2.x
providerClassToModuleName.put(PROVIDER_CLASS_HIBERNATE4_1, PROVIDER_MODULE_HIBERNATE4_3);
providerClassToModuleName.put(PROVIDER_CLASS_HIBERNATE_OGM, PROVIDER_MODULE_HIBERNATE_OGM);
providerClassToModuleName.put(PROVIDER_CLASS_TOPLINK_ESSENTIALS, PROVIDER_MODULE_TOPLINK);
providerClassToModuleName.put(PROVIDER_CLASS_TOPLINK, PROVIDER_MODULE_TOPLINK);
providerClassToModuleName.put(PROVIDER_CLASS_ECLIPSELINK, PROVIDER_MODULE_ECLIPSELINK);
providerClassToModuleName.put(PROVIDER_CLASS_DATANUCLEUS, PROVIDER_MODULE_DATANUCLEUS);
providerClassToModuleName.put(PROVIDER_CLASS_DATANUCLEUS_GAE, PROVIDER_MODULE_DATANUCLEUS_GAE);
providerClassToModuleName.put(PROVIDER_CLASS_OPENJPA, PROVIDER_MODULE_OPENJPA);
}
/**
* Get the provider module name for the specified provider class.
*
* @param providerClassName the PU class name
* @return provider module name or null if not known
*/
public static String getProviderModuleNameFromProviderClassName(final String providerClassName) {
return providerClassToModuleName.get(providerClassName);
}
/**
* Determine if class file transformer is needed for the specified persistence unit
*
* if the persistence provider is Hibernate and use_class_enhancer is not true, don't need a class transformer.
* for other persistence providers, the transformer is assumed to be needed.
*
* @param pu the PU
* @return true if class file transformer support is needed for pu
*/
public static boolean needClassFileTransformer(PersistenceUnitMetadata pu) {
boolean result = true;
String provider = pu.getPersistenceProviderClassName();
if (pu.getProperties().containsKey(Configuration.JPA_CONTAINER_CLASS_TRANSFORMER)) {
result = Boolean.parseBoolean(pu.getProperties().getProperty(Configuration.JPA_CONTAINER_CLASS_TRANSFORMER));
}
else if (isHibernateProvider(provider)) {
result = (Boolean.TRUE.toString().equals(pu.getProperties().getProperty(HIBERNATE_USE_CLASS_ENHANCER))
|| Boolean.TRUE.toString().equals(pu.getProperties().getProperty(HIBERNATE_ENABLE_DIRTY_TRACKING))
|| Boolean.TRUE.toString().equals(pu.getProperties().getProperty(HIBERNATE_ENABLE_LAZY_INITIALIZATION))
|| Boolean.TRUE.toString().equals(pu.getProperties().getProperty(HIBERNATE_ENABLE_ASSOCIATION_MANAGEMENT)));
}
return result;
}
private static boolean isHibernateProvider(String provider) {
return provider == null ||
PROVIDER_CLASS_HIBERNATE.equals(provider) ||
PROVIDER_CLASS_HIBERNATE4_1.equals(provider);
}
// key = provider class name, value = adapter module name
private static final Map<String, String> providerClassToAdapterModuleName = new HashMap<String, String>();
static {
providerClassToAdapterModuleName.put(PROVIDER_CLASS_OPENJPA, ADAPTER_MODULE_OPENJPA);
}
public static String getProviderAdapterModuleNameFromProviderClassName(final String providerClassName) {
return providerClassToAdapterModuleName.get(providerClassName);
}
public static String getDefaultProviderModuleName() {
return PROVIDER_MODULE_DEFAULT;
}
/**
* Determine if two phase persistence unit start is allowed
*
* @param pu
* @return
*/
public static boolean allowTwoPhaseBootstrap(PersistenceUnitMetadata pu) {
boolean result = true;
if (EE_DEFAULT_DATASOURCE.equals(pu.getJtaDataSourceName())) {
result = false;
}
if (pu.getProperties().containsKey(Configuration.JPA_ALLOW_TWO_PHASE_BOOTSTRAP)) {
result = Boolean.parseBoolean(pu.getProperties().getProperty(Configuration.JPA_ALLOW_TWO_PHASE_BOOTSTRAP));
}
return result;
}
/**
* Determine if the default data-source should be used
*
* @param pu
* @return true if the default data-source should be used
*/
public static boolean allowDefaultDataSourceUse(PersistenceUnitMetadata pu) {
boolean result = true;
if (pu.getProperties().containsKey(Configuration.JPA_ALLOW_DEFAULT_DATA_SOURCE_USE)) {
result = Boolean.parseBoolean(pu.getProperties().getProperty(Configuration.JPA_ALLOW_DEFAULT_DATA_SOURCE_USE));
}
return result;
}
/**
* Return true if detaching of managed entities should be deferred until the entity manager is closed.
* Note: only applies to transaction scoped entity managers used without an active JTA transaction.
*
* @param properties
* @return
*/
public static boolean deferEntityDetachUntilClose(final Map<String, Object> properties) {
boolean result = false;
if ( properties.containsKey(JPA_DEFER_DETACH))
result = Boolean.parseBoolean((String)properties.get(JPA_DEFER_DETACH));
return result;
}
public static String getScopedPersistenceUnitName(PersistenceUnitMetadata pu) {
Object name = pu.getProperties().get(JPA_SCOPED_PERSISTENCE_UNIT_NAME);
if (name instanceof String) {
return (String)name;
}
return null;
}
/**
* Allow the mixed synchronization checking to be skipped for backward compatibility with WildFly 10.1.0
*
*
* @param emf
* @param targetEntityManagerProperties
* @return
*/
public static boolean skipMixedSynchronizationTypeCheck(EntityManagerFactory emf, Map targetEntityManagerProperties) {
boolean result = false;
// EntityManager properties will take priority over persistence.xml level (emf) properties
if(targetEntityManagerProperties != null && targetEntityManagerProperties.containsKey(SKIPMIXEDSYNCTYPECHECKING)) {
result = Boolean.parseBoolean((String) targetEntityManagerProperties.get(SKIPMIXEDSYNCTYPECHECKING));
}
else if(emf.getProperties() != null && emf.getProperties().containsKey(SKIPMIXEDSYNCTYPECHECKING)) {
result = Boolean.parseBoolean((String) emf.getProperties().get(SKIPMIXEDSYNCTYPECHECKING));
}
return result;
}
/**
* Allow an unsynchronized persistence context that is joined to the transaction, be treated the same as a synchronized
* persistence context, with respect to the checking for mixed unsync/sync types.
*
*
* @param emf
* @param targetEntityManagerProperties
* @return
*/
public static boolean allowJoinedUnsyncPersistenceContext(EntityManagerFactory emf, Map targetEntityManagerProperties) {
boolean result = false;
// EntityManager properties will take priority over persistence.xml (emf) properties
if(targetEntityManagerProperties != null && targetEntityManagerProperties.containsKey(ALLOWJOINEDUNSYNCPC)) {
result = Boolean.parseBoolean((String) targetEntityManagerProperties.get(ALLOWJOINEDUNSYNCPC));
}
else if(emf.getProperties() != null && emf.getProperties().containsKey(ALLOWJOINEDUNSYNCPC)) {
result = Boolean.parseBoolean((String) emf.getProperties().get(ALLOWJOINEDUNSYNCPC));
}
return result;
}
}