HHH-12858 + HHH-13432 Persistence.createEntityManagerFactory(Map) should allow overwriting jta-data-source of persistence.xml
HHH-12858 - integration overrides during JPA bootstrap ought to override all logically related settings - e.g. a datasource passed in the integration overrides map ought to effectively override JDBC-connection settings in `persistence.xml` (and vice-versa) HHH-13432 - Have EntityManagerFactory expose persistence.xml `jta-data-source` element as a `javax.persistence.nonJtaDataSource` property
This commit is contained in:
parent
3e1663a66e
commit
7eb0911fd6
|
@ -1,5 +1,3 @@
|
||||||
import org.apache.tools.ant.filters.ReplaceTokens
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
*
|
*
|
||||||
|
|
|
@ -47,7 +47,7 @@ public class LoadedConfig {
|
||||||
private List<MappingReference> mappingReferences;
|
private List<MappingReference> mappingReferences;
|
||||||
private Map<EventType,Set<String>> eventListenerMap;
|
private Map<EventType,Set<String>> eventListenerMap;
|
||||||
|
|
||||||
private LoadedConfig(String sessionFactoryName) {
|
public LoadedConfig(String sessionFactoryName) {
|
||||||
this.sessionFactoryName = sessionFactoryName;
|
this.sessionFactoryName = sessionFactoryName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +259,7 @@ public class LoadedConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void addConfigurationValues(Map configurationValues) {
|
protected void addConfigurationValues(Map configurationValues) {
|
||||||
if ( configurationValues == null ) {
|
if ( configurationValues == null ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.hibernate.boot.MappingException;
|
||||||
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmFilterAliasMappingType;
|
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmFilterAliasMappingType;
|
||||||
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmFilterType;
|
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmFilterType;
|
||||||
import org.hibernate.boot.model.source.spi.FilterSource;
|
import org.hibernate.boot.model.source.spi.FilterSource;
|
||||||
|
import org.hibernate.internal.util.NullnessHelper;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,7 +64,7 @@ public class FilterSourceImpl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.condition = Helper.coalesce( conditionContent, conditionAttribute );
|
this.condition = NullnessHelper.coalesce( conditionContent, conditionAttribute );
|
||||||
this.autoAliasInjection = StringHelper.isNotEmpty( explicitAutoAliasInjectionSetting )
|
this.autoAliasInjection = StringHelper.isNotEmpty( explicitAutoAliasInjectionSetting )
|
||||||
? Boolean.valueOf( explicitAutoAliasInjectionSetting )
|
? Boolean.valueOf( explicitAutoAliasInjectionSetting )
|
||||||
: true;
|
: true;
|
||||||
|
|
|
@ -123,33 +123,6 @@ public class Helper {
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Operates like SQL coalesce expression, except empty strings are treated as null. Return the first non-empty value
|
|
||||||
*
|
|
||||||
* @param values The list of values.
|
|
||||||
* @param <T> Generic type of values to coalesce
|
|
||||||
*
|
|
||||||
* @return The first non-empty value, or null if all values were empty
|
|
||||||
*/
|
|
||||||
public static <T> T coalesce(T... values) {
|
|
||||||
if ( values == null ) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
for ( T value : values ) {
|
|
||||||
if ( value != null ) {
|
|
||||||
if ( String.class.isInstance( value ) ) {
|
|
||||||
if ( StringHelper.isNotEmpty( (String) value ) ) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ToolingHintContext collectToolingHints(
|
static ToolingHintContext collectToolingHints(
|
||||||
ToolingHintContext baseline,
|
ToolingHintContext baseline,
|
||||||
ToolingHintContainer toolingHintContainer) {
|
ToolingHintContainer toolingHintContainer) {
|
||||||
|
|
|
@ -36,6 +36,35 @@ import org.hibernate.service.spi.ServiceContributor;
|
||||||
* @see org.hibernate.boot.registry.BootstrapServiceRegistryBuilder
|
* @see org.hibernate.boot.registry.BootstrapServiceRegistryBuilder
|
||||||
*/
|
*/
|
||||||
public class StandardServiceRegistryBuilder {
|
public class StandardServiceRegistryBuilder {
|
||||||
|
/**
|
||||||
|
* Intended only for use from {@link org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl}.
|
||||||
|
*
|
||||||
|
* Creates a StandardServiceRegistryBuilder specific to the needs of JPA bootstrapping.
|
||||||
|
* Specifically we ignore properties found in `cfg.xml` files in terms of adding them to
|
||||||
|
* the builder immediately. EntityManagerFactoryBuilderImpl handles collecting these
|
||||||
|
* properties itself.
|
||||||
|
*/
|
||||||
|
public static StandardServiceRegistryBuilder forJpa(BootstrapServiceRegistry bootstrapServiceRegistry) {
|
||||||
|
final LoadedConfig loadedConfig = new LoadedConfig( null ) {
|
||||||
|
@Override
|
||||||
|
protected void addConfigurationValues(Map configurationValues) {
|
||||||
|
// here, do nothing
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return new StandardServiceRegistryBuilder(
|
||||||
|
bootstrapServiceRegistry,
|
||||||
|
new HashMap(),
|
||||||
|
loadedConfig
|
||||||
|
) {
|
||||||
|
@Override
|
||||||
|
public StandardServiceRegistryBuilder configure(LoadedConfig loadedConfig) {
|
||||||
|
getAggregatedCfgXml().merge( loadedConfig );
|
||||||
|
// super also collects the properties - here we skip that part
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default resource name for a hibernate configuration xml file.
|
* The default resource name for a hibernate configuration xml file.
|
||||||
*/
|
*/
|
||||||
|
@ -43,7 +72,7 @@ public class StandardServiceRegistryBuilder {
|
||||||
|
|
||||||
private final Map settings;
|
private final Map settings;
|
||||||
private final List<StandardServiceInitiator> initiators = standardInitiatorList();
|
private final List<StandardServiceInitiator> initiators = standardInitiatorList();
|
||||||
private final List<ProvidedService> providedServices = new ArrayList<ProvidedService>();
|
private final List<ProvidedService> providedServices = new ArrayList<>();
|
||||||
|
|
||||||
private boolean autoCloseRegistry = true;
|
private boolean autoCloseRegistry = true;
|
||||||
|
|
||||||
|
@ -67,6 +96,21 @@ public class StandardServiceRegistryBuilder {
|
||||||
this( bootstrapServiceRegistry, LoadedConfig.baseline() );
|
this( bootstrapServiceRegistry, LoadedConfig.baseline() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Intended for use exclusively from JPA boot-strapping.
|
||||||
|
*
|
||||||
|
* @see #forJpa
|
||||||
|
*/
|
||||||
|
private StandardServiceRegistryBuilder(
|
||||||
|
BootstrapServiceRegistry bootstrapServiceRegistry,
|
||||||
|
Map settings,
|
||||||
|
LoadedConfig loadedConfig) {
|
||||||
|
this.bootstrapServiceRegistry = bootstrapServiceRegistry;
|
||||||
|
this.configLoader = new ConfigLoader( bootstrapServiceRegistry );
|
||||||
|
this.settings = settings;
|
||||||
|
this.aggregatedCfgXml = loadedConfig;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a builder with the specified bootstrap services.
|
* Create a builder with the specified bootstrap services.
|
||||||
*
|
*
|
||||||
|
@ -81,6 +125,10 @@ public class StandardServiceRegistryBuilder {
|
||||||
this.aggregatedCfgXml = loadedConfigBaseline;
|
this.aggregatedCfgXml = loadedConfigBaseline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ConfigLoader getConfigLoader() {
|
||||||
|
return configLoader;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Intended for internal testing use only!!
|
* Intended for internal testing use only!!
|
||||||
*/
|
*/
|
||||||
|
@ -94,11 +142,12 @@ public class StandardServiceRegistryBuilder {
|
||||||
* @return List of standard initiators
|
* @return List of standard initiators
|
||||||
*/
|
*/
|
||||||
private static List<StandardServiceInitiator> standardInitiatorList() {
|
private static List<StandardServiceInitiator> standardInitiatorList() {
|
||||||
final List<StandardServiceInitiator> initiators = new ArrayList<StandardServiceInitiator>();
|
final List<StandardServiceInitiator> initiators = new ArrayList<>( StandardServiceInitiators.LIST.size() );
|
||||||
initiators.addAll( StandardServiceInitiators.LIST );
|
initiators.addAll( StandardServiceInitiators.LIST );
|
||||||
return initiators;
|
return initiators;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
public BootstrapServiceRegistry getBootstrapServiceRegistry() {
|
public BootstrapServiceRegistry getBootstrapServiceRegistry() {
|
||||||
return bootstrapServiceRegistry;
|
return bootstrapServiceRegistry;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.internal.util;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class NullnessHelper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Operates like SQL coalesce expression, except empty strings are treated as null. Return the first non-empty value
|
||||||
|
*
|
||||||
|
* @param values The list of values.
|
||||||
|
* @param <T> Generic type of values to coalesce
|
||||||
|
*
|
||||||
|
* @return The first non-empty value, or null if all values were empty
|
||||||
|
*/
|
||||||
|
public static <T> T coalesce(T... values) {
|
||||||
|
if ( values == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for ( T value : values ) {
|
||||||
|
if ( value != null ) {
|
||||||
|
if ( String.class.isInstance( value ) ) {
|
||||||
|
if ( !( (String) value ).isEmpty() ) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the first non-null value supplied by the given suppliers
|
||||||
|
*/
|
||||||
|
public static <T> T coalesceSuppliedValues(Supplier<T>... valueSuppliers) {
|
||||||
|
if ( valueSuppliers == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( Supplier<T> valueSupplier : valueSuppliers ) {
|
||||||
|
final T value = valueSupplier.get();
|
||||||
|
if ( value != null ) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,11 +27,9 @@ import javax.sql.DataSource;
|
||||||
import org.hibernate.SessionFactory;
|
import org.hibernate.SessionFactory;
|
||||||
import org.hibernate.SessionFactoryObserver;
|
import org.hibernate.SessionFactoryObserver;
|
||||||
import org.hibernate.boot.CacheRegionDefinition;
|
import org.hibernate.boot.CacheRegionDefinition;
|
||||||
import org.hibernate.boot.MetadataBuilder;
|
|
||||||
import org.hibernate.boot.MetadataSources;
|
import org.hibernate.boot.MetadataSources;
|
||||||
import org.hibernate.boot.SessionFactoryBuilder;
|
import org.hibernate.boot.SessionFactoryBuilder;
|
||||||
import org.hibernate.boot.archive.scan.internal.StandardScanOptions;
|
import org.hibernate.boot.archive.scan.internal.StandardScanOptions;
|
||||||
import org.hibernate.boot.cfgxml.internal.ConfigLoader;
|
|
||||||
import org.hibernate.boot.cfgxml.spi.CfgXmlAccessService;
|
import org.hibernate.boot.cfgxml.spi.CfgXmlAccessService;
|
||||||
import org.hibernate.boot.cfgxml.spi.LoadedConfig;
|
import org.hibernate.boot.cfgxml.spi.LoadedConfig;
|
||||||
import org.hibernate.boot.cfgxml.spi.MappingReference;
|
import org.hibernate.boot.cfgxml.spi.MappingReference;
|
||||||
|
@ -60,7 +58,9 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.id.factory.spi.MutableIdentifierGeneratorFactory;
|
import org.hibernate.id.factory.spi.MutableIdentifierGeneratorFactory;
|
||||||
import org.hibernate.integrator.spi.Integrator;
|
import org.hibernate.integrator.spi.Integrator;
|
||||||
import org.hibernate.internal.EntityManagerMessageLogger;
|
import org.hibernate.internal.EntityManagerMessageLogger;
|
||||||
|
import org.hibernate.internal.util.NullnessHelper;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
|
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||||
import org.hibernate.jpa.AvailableSettings;
|
import org.hibernate.jpa.AvailableSettings;
|
||||||
import org.hibernate.jpa.boot.spi.EntityManagerFactoryBuilder;
|
import org.hibernate.jpa.boot.spi.EntityManagerFactoryBuilder;
|
||||||
import org.hibernate.jpa.boot.spi.IntegratorProvider;
|
import org.hibernate.jpa.boot.spi.IntegratorProvider;
|
||||||
|
@ -73,6 +73,7 @@ import org.hibernate.jpa.spi.IdentifierGeneratorStrategyProvider;
|
||||||
import org.hibernate.proxy.EntityNotFoundDelegate;
|
import org.hibernate.proxy.EntityNotFoundDelegate;
|
||||||
import org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorBuilderImpl;
|
import org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorBuilderImpl;
|
||||||
import org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorBuilderImpl;
|
import org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorBuilderImpl;
|
||||||
|
import org.hibernate.resource.transaction.spi.TransactionCoordinatorBuilder;
|
||||||
import org.hibernate.secure.spi.GrantedPermission;
|
import org.hibernate.secure.spi.GrantedPermission;
|
||||||
import org.hibernate.secure.spi.JaccPermissionDeclarations;
|
import org.hibernate.secure.spi.JaccPermissionDeclarations;
|
||||||
import org.hibernate.service.ServiceRegistry;
|
import org.hibernate.service.ServiceRegistry;
|
||||||
|
@ -199,24 +200,31 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
||||||
final BootstrapServiceRegistry bsr = buildBootstrapServiceRegistry( integrationSettings, providedClassLoader, providedClassLoaderService);
|
final BootstrapServiceRegistry bsr = buildBootstrapServiceRegistry( integrationSettings, providedClassLoader, providedClassLoaderService);
|
||||||
|
|
||||||
// merge configuration sources and build the "standard" service registry
|
// merge configuration sources and build the "standard" service registry
|
||||||
final StandardServiceRegistryBuilder ssrBuilder = new StandardServiceRegistryBuilder( bsr );
|
final StandardServiceRegistryBuilder ssrBuilder = StandardServiceRegistryBuilder.forJpa( bsr );
|
||||||
|
|
||||||
final MergedSettings mergedSettings = mergeSettings( persistenceUnit, integrationSettings, ssrBuilder );
|
final MergedSettings mergedSettings = mergeSettings( persistenceUnit, integrationSettings, ssrBuilder );
|
||||||
|
|
||||||
|
// flush before completion validation
|
||||||
|
if ( "true".equals( mergedSettings.configurationValues.get( Environment.FLUSH_BEFORE_COMPLETION ) ) ) {
|
||||||
|
LOG.definingFlushBeforeCompletionIgnoredInHem( Environment.FLUSH_BEFORE_COMPLETION );
|
||||||
|
mergedSettings.configurationValues.put( Environment.FLUSH_BEFORE_COMPLETION, "false" );
|
||||||
|
}
|
||||||
|
|
||||||
|
// keep the merged config values for phase-2
|
||||||
this.configurationValues = mergedSettings.getConfigurationValues();
|
this.configurationValues = mergedSettings.getConfigurationValues();
|
||||||
|
|
||||||
// Build the "standard" service registry
|
// Build the "standard" service registry
|
||||||
ssrBuilder.applySettings( configurationValues );
|
ssrBuilder.applySettings( configurationValues );
|
||||||
configure( ssrBuilder );
|
|
||||||
this.standardServiceRegistry = ssrBuilder.build();
|
this.standardServiceRegistry = ssrBuilder.build();
|
||||||
configure( standardServiceRegistry, mergedSettings );
|
|
||||||
|
configureIdentifierGenerators( standardServiceRegistry );
|
||||||
|
|
||||||
final MetadataSources metadataSources = new MetadataSources( bsr );
|
final MetadataSources metadataSources = new MetadataSources( bsr );
|
||||||
List<AttributeConverterDefinition> attributeConverterDefinitions = populate(
|
List<AttributeConverterDefinition> attributeConverterDefinitions = applyMappingResources( metadataSources );
|
||||||
metadataSources,
|
|
||||||
mergedSettings,
|
|
||||||
standardServiceRegistry
|
|
||||||
);
|
|
||||||
this.metamodelBuilder = (MetadataBuilderImplementor) metadataSources.getMetadataBuilder( standardServiceRegistry );
|
this.metamodelBuilder = (MetadataBuilderImplementor) metadataSources.getMetadataBuilder( standardServiceRegistry );
|
||||||
populate( metamodelBuilder, mergedSettings, standardServiceRegistry, attributeConverterDefinitions );
|
applyMetamodelBuilderSettings( mergedSettings, attributeConverterDefinitions );
|
||||||
|
|
||||||
// todo : would be nice to have MetadataBuilder still do the handling of CfgXmlAccessService here
|
// todo : would be nice to have MetadataBuilder still do the handling of CfgXmlAccessService here
|
||||||
// another option is to immediately handle them here (probably in mergeSettings?) as we encounter them...
|
// another option is to immediately handle them here (probably in mergeSettings?) as we encounter them...
|
||||||
|
@ -308,7 +316,6 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
||||||
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// temporary!
|
// temporary!
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public Map getConfigurationValues() {
|
public Map getConfigurationValues() {
|
||||||
return Collections.unmodifiableMap( configurationValues );
|
return Collections.unmodifiableMap( configurationValues );
|
||||||
}
|
}
|
||||||
|
@ -327,7 +334,10 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
||||||
* @param associationManagementEnabled To enable association management feature
|
* @param associationManagementEnabled To enable association management feature
|
||||||
* @return An enhancement context for classes managed by this EM
|
* @return An enhancement context for classes managed by this EM
|
||||||
*/
|
*/
|
||||||
protected EnhancementContext getEnhancementContext(final boolean dirtyTrackingEnabled, final boolean lazyInitializationEnabled, final boolean associationManagementEnabled ) {
|
protected EnhancementContext getEnhancementContext(
|
||||||
|
final boolean dirtyTrackingEnabled,
|
||||||
|
final boolean lazyInitializationEnabled,
|
||||||
|
final boolean associationManagementEnabled ) {
|
||||||
return new DefaultEnhancementContext() {
|
return new DefaultEnhancementContext() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -455,62 +465,25 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
||||||
return bsrBuilder.build();
|
return bsrBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private MergedSettings mergeSettings(
|
private MergedSettings mergeSettings(
|
||||||
PersistenceUnitDescriptor persistenceUnit,
|
PersistenceUnitDescriptor persistenceUnit,
|
||||||
Map<?,?> integrationSettings,
|
Map<?,?> integrationSettings,
|
||||||
StandardServiceRegistryBuilder ssrBuilder) {
|
StandardServiceRegistryBuilder ssrBuilder) {
|
||||||
final MergedSettings mergedSettings = new MergedSettings();
|
final MergedSettings mergedSettings = new MergedSettings();
|
||||||
|
mergedSettings.processPersistenceUnitDescriptorProperties( persistenceUnit );
|
||||||
// first, apply persistence.xml-defined settings
|
|
||||||
if ( persistenceUnit.getProperties() != null ) {
|
|
||||||
mergedSettings.configurationValues.putAll( persistenceUnit.getProperties() );
|
|
||||||
}
|
|
||||||
|
|
||||||
mergedSettings.configurationValues.put( PERSISTENCE_UNIT_NAME, persistenceUnit.getName() );
|
|
||||||
|
|
||||||
final ConfigLoader configLoader = new ConfigLoader( ssrBuilder.getBootstrapServiceRegistry() );
|
|
||||||
|
|
||||||
// see if the persistence.xml settings named a Hibernate config file....
|
// see if the persistence.xml settings named a Hibernate config file....
|
||||||
final String cfgXmlResourceName1 = (String) mergedSettings.configurationValues.remove( CFG_FILE );
|
String cfgXmlResourceName = (String) mergedSettings.configurationValues.remove( CFG_FILE );
|
||||||
if ( StringHelper.isNotEmpty( cfgXmlResourceName1 ) ) {
|
if ( StringHelper.isEmpty( cfgXmlResourceName ) ) {
|
||||||
final LoadedConfig loadedCfg = configLoader.loadConfigXmlResource( cfgXmlResourceName1 );
|
// see if integration settings named a Hibernate config file....
|
||||||
processConfigXml( loadedCfg, mergedSettings, ssrBuilder );
|
cfgXmlResourceName = (String) integrationSettings.get( CFG_FILE );
|
||||||
}
|
}
|
||||||
|
|
||||||
// see if integration settings named a Hibernate config file....
|
if ( StringHelper.isNotEmpty( cfgXmlResourceName ) ) {
|
||||||
final String cfgXmlResourceName2 = (String) integrationSettings.get( CFG_FILE );
|
processHibernateConfigXmlResources( ssrBuilder, mergedSettings, cfgXmlResourceName );
|
||||||
if ( StringHelper.isNotEmpty( cfgXmlResourceName2 ) ) {
|
|
||||||
integrationSettings.remove( CFG_FILE );
|
|
||||||
final LoadedConfig loadedCfg = configLoader.loadConfigXmlResource( cfgXmlResourceName2 );
|
|
||||||
processConfigXml( loadedCfg, mergedSettings, ssrBuilder );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// finally, apply integration-supplied settings (per JPA spec, integration settings should override other sources)
|
normalizeSettings( persistenceUnit, integrationSettings, mergedSettings );
|
||||||
for ( Map.Entry<?,?> entry : integrationSettings.entrySet() ) {
|
|
||||||
if ( entry.getKey() == null ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( entry.getValue() == null ) {
|
|
||||||
mergedSettings.configurationValues.remove( entry.getKey() );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
mergedSettings.configurationValues.put( entry.getKey(), entry.getValue() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !mergedSettings.configurationValues.containsKey( JPA_VALIDATION_MODE ) ) {
|
|
||||||
if ( persistenceUnit.getValidationMode() != null ) {
|
|
||||||
mergedSettings.configurationValues.put( JPA_VALIDATION_MODE, persistenceUnit.getValidationMode() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !mergedSettings.configurationValues.containsKey( JPA_SHARED_CACHE_MODE ) ) {
|
|
||||||
if ( persistenceUnit.getSharedCacheMode() != null ) {
|
|
||||||
mergedSettings.configurationValues.put( JPA_SHARED_CACHE_MODE, persistenceUnit.getSharedCacheMode() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final String jaccContextId = (String) mergedSettings.configurationValues.get( JACC_CONTEXT_ID );
|
final String jaccContextId = (String) mergedSettings.configurationValues.get( JACC_CONTEXT_ID );
|
||||||
|
|
||||||
|
@ -571,22 +544,446 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
||||||
return mergedSettings;
|
return mergedSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles normalizing the settings coming from multiple sources, applying proper precedences
|
||||||
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void processConfigXml(
|
private void normalizeSettings(
|
||||||
LoadedConfig loadedConfig,
|
PersistenceUnitDescriptor persistenceUnit,
|
||||||
MergedSettings mergedSettings,
|
Map<?, ?> integrationSettings,
|
||||||
StandardServiceRegistryBuilder ssrBuilder) {
|
MergedSettings mergedSettings) {
|
||||||
if ( ! mergedSettings.configurationValues.containsKey( SESSION_FACTORY_NAME ) ) {
|
// make a copy so we can remove things as we process them
|
||||||
// there is not already a SF-name in the merged settings
|
final HashMap<?, ?> integrationSettingsCopy = new HashMap<>( integrationSettings );
|
||||||
final String sfName = loadedConfig.getSessionFactoryName();
|
|
||||||
if ( sfName != null ) {
|
normalizeConnectionAccessUserAndPass( integrationSettingsCopy, mergedSettings );
|
||||||
// but the cfg.xml file we are processing named one..
|
|
||||||
mergedSettings.configurationValues.put( SESSION_FACTORY_NAME, sfName );
|
normalizeTransactionCoordinator( persistenceUnit, integrationSettingsCopy, mergedSettings );
|
||||||
|
|
||||||
|
normalizeDataAccess( integrationSettingsCopy, mergedSettings, persistenceUnit );
|
||||||
|
|
||||||
|
// normalize ValidationMode
|
||||||
|
final Object intgValidationMode = integrationSettingsCopy.remove( JPA_VALIDATION_MODE );
|
||||||
|
if ( intgValidationMode != null ) {
|
||||||
|
mergedSettings.configurationValues.put( JPA_VALIDATION_MODE, intgValidationMode );
|
||||||
|
}
|
||||||
|
else if ( persistenceUnit.getValidationMode() != null ) {
|
||||||
|
mergedSettings.configurationValues.put( JPA_VALIDATION_MODE, persistenceUnit.getValidationMode() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// normalize SharedCacheMode
|
||||||
|
final Object intgCacheMode = integrationSettingsCopy.remove( JPA_SHARED_CACHE_MODE );
|
||||||
|
if ( intgCacheMode != null ) {
|
||||||
|
mergedSettings.configurationValues.put( JPA_SHARED_CACHE_MODE, intgCacheMode );
|
||||||
|
}
|
||||||
|
else if ( persistenceUnit.getSharedCacheMode() != null ) {
|
||||||
|
mergedSettings.configurationValues.put( JPA_SHARED_CACHE_MODE, persistenceUnit.getSharedCacheMode() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply all "integration overrides" as the last step. By specification,
|
||||||
|
// these should have precedence.
|
||||||
|
//
|
||||||
|
// NOTE that this occurs after the specialized normalize calls above which remove
|
||||||
|
// any specially-handled settings.
|
||||||
|
for ( Map.Entry<?,?> entry : integrationSettingsCopy.entrySet() ) {
|
||||||
|
if ( entry.getKey() == null ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( entry.getValue() == null ) {
|
||||||
|
mergedSettings.configurationValues.remove( entry.getKey() );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mergedSettings.configurationValues.put( entry.getKey(), entry.getValue() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Because a DataSource can be secured (requiring Hibernate to pass the USER/PASSWORD when accessing the DataSource)
|
||||||
|
* we apply precedence to the USER and PASS separately
|
||||||
|
*/
|
||||||
|
private void normalizeConnectionAccessUserAndPass(
|
||||||
|
HashMap<?, ?> integrationSettingsCopy,
|
||||||
|
MergedSettings mergedSettings) {
|
||||||
|
//noinspection unchecked
|
||||||
|
final Object effectiveUser = NullnessHelper.coalesceSuppliedValues(
|
||||||
|
() -> integrationSettingsCopy.remove( USER ),
|
||||||
|
() -> integrationSettingsCopy.remove( JPA_JDBC_USER ),
|
||||||
|
() -> extractPuProperty( persistenceUnit, USER ),
|
||||||
|
() -> extractPuProperty( persistenceUnit, JPA_JDBC_USER )
|
||||||
|
);
|
||||||
|
|
||||||
|
//noinspection unchecked
|
||||||
|
final Object effectivePass = NullnessHelper.coalesceSuppliedValues(
|
||||||
|
() -> integrationSettingsCopy.remove( PASS ),
|
||||||
|
() -> integrationSettingsCopy.remove( JPA_JDBC_PASSWORD ),
|
||||||
|
() -> extractPuProperty( persistenceUnit, PASS ),
|
||||||
|
() -> extractPuProperty( persistenceUnit, JPA_JDBC_PASSWORD )
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( effectiveUser != null || effectivePass != null ) {
|
||||||
|
applyUserAndPass( effectiveUser, effectivePass, mergedSettings );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> T extractPuProperty(PersistenceUnitDescriptor persistenceUnit, String propertyName) {
|
||||||
|
//noinspection unchecked
|
||||||
|
return persistenceUnit.getProperties() == null ? null : (T) persistenceUnit.getProperties().get( propertyName );
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private void applyUserAndPass(Object effectiveUser, Object effectivePass, MergedSettings mergedSettings) {
|
||||||
|
if ( effectiveUser != null ) {
|
||||||
|
mergedSettings.configurationValues.put( USER, effectiveUser );
|
||||||
|
mergedSettings.configurationValues.put( JPA_JDBC_USER, effectiveUser );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( effectivePass != null ) {
|
||||||
|
mergedSettings.configurationValues.put( PASS, effectivePass );
|
||||||
|
mergedSettings.configurationValues.put( JPA_JDBC_PASSWORD, effectivePass );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String IS_JTA_TXN_COORD = "local.setting.IS_JTA_TXN_COORD";
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private void normalizeTransactionCoordinator(
|
||||||
|
PersistenceUnitDescriptor persistenceUnit,
|
||||||
|
HashMap<?, ?> integrationSettingsCopy,
|
||||||
|
MergedSettings mergedSettings) {
|
||||||
|
PersistenceUnitTransactionType txnType = null;
|
||||||
|
|
||||||
|
final Object intgTxnType = integrationSettingsCopy.remove( JPA_TRANSACTION_TYPE );
|
||||||
|
|
||||||
|
if ( intgTxnType != null ) {
|
||||||
|
txnType = PersistenceUnitTransactionTypeHelper.interpretTransactionType( intgTxnType );
|
||||||
|
}
|
||||||
|
else if ( persistenceUnit.getTransactionType() != null ) {
|
||||||
|
txnType = persistenceUnit.getTransactionType();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
final Object puPropTxnType = mergedSettings.configurationValues.get( JPA_TRANSACTION_TYPE );
|
||||||
|
if ( puPropTxnType != null ) {
|
||||||
|
txnType = PersistenceUnitTransactionTypeHelper.interpretTransactionType( puPropTxnType );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mergedSettings.configurationValues.putAll( loadedConfig.getConfigurationValues() );
|
if ( txnType == null ) {
|
||||||
ssrBuilder.configure( loadedConfig );
|
// is it more appropriate to have this be based on bootstrap entry point (EE vs SE)?
|
||||||
|
LOG.debugf( "PersistenceUnitTransactionType not specified - falling back to RESOURCE_LOCAL" );
|
||||||
|
txnType = PersistenceUnitTransactionType.RESOURCE_LOCAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean hasTxStrategy = mergedSettings.configurationValues.containsKey( TRANSACTION_COORDINATOR_STRATEGY );
|
||||||
|
final Boolean definiteJtaCoordinator;
|
||||||
|
|
||||||
|
if ( hasTxStrategy ) {
|
||||||
|
LOG.overridingTransactionStrategyDangerous( TRANSACTION_COORDINATOR_STRATEGY );
|
||||||
|
|
||||||
|
// see if we can tell whether it is a JTA coordinator
|
||||||
|
final Object strategy = mergedSettings.configurationValues.get( TRANSACTION_COORDINATOR_STRATEGY );
|
||||||
|
if ( strategy instanceof TransactionCoordinatorBuilder ) {
|
||||||
|
definiteJtaCoordinator = ( (TransactionCoordinatorBuilder) strategy ).isJta();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
definiteJtaCoordinator = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ( txnType == PersistenceUnitTransactionType.JTA ) {
|
||||||
|
mergedSettings.configurationValues.put( TRANSACTION_COORDINATOR_STRATEGY, JtaTransactionCoordinatorBuilderImpl.class );
|
||||||
|
definiteJtaCoordinator = true;
|
||||||
|
}
|
||||||
|
else if ( txnType == PersistenceUnitTransactionType.RESOURCE_LOCAL ) {
|
||||||
|
mergedSettings.configurationValues.put( TRANSACTION_COORDINATOR_STRATEGY, JdbcResourceLocalTransactionCoordinatorBuilderImpl.class );
|
||||||
|
definiteJtaCoordinator = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new IllegalStateException( "Could not determine TransactionCoordinator strategy to use" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mergedSettings.configurationValues.put( IS_JTA_TXN_COORD, definiteJtaCoordinator );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void normalizeDataAccess(
|
||||||
|
HashMap<?, ?> integrationSettingsCopy,
|
||||||
|
MergedSettings mergedSettings,
|
||||||
|
PersistenceUnitDescriptor persistenceUnit) {
|
||||||
|
if ( dataSource != null ) {
|
||||||
|
applyDataSource(
|
||||||
|
dataSource,
|
||||||
|
// we don't explicitly know
|
||||||
|
null,
|
||||||
|
integrationSettingsCopy,
|
||||||
|
mergedSettings
|
||||||
|
);
|
||||||
|
|
||||||
|
// EARLY EXIT!!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( integrationSettingsCopy.containsKey( DATASOURCE ) ) {
|
||||||
|
final Object dataSourceRef = integrationSettingsCopy.remove( DATASOURCE );
|
||||||
|
if ( dataSourceRef != null ) {
|
||||||
|
applyDataSource(
|
||||||
|
dataSourceRef,
|
||||||
|
null,
|
||||||
|
integrationSettingsCopy,
|
||||||
|
mergedSettings
|
||||||
|
);
|
||||||
|
|
||||||
|
// EARLY EXIT!!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( integrationSettingsCopy.containsKey( JPA_JTA_DATASOURCE ) ) {
|
||||||
|
final Object dataSourceRef = integrationSettingsCopy.remove( JPA_JTA_DATASOURCE );
|
||||||
|
if ( dataSourceRef != null ) {
|
||||||
|
applyDataSource(
|
||||||
|
dataSourceRef,
|
||||||
|
true,
|
||||||
|
integrationSettingsCopy,
|
||||||
|
mergedSettings
|
||||||
|
);
|
||||||
|
|
||||||
|
// EARLY EXIT!!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( integrationSettingsCopy.containsKey( JPA_NON_JTA_DATASOURCE ) ) {
|
||||||
|
final Object dataSourceRef = integrationSettingsCopy.remove( JPA_NON_JTA_DATASOURCE );
|
||||||
|
|
||||||
|
applyDataSource(
|
||||||
|
dataSourceRef,
|
||||||
|
false,
|
||||||
|
integrationSettingsCopy,
|
||||||
|
mergedSettings
|
||||||
|
);
|
||||||
|
|
||||||
|
// EARLY EXIT!!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( integrationSettingsCopy.containsKey( URL ) ) {
|
||||||
|
// these have precedence over the JPA ones
|
||||||
|
final Object integrationJdbcUrl = integrationSettingsCopy.get( URL );
|
||||||
|
if ( integrationJdbcUrl != null ) {
|
||||||
|
//noinspection unchecked
|
||||||
|
applyJdbcSettings(
|
||||||
|
integrationJdbcUrl,
|
||||||
|
NullnessHelper.coalesceSuppliedValues(
|
||||||
|
() -> ConfigurationHelper.getString( DRIVER, integrationSettingsCopy ),
|
||||||
|
() -> ConfigurationHelper.getString( JPA_JDBC_DRIVER, integrationSettingsCopy ),
|
||||||
|
() -> ConfigurationHelper.getString( DRIVER, mergedSettings.configurationValues ),
|
||||||
|
() -> ConfigurationHelper.getString( JPA_JDBC_DRIVER, mergedSettings.configurationValues )
|
||||||
|
),
|
||||||
|
integrationSettingsCopy,
|
||||||
|
mergedSettings
|
||||||
|
);
|
||||||
|
|
||||||
|
// EARLY EXIT!!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( integrationSettingsCopy.containsKey( JPA_JDBC_URL ) ) {
|
||||||
|
final Object integrationJdbcUrl = integrationSettingsCopy.get( JPA_JDBC_URL );
|
||||||
|
|
||||||
|
if ( integrationJdbcUrl != null ) {
|
||||||
|
//noinspection unchecked
|
||||||
|
applyJdbcSettings(
|
||||||
|
integrationJdbcUrl,
|
||||||
|
NullnessHelper.coalesceSuppliedValues(
|
||||||
|
() -> ConfigurationHelper.getString( JPA_JDBC_DRIVER, integrationSettingsCopy ),
|
||||||
|
() -> ConfigurationHelper.getString( JPA_JDBC_DRIVER, mergedSettings.configurationValues )
|
||||||
|
),
|
||||||
|
integrationSettingsCopy,
|
||||||
|
mergedSettings
|
||||||
|
);
|
||||||
|
|
||||||
|
// EARLY EXIT!!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( persistenceUnit.getJtaDataSource() != null ) {
|
||||||
|
applyDataSource(
|
||||||
|
persistenceUnit.getJtaDataSource(),
|
||||||
|
true,
|
||||||
|
integrationSettingsCopy,
|
||||||
|
mergedSettings
|
||||||
|
);
|
||||||
|
|
||||||
|
// EARLY EXIT!!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( persistenceUnit.getNonJtaDataSource() != null ) {
|
||||||
|
applyDataSource(
|
||||||
|
persistenceUnit.getNonJtaDataSource(),
|
||||||
|
false,
|
||||||
|
integrationSettingsCopy,
|
||||||
|
mergedSettings
|
||||||
|
);
|
||||||
|
|
||||||
|
// EARLY EXIT!!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( mergedSettings.configurationValues.containsKey( URL ) ) {
|
||||||
|
final Object url = mergedSettings.configurationValues.get( URL );
|
||||||
|
|
||||||
|
if ( url != null && ( ! ( url instanceof String ) || StringHelper.isNotEmpty( (String) url ) ) ) {
|
||||||
|
applyJdbcSettings(
|
||||||
|
url,
|
||||||
|
ConfigurationHelper.getString( DRIVER, mergedSettings.configurationValues ),
|
||||||
|
integrationSettingsCopy,
|
||||||
|
mergedSettings
|
||||||
|
);
|
||||||
|
|
||||||
|
// EARLY EXIT!!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( mergedSettings.configurationValues.containsKey( JPA_JDBC_URL ) ) {
|
||||||
|
final Object url = mergedSettings.configurationValues.get( JPA_JDBC_URL );
|
||||||
|
|
||||||
|
if ( url != null && ( ! ( url instanceof String ) || StringHelper.isNotEmpty( (String) url ) ) ) {
|
||||||
|
applyJdbcSettings(
|
||||||
|
url,
|
||||||
|
ConfigurationHelper.getString( JPA_JDBC_DRIVER, mergedSettings.configurationValues ),
|
||||||
|
integrationSettingsCopy,
|
||||||
|
mergedSettings
|
||||||
|
);
|
||||||
|
|
||||||
|
// EARLY EXIT!!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// any other conditions to account for?
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private void applyDataSource(
|
||||||
|
Object dataSourceRef,
|
||||||
|
Boolean useJtaDataSource,
|
||||||
|
HashMap<?, ?> integrationSettingsCopy,
|
||||||
|
MergedSettings mergedSettings) {
|
||||||
|
|
||||||
|
// `IS_JTA_TXN_COORD` is a value set during `#normalizeTransactionCoordinator` to indicate whether
|
||||||
|
// the execution environment "is JTA" as best as it can tell..
|
||||||
|
//
|
||||||
|
// we use this value when JTA was not explicitly specified in regards the DataSource
|
||||||
|
final boolean isJtaTransactionCoordinator = (boolean) mergedSettings.configurationValues.remove( IS_JTA_TXN_COORD );
|
||||||
|
final boolean isJta = useJtaDataSource == null ? isJtaTransactionCoordinator : useJtaDataSource;
|
||||||
|
|
||||||
|
// add to EMF properties (questionable - see HHH-13432)
|
||||||
|
final String emfKey;
|
||||||
|
final String inverseEmfKey;
|
||||||
|
if ( isJta ) {
|
||||||
|
emfKey = JPA_JTA_DATASOURCE;
|
||||||
|
inverseEmfKey = JPA_NON_JTA_DATASOURCE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
emfKey = JPA_NON_JTA_DATASOURCE;
|
||||||
|
inverseEmfKey = JPA_JTA_DATASOURCE;
|
||||||
|
}
|
||||||
|
mergedSettings.configurationValues.put( emfKey, dataSourceRef );
|
||||||
|
|
||||||
|
// clear any settings logically overridden by this datasource
|
||||||
|
cleanUpConfigKeys(
|
||||||
|
integrationSettingsCopy,
|
||||||
|
mergedSettings,
|
||||||
|
inverseEmfKey,
|
||||||
|
JPA_JDBC_DRIVER,
|
||||||
|
DRIVER,
|
||||||
|
JPA_JDBC_URL,
|
||||||
|
URL
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// clean-up the entries in the "integration overrides" so they do not get get picked
|
||||||
|
// up in the general "integration overrides" handling
|
||||||
|
cleanUpConfigKeys( integrationSettingsCopy, DATASOURCE, JPA_JTA_DATASOURCE, JPA_NON_JTA_DATASOURCE );
|
||||||
|
|
||||||
|
// add under Hibernate's DATASOURCE setting where the ConnectionProvider will find it
|
||||||
|
mergedSettings.configurationValues.put( DATASOURCE, dataSourceRef );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cleanUpConfigKeys(HashMap<?, ?> integrationSettingsCopy, MergedSettings mergedSettings, String... keys) {
|
||||||
|
for ( String key : keys ) {
|
||||||
|
final Object removedIntgSetting = integrationSettingsCopy.remove( key );
|
||||||
|
if ( removedIntgSetting != null ) {
|
||||||
|
LOG.debugf( "Removed integration override setting [%s] due to normalization", key );
|
||||||
|
}
|
||||||
|
|
||||||
|
final Object removedMergedSetting = mergedSettings.configurationValues.remove( key );
|
||||||
|
if ( removedMergedSetting != null ) {
|
||||||
|
LOG.debugf( "Removed merged setting [%s] due to normalization", key );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cleanUpConfigKeys(Map<?, ?> settings, String... keys) {
|
||||||
|
for ( String key : keys ) {
|
||||||
|
settings.remove( key );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private void applyJdbcSettings(
|
||||||
|
Object url,
|
||||||
|
String driver,
|
||||||
|
HashMap<?, ?> integrationSettingsCopy,
|
||||||
|
MergedSettings mergedSettings) {
|
||||||
|
mergedSettings.configurationValues.put( URL, url );
|
||||||
|
mergedSettings.configurationValues.put( JPA_JDBC_URL, url );
|
||||||
|
|
||||||
|
if ( driver != null ) {
|
||||||
|
mergedSettings.configurationValues.put( DRIVER, driver );
|
||||||
|
mergedSettings.configurationValues.put( JPA_JDBC_DRIVER, driver );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mergedSettings.configurationValues.remove( DRIVER );
|
||||||
|
mergedSettings.configurationValues.remove( JPA_JDBC_DRIVER );
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean up the integration-map values
|
||||||
|
cleanUpConfigKeys(
|
||||||
|
integrationSettingsCopy,
|
||||||
|
DRIVER,
|
||||||
|
JPA_JDBC_DRIVER,
|
||||||
|
URL,
|
||||||
|
JPA_JDBC_URL,
|
||||||
|
USER,
|
||||||
|
JPA_JDBC_USER,
|
||||||
|
PASS,
|
||||||
|
JPA_JDBC_PASSWORD
|
||||||
|
);
|
||||||
|
|
||||||
|
cleanUpConfigKeys(
|
||||||
|
integrationSettingsCopy,
|
||||||
|
mergedSettings,
|
||||||
|
DATASOURCE,
|
||||||
|
JPA_JTA_DATASOURCE,
|
||||||
|
JPA_NON_JTA_DATASOURCE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processHibernateConfigXmlResources(
|
||||||
|
StandardServiceRegistryBuilder ssrBuilder,
|
||||||
|
MergedSettings mergedSettings,
|
||||||
|
String cfgXmlResourceName) {
|
||||||
|
final LoadedConfig loadedConfig = ssrBuilder.getConfigLoader().loadConfigXmlResource( cfgXmlResourceName );
|
||||||
|
|
||||||
|
mergedSettings.processHibernateConfigXmlResources( loadedConfig );
|
||||||
|
|
||||||
|
ssrBuilder.getAggregatedCfgXml().merge( loadedConfig );
|
||||||
}
|
}
|
||||||
|
|
||||||
private GrantedPermission parseJaccConfigEntry(String keyString, String valueString) {
|
private GrantedPermission parseJaccConfigEntry(String keyString, String valueString) {
|
||||||
|
@ -642,90 +1039,7 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
||||||
return new CacheRegionDefinition( cacheType, role, usage, region, lazyProperty );
|
return new CacheRegionDefinition( cacheType, role, usage, region, lazyProperty );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void configure(StandardServiceRegistryBuilder ssrBuilder) {
|
private void configureIdentifierGenerators(StandardServiceRegistry ssr) {
|
||||||
|
|
||||||
applyJdbcConnectionProperties( ssrBuilder );
|
|
||||||
applyTransactionProperties( ssrBuilder );
|
|
||||||
|
|
||||||
// flush before completion validation
|
|
||||||
if ( "true".equals( configurationValues.get( Environment.FLUSH_BEFORE_COMPLETION ) ) ) {
|
|
||||||
ssrBuilder.applySetting( Environment.FLUSH_BEFORE_COMPLETION, "false" );
|
|
||||||
LOG.definingFlushBeforeCompletionIgnoredInHem( Environment.FLUSH_BEFORE_COMPLETION );
|
|
||||||
}
|
|
||||||
|
|
||||||
// final StrategySelector strategySelector = ssrBuilder.getBootstrapServiceRegistry().getService( StrategySelector.class );
|
|
||||||
// final Object interceptorSetting = configurationValues.remove( AvailableSettings.SESSION_INTERCEPTOR );
|
|
||||||
// if ( interceptorSetting != null ) {
|
|
||||||
// settings.setSessionInterceptorClass(
|
|
||||||
// loadSessionInterceptorClass( interceptorSetting, strategySelector )
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
private void applyJdbcConnectionProperties(StandardServiceRegistryBuilder ssrBuilder) {
|
|
||||||
if ( dataSource != null ) {
|
|
||||||
ssrBuilder.applySetting( DATASOURCE, dataSource );
|
|
||||||
}
|
|
||||||
else if ( persistenceUnit.getJtaDataSource() != null ) {
|
|
||||||
if ( ! ssrBuilder.getSettings().containsKey( DATASOURCE ) ) {
|
|
||||||
ssrBuilder.applySetting( DATASOURCE, persistenceUnit.getJtaDataSource() );
|
|
||||||
// HHH-8121 : make the PU-defined value available to EMF.getProperties()
|
|
||||||
configurationValues.put( JPA_JTA_DATASOURCE, persistenceUnit.getJtaDataSource() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( persistenceUnit.getNonJtaDataSource() != null ) {
|
|
||||||
if ( ! ssrBuilder.getSettings().containsKey( DATASOURCE ) ) {
|
|
||||||
ssrBuilder.applySetting( DATASOURCE, persistenceUnit.getNonJtaDataSource() );
|
|
||||||
// HHH-8121 : make the PU-defined value available to EMF.getProperties()
|
|
||||||
configurationValues.put( JPA_NON_JTA_DATASOURCE, persistenceUnit.getNonJtaDataSource() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
final String driver = (String) configurationValues.get( JPA_JDBC_DRIVER );
|
|
||||||
if ( StringHelper.isNotEmpty( driver ) ) {
|
|
||||||
ssrBuilder.applySetting( DRIVER, driver );
|
|
||||||
}
|
|
||||||
final String url = (String) configurationValues.get( JPA_JDBC_URL );
|
|
||||||
if ( StringHelper.isNotEmpty( url ) ) {
|
|
||||||
ssrBuilder.applySetting( URL, url );
|
|
||||||
}
|
|
||||||
final String user = (String) configurationValues.get( JPA_JDBC_USER );
|
|
||||||
if ( StringHelper.isNotEmpty( user ) ) {
|
|
||||||
ssrBuilder.applySetting( USER, user );
|
|
||||||
}
|
|
||||||
final String pass = (String) configurationValues.get( JPA_JDBC_PASSWORD );
|
|
||||||
if ( StringHelper.isNotEmpty( pass ) ) {
|
|
||||||
ssrBuilder.applySetting( PASS, pass );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void applyTransactionProperties(StandardServiceRegistryBuilder ssrBuilder) {
|
|
||||||
PersistenceUnitTransactionType txnType = PersistenceUnitTransactionTypeHelper.interpretTransactionType(
|
|
||||||
configurationValues.get( JPA_TRANSACTION_TYPE )
|
|
||||||
);
|
|
||||||
if ( txnType == null ) {
|
|
||||||
txnType = persistenceUnit.getTransactionType();
|
|
||||||
}
|
|
||||||
if ( txnType == null ) {
|
|
||||||
// is it more appropriate to have this be based on bootstrap entry point (EE vs SE)?
|
|
||||||
txnType = PersistenceUnitTransactionType.RESOURCE_LOCAL;
|
|
||||||
}
|
|
||||||
boolean hasTxStrategy = configurationValues.containsKey( TRANSACTION_COORDINATOR_STRATEGY );
|
|
||||||
if ( hasTxStrategy ) {
|
|
||||||
LOG.overridingTransactionStrategyDangerous( TRANSACTION_COORDINATOR_STRATEGY );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ( txnType == PersistenceUnitTransactionType.JTA ) {
|
|
||||||
ssrBuilder.applySetting( TRANSACTION_COORDINATOR_STRATEGY, JtaTransactionCoordinatorBuilderImpl.class );
|
|
||||||
}
|
|
||||||
else if ( txnType == PersistenceUnitTransactionType.RESOURCE_LOCAL ) {
|
|
||||||
ssrBuilder.applySetting( TRANSACTION_COORDINATOR_STRATEGY, JdbcResourceLocalTransactionCoordinatorBuilderImpl.class );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void configure(StandardServiceRegistry ssr, MergedSettings mergedSettings) {
|
|
||||||
final StrategySelector strategySelector = ssr.getService( StrategySelector.class );
|
final StrategySelector strategySelector = ssr.getService( StrategySelector.class );
|
||||||
|
|
||||||
// apply id generators
|
// apply id generators
|
||||||
|
@ -747,10 +1061,9 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected List<AttributeConverterDefinition> populate(
|
private List<AttributeConverterDefinition> applyMappingResources(MetadataSources metadataSources) {
|
||||||
MetadataSources metadataSources,
|
// todo : where in the heck are `org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor.getManagedClassNames` handled?!?
|
||||||
MergedSettings mergedSettings,
|
|
||||||
StandardServiceRegistry ssr) {
|
|
||||||
// final ClassLoaderService classLoaderService = ssr.getService( ClassLoaderService.class );
|
// final ClassLoaderService classLoaderService = ssr.getService( ClassLoaderService.class );
|
||||||
//
|
//
|
||||||
// // todo : make sure MetadataSources/Metadata are capable of handling duplicate sources
|
// // todo : make sure MetadataSources/Metadata are capable of handling duplicate sources
|
||||||
|
@ -827,12 +1140,10 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
||||||
return attributeConverterDefinitions;
|
return attributeConverterDefinitions;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void populate(
|
private void applyMetamodelBuilderSettings(
|
||||||
MetadataBuilder metamodelBuilder,
|
|
||||||
MergedSettings mergedSettings,
|
MergedSettings mergedSettings,
|
||||||
StandardServiceRegistry ssr,
|
|
||||||
List<AttributeConverterDefinition> attributeConverterDefinitions) {
|
List<AttributeConverterDefinition> attributeConverterDefinitions) {
|
||||||
( (MetadataBuilderImplementor) metamodelBuilder ).getBootstrapContext().markAsJpaBootstrap();
|
metamodelBuilder.getBootstrapContext().markAsJpaBootstrap();
|
||||||
|
|
||||||
if ( persistenceUnit.getTempClassLoader() != null ) {
|
if ( persistenceUnit.getTempClassLoader() != null ) {
|
||||||
metamodelBuilder.applyTempClassLoader( persistenceUnit.getTempClassLoader() );
|
metamodelBuilder.applyTempClassLoader( persistenceUnit.getTempClassLoader() );
|
||||||
|
@ -916,7 +1227,7 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
||||||
// Metamodel will clean this up...
|
// Metamodel will clean this up...
|
||||||
try {
|
try {
|
||||||
SessionFactoryBuilder sfBuilder = metadata().getSessionFactoryBuilder();
|
SessionFactoryBuilder sfBuilder = metadata().getSessionFactoryBuilder();
|
||||||
populate( sfBuilder, standardServiceRegistry );
|
populateSfBuilder( sfBuilder, standardServiceRegistry );
|
||||||
|
|
||||||
SchemaManagementToolCoordinator.process(
|
SchemaManagementToolCoordinator.process(
|
||||||
metadata, standardServiceRegistry, configurationValues, DelayedDropRegistryNotAvailableImpl.INSTANCE
|
metadata, standardServiceRegistry, configurationValues, DelayedDropRegistryNotAvailableImpl.INSTANCE
|
||||||
|
@ -930,10 +1241,10 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
||||||
cancel();
|
cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@Override
|
||||||
public EntityManagerFactory build() {
|
public EntityManagerFactory build() {
|
||||||
SessionFactoryBuilder sfBuilder = metadata().getSessionFactoryBuilder();
|
final SessionFactoryBuilder sfBuilder = metadata().getSessionFactoryBuilder();
|
||||||
populate( sfBuilder, standardServiceRegistry );
|
populateSfBuilder( sfBuilder, standardServiceRegistry );
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return sfBuilder.build();
|
return sfBuilder.build();
|
||||||
|
@ -943,7 +1254,7 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void populate(SessionFactoryBuilder sfBuilder, StandardServiceRegistry ssr) {
|
protected void populateSfBuilder(SessionFactoryBuilder sfBuilder, StandardServiceRegistry ssr) {
|
||||||
|
|
||||||
final StrategySelector strategySelector = ssr.getService( StrategySelector.class );
|
final StrategySelector strategySelector = ssr.getService( StrategySelector.class );
|
||||||
|
|
||||||
|
@ -1028,7 +1339,36 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
||||||
private Map<String, JaccPermissionDeclarations> jaccPermissionsByContextId;
|
private Map<String, JaccPermissionDeclarations> jaccPermissionsByContextId;
|
||||||
private List<CacheRegionDefinition> cacheRegionDefinitions;
|
private List<CacheRegionDefinition> cacheRegionDefinitions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MergedSettings is initialized with hibernate.properties
|
||||||
|
*/
|
||||||
private MergedSettings() {
|
private MergedSettings() {
|
||||||
|
configurationValues.putAll( Environment.getProperties() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void processPersistenceUnitDescriptorProperties(PersistenceUnitDescriptor persistenceUnit) {
|
||||||
|
if ( persistenceUnit.getProperties() != null ) {
|
||||||
|
configurationValues.putAll( persistenceUnit.getProperties() );
|
||||||
|
}
|
||||||
|
|
||||||
|
configurationValues.put( PERSISTENCE_UNIT_NAME, persistenceUnit.getName() );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void processHibernateConfigXmlResources(LoadedConfig loadedConfig){
|
||||||
|
if ( ! configurationValues.containsKey( SESSION_FACTORY_NAME ) ) {
|
||||||
|
// there is not already a SF-name in the merged settings
|
||||||
|
final String sfName = loadedConfig.getSessionFactoryName();
|
||||||
|
if ( sfName != null ) {
|
||||||
|
// but the cfg.xml file we are processing named one..
|
||||||
|
configurationValues.put( SESSION_FACTORY_NAME, sfName );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// make sure they match?
|
||||||
|
}
|
||||||
|
|
||||||
|
configurationValues.putAll( loadedConfig.getConfigurationValues() );
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map getConfigurationValues() {
|
public Map getConfigurationValues() {
|
||||||
|
|
|
@ -34,10 +34,8 @@ public class MaskSensitiveInformationTest extends BaseEntityManagerFunctionalTes
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
protected void addConfigOptions(Map options) {
|
protected void addConfigOptions(Map options) {
|
||||||
options.put( AvailableSettings.JPA_JDBC_USER, options.get( AvailableSettings.USER ) );
|
super.addConfigOptions( options );
|
||||||
options.put( AvailableSettings.JPA_JDBC_PASSWORD, options.get( AvailableSettings.PASS ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -9,53 +9,106 @@
|
||||||
|
|
||||||
package org.hibernate.jpa.test.connection;
|
package org.hibernate.jpa.test.connection;
|
||||||
|
|
||||||
import java.io.File;
|
import java.net.URL;
|
||||||
import javax.persistence.EntityManagerFactory;
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import javax.persistence.PersistenceException;
|
import javax.persistence.PersistenceException;
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.dialect.H2Dialect;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.engine.spi.SessionImplementor;
|
||||||
import org.hibernate.jpa.HibernatePersistenceProvider;
|
import org.hibernate.jpa.HibernatePersistenceProvider;
|
||||||
|
import org.hibernate.jpa.test.Distributor;
|
||||||
|
import org.hibernate.jpa.test.Item;
|
||||||
|
import org.hibernate.jpa.test.xml.Light;
|
||||||
|
import org.hibernate.jpa.test.xml.Lighter;
|
||||||
|
|
||||||
|
import org.hibernate.testing.util.jpa.PersistenceUnitInfoAdapter;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Emmanuel Bernard
|
* @author Emmanuel Bernard
|
||||||
*/
|
*/
|
||||||
public class DataSourceInjectionTest {
|
public class DataSourceInjectionTest {
|
||||||
EntityManagerFactory emf;
|
|
||||||
@Test
|
@Test
|
||||||
public void testDatasourceInjection() throws Exception {
|
public void testDatasourceInjection() throws Exception {
|
||||||
File current = new File(".");
|
withPuRoot(
|
||||||
File sub = new File(current, "puroot");
|
puRootUrl -> {
|
||||||
sub.mkdir();
|
final PersistenceUnitInfoAdapter persistenceUnitInfo = createPuDescriptor( puRootUrl, new FakeDataSource() );
|
||||||
PersistenceUnitInfoImpl info = new PersistenceUnitInfoImpl( sub.toURI().toURL(), new String[]{} );
|
|
||||||
|
// otherwise the FakeDataSourceException will be eaten trying to resolve the Dialect
|
||||||
|
final Map<String, Object> intgOverrides = Collections.singletonMap(
|
||||||
|
AvailableSettings.DIALECT,
|
||||||
|
H2Dialect.class
|
||||||
|
);
|
||||||
|
|
||||||
|
final HibernatePersistenceProvider provider = new HibernatePersistenceProvider();
|
||||||
|
try ( final SessionFactoryImplementor sf = provider.createContainerEntityManagerFactory(
|
||||||
|
persistenceUnitInfo,
|
||||||
|
intgOverrides
|
||||||
|
).unwrap( SessionFactoryImplementor.class ) ) {
|
||||||
|
|
||||||
|
try ( final SessionImplementor session = sf.openSession().unwrap( SessionImplementor.class ) ) {
|
||||||
|
session.createQuery( "select i from Item i" ).list();
|
||||||
|
Assert.fail( "Expecting FakeDataSourceException" );
|
||||||
|
}
|
||||||
|
catch (PersistenceException pe) {
|
||||||
|
try {
|
||||||
|
throw (RuntimeException) pe.getCause();
|
||||||
|
}
|
||||||
|
catch (FakeDataSourceException fde) {
|
||||||
|
//success
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (FakeDataSourceException fde) {
|
||||||
|
//success
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected PersistenceUnitInfoAdapter createPuDescriptor(URL puRootUrl, DataSource dataSource) {
|
||||||
|
return new PersistenceUnitInfoAdapter() {
|
||||||
|
@Override
|
||||||
|
public DataSource getNonJtaDataSource() {
|
||||||
|
return dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public URL getPersistenceUnitRootUrl() {
|
||||||
|
return puRootUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getManagedClassNames() {
|
||||||
|
List<String> classes = new ArrayList<>();
|
||||||
|
classes.add( Item.class.getName() );
|
||||||
|
classes.add( Distributor.class.getName() );
|
||||||
|
classes.add( Light.class.getName() );
|
||||||
|
classes.add( Lighter.class.getName() );
|
||||||
|
return classes;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void withPuRoot(Consumer<URL> puRootUrlConsumer) throws Exception {
|
||||||
|
// create a temporary directory to serve as the "PU root URL"
|
||||||
|
final Path puroot = Files.createTempDirectory( "puroot" );
|
||||||
|
final URL puRootUrl = puroot.toUri().toURL();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
emf = new HibernatePersistenceProvider().createContainerEntityManagerFactory( info, null );
|
puRootUrlConsumer.accept( puRootUrl );
|
||||||
try {
|
|
||||||
emf.createEntityManager().createQuery( "select i from Item i" ).getResultList();
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
try {
|
|
||||||
emf.close();
|
|
||||||
}
|
|
||||||
catch (Exception ignore) {
|
|
||||||
int i = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Assert.fail( "FakeDatasource should have been used" );
|
|
||||||
}
|
|
||||||
catch (PersistenceException pe) {
|
|
||||||
if(emf != null){
|
|
||||||
emf.close();
|
|
||||||
}
|
|
||||||
Assert.assertTrue( pe.getCause() instanceof FakeDataSourceException );
|
|
||||||
}
|
|
||||||
catch (FakeDataSourceException fde) {
|
|
||||||
//success
|
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
sub.delete();
|
Files.deleteIfExists( puroot );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ public class PersistenceUnitInfoImpl implements PersistenceUnitInfo {
|
||||||
private URL puRoot;
|
private URL puRoot;
|
||||||
|
|
||||||
public PersistenceUnitInfoImpl(URL puRoot, String[] mappingFiles) {
|
public PersistenceUnitInfoImpl(URL puRoot, String[] mappingFiles) {
|
||||||
this.mappingFiles = new ArrayList<String>( mappingFiles.length );
|
this.mappingFiles = new ArrayList<>( mappingFiles.length );
|
||||||
this.mappingFiles.addAll( Arrays.asList( mappingFiles ) );
|
this.mappingFiles.addAll( Arrays.asList( mappingFiles ) );
|
||||||
this.puRoot = puRoot;
|
this.puRoot = puRoot;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.orm.test.bootstrap;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.tool.schema.Action;
|
||||||
|
import org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class SchemaToolingAutoActionTests {
|
||||||
|
@Test
|
||||||
|
public void testLegacySettingAsAction() {
|
||||||
|
final Properties props = new Properties();
|
||||||
|
props.put( AvailableSettings.HBM2DDL_AUTO, Action.CREATE_DROP );
|
||||||
|
|
||||||
|
final SchemaManagementToolCoordinator.ActionGrouping actionGrouping = SchemaManagementToolCoordinator.ActionGrouping.interpret( props );
|
||||||
|
|
||||||
|
assertThat( actionGrouping.getDatabaseAction(), is( Action.CREATE_DROP ) );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,105 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.orm.test.bootstrap.jpa;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.persistence.EntityManagerFactory;
|
||||||
|
import javax.persistence.spi.PersistenceProvider;
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl;
|
||||||
|
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.jpa.HibernatePersistenceProvider;
|
||||||
|
import org.hibernate.testing.jdbc.DataSourceStub;
|
||||||
|
|
||||||
|
import org.hibernate.testing.FailureExpected;
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||||
|
import org.hibernate.testing.util.jpa.PersistenceUnitInfoAdapter;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||||
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class PersistenceUnitInfoTests extends BaseUnitTestCase {
|
||||||
|
@Test
|
||||||
|
@TestForIssue( jiraKey = "HHH-13432" )
|
||||||
|
public void testNonJtaDataExposedAsProperty() {
|
||||||
|
final DataSource puDataSource = new DataSourceStub( "puDataSource" );
|
||||||
|
final PersistenceUnitInfoAdapter info = new PersistenceUnitInfoAdapter() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataSource getNonJtaDataSource() {
|
||||||
|
return puDataSource;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
final PersistenceProvider provider = new HibernatePersistenceProvider();
|
||||||
|
|
||||||
|
final EntityManagerFactory emf = provider.createContainerEntityManagerFactory(
|
||||||
|
info,
|
||||||
|
Collections.emptyMap()
|
||||||
|
);
|
||||||
|
|
||||||
|
// first let's check the DataSource used in the EMF...
|
||||||
|
final ConnectionProvider connectionProvider = emf.unwrap( SessionFactoryImplementor.class )
|
||||||
|
.getServiceRegistry()
|
||||||
|
.getService( ConnectionProvider.class );
|
||||||
|
assertThat( connectionProvider, instanceOf( DatasourceConnectionProviderImpl.class ) );
|
||||||
|
final DatasourceConnectionProviderImpl dsCp = (DatasourceConnectionProviderImpl) connectionProvider;
|
||||||
|
assertThat( dsCp.getDataSource(), is( puDataSource ) );
|
||||||
|
|
||||||
|
// now let's check that it is exposed via the EMF properties
|
||||||
|
// - note : the spec does not indicate that this should work, but
|
||||||
|
// it worked this way in previous versions
|
||||||
|
final Object o = emf.getProperties().get( AvailableSettings.JPA_NON_JTA_DATASOURCE );
|
||||||
|
assertThat( o, is( puDataSource ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue( jiraKey = "HHH-13432" )
|
||||||
|
public void testJtaDataExposedAsProperty() {
|
||||||
|
final DataSource puDataSource = new DataSourceStub( "puDataSource" );
|
||||||
|
final PersistenceUnitInfoAdapter info = new PersistenceUnitInfoAdapter() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataSource getJtaDataSource() {
|
||||||
|
return puDataSource;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
final PersistenceProvider provider = new HibernatePersistenceProvider();
|
||||||
|
|
||||||
|
final EntityManagerFactory emf = provider.createContainerEntityManagerFactory(
|
||||||
|
info,
|
||||||
|
Collections.emptyMap()
|
||||||
|
);
|
||||||
|
|
||||||
|
// first let's check the DataSource used in the EMF...
|
||||||
|
final ConnectionProvider connectionProvider = emf.unwrap( SessionFactoryImplementor.class )
|
||||||
|
.getServiceRegistry()
|
||||||
|
.getService( ConnectionProvider.class );
|
||||||
|
assertThat( connectionProvider, instanceOf( DatasourceConnectionProviderImpl.class ) );
|
||||||
|
final DatasourceConnectionProviderImpl dsCp = (DatasourceConnectionProviderImpl) connectionProvider;
|
||||||
|
assertThat( dsCp.getDataSource(), is( puDataSource ) );
|
||||||
|
|
||||||
|
// now let's check that it is exposed via the EMF properties
|
||||||
|
// - again, the spec does not indicate that this should work, but
|
||||||
|
// it worked this way in previous versions
|
||||||
|
final Map<String, Object> properties = emf.getProperties();
|
||||||
|
final Object o = properties.get( AvailableSettings.JPA_JTA_DATASOURCE );
|
||||||
|
assertEquals( puDataSource, o );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,370 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.orm.test.bootstrap.jpa;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
import javax.persistence.EntityManagerFactory;
|
||||||
|
import javax.persistence.spi.PersistenceProvider;
|
||||||
|
import javax.persistence.spi.PersistenceUnitInfo;
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl;
|
||||||
|
import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl;
|
||||||
|
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.jpa.HibernatePersistenceProvider;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
import org.hibernate.testing.jdbc.DataSourceStub;
|
||||||
|
|
||||||
|
import org.hibernate.testing.FailureExpected;
|
||||||
|
import org.hibernate.testing.env.ConnectionProviderBuilder;
|
||||||
|
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||||
|
import org.hibernate.testing.util.jpa.DelegatingPersistenceUnitInfo;
|
||||||
|
import org.hibernate.testing.util.jpa.PersistenceUnitInfoAdapter;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
|
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||||
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
|
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||||
|
import static org.hamcrest.CoreMatchers.nullValue;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class PersistenceUnitOverridesTests extends BaseUnitTestCase {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPassingIntegrationJpaJdbcOverrides() {
|
||||||
|
|
||||||
|
// the integration overrides say to use the "db2" JPA connection settings (which should override the persistence unit values)
|
||||||
|
final Map integrationOverrides = ConnectionProviderBuilder.getJpaConnectionProviderProperties( "db2" );
|
||||||
|
|
||||||
|
final EntityManagerFactory emf = new HibernatePersistenceProvider().createContainerEntityManagerFactory(
|
||||||
|
new PersistenceUnitInfoAdapter() {
|
||||||
|
@Override
|
||||||
|
public Properties getProperties() {
|
||||||
|
// effectively, the `persistence.xml` defines `db1` as the connection settings
|
||||||
|
return ConnectionProviderBuilder.getJpaConnectionProviderProperties( "db1" );
|
||||||
|
}
|
||||||
|
},
|
||||||
|
integrationOverrides
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
final Map<String, Object> properties = emf.getProperties();
|
||||||
|
|
||||||
|
final Object hibernateJdbcDriver = properties.get( AvailableSettings.URL );
|
||||||
|
assertThat( hibernateJdbcDriver, notNullValue() );
|
||||||
|
|
||||||
|
final Object jpaJdbcDriver = properties.get( AvailableSettings.JPA_JDBC_URL );
|
||||||
|
assertThat( (String) jpaJdbcDriver, containsString( "db2" ) );
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
emf.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPassingIntegrationJtaDataSourceOverrideForJpaJdbcSettings() {
|
||||||
|
final PersistenceUnitInfoAdapter puInfo = new PersistenceUnitInfoAdapter(
|
||||||
|
ConnectionProviderBuilder.getJpaConnectionProviderProperties( "db2" )
|
||||||
|
);
|
||||||
|
|
||||||
|
final DataSource integrationDataSource = new DataSourceStub( "integrationDataSource" );
|
||||||
|
|
||||||
|
final HibernatePersistenceProvider provider = new HibernatePersistenceProvider();
|
||||||
|
|
||||||
|
final EntityManagerFactory emf = provider.createContainerEntityManagerFactory(
|
||||||
|
puInfo,
|
||||||
|
Collections.singletonMap( AvailableSettings.JPA_JTA_DATASOURCE, integrationDataSource )
|
||||||
|
);
|
||||||
|
|
||||||
|
// first let's check the DataSource used in the EMF...
|
||||||
|
final ConnectionProvider connectionProvider = emf.unwrap( SessionFactoryImplementor.class )
|
||||||
|
.getServiceRegistry()
|
||||||
|
.getService( ConnectionProvider.class );
|
||||||
|
assertThat( connectionProvider, instanceOf( DatasourceConnectionProviderImpl.class ) );
|
||||||
|
final DatasourceConnectionProviderImpl dsCp = (DatasourceConnectionProviderImpl) connectionProvider;
|
||||||
|
assertThat( dsCp.getDataSource(), is( integrationDataSource ) );
|
||||||
|
|
||||||
|
// now let's check that it is exposed via the EMF properties
|
||||||
|
// - note : the spec does not indicate that this should work, but
|
||||||
|
// it worked this way in previous versions
|
||||||
|
final Object jtaDs = emf.getProperties().get( AvailableSettings.JPA_JTA_DATASOURCE );
|
||||||
|
assertThat( jtaDs, is( integrationDataSource ) );
|
||||||
|
|
||||||
|
// Additionally, we should have set Hibernate's DATASOURCE setting
|
||||||
|
final Object hibDs = emf.getProperties().get( AvailableSettings.JPA_JTA_DATASOURCE );
|
||||||
|
assertThat( hibDs, is( integrationDataSource ) );
|
||||||
|
|
||||||
|
// Make sure the non-jta-data-source setting was cleared or otherwise null
|
||||||
|
final Object nonJtaDs = emf.getProperties().get( AvailableSettings.JPA_NON_JTA_DATASOURCE );
|
||||||
|
assertThat( nonJtaDs, nullValue() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPassingIntegrationJpaJdbcOverrideForJtaDataSourceProperty() {
|
||||||
|
PersistenceProvider provider = new HibernatePersistenceProvider() {
|
||||||
|
@Override
|
||||||
|
public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map integrationOverrides) {
|
||||||
|
return super.createContainerEntityManagerFactory(
|
||||||
|
new DelegatingPersistenceUnitInfo( info ) {
|
||||||
|
|
||||||
|
// inject a JPA JTA DataSource setting into the PU
|
||||||
|
final DataSource puDataSource;
|
||||||
|
final Properties puProperties;
|
||||||
|
|
||||||
|
{
|
||||||
|
puDataSource = new DataSourceStub( "puDataSource" );
|
||||||
|
|
||||||
|
puProperties = new Properties();
|
||||||
|
puProperties.putAll( info.getProperties() );
|
||||||
|
puProperties.put( AvailableSettings.JPA_JTA_DATASOURCE, puDataSource );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataSource getJtaDataSource() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataSource getNonJtaDataSource() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Properties getProperties() {
|
||||||
|
return puProperties;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
integrationOverrides
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
final EntityManagerFactory emf = provider.createContainerEntityManagerFactory(
|
||||||
|
new PersistenceUnitInfoAdapter(),
|
||||||
|
// however, provide JPA connection settings as "integration settings", which according to JPA spec should override the persistence unit values.
|
||||||
|
// - note that it is unclear in the spec whether JDBC value in the integration settings should override
|
||||||
|
// a JTA DataSource (nor the reverse). However, that is a useful thing to support
|
||||||
|
ConnectionProviderBuilder.getJpaConnectionProviderProperties( "db2" )
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
final Map<String, Object> properties = emf.getProperties();
|
||||||
|
|
||||||
|
final Object hibernateJdbcDriver = properties.get( AvailableSettings.URL );
|
||||||
|
assertThat( hibernateJdbcDriver, notNullValue() );
|
||||||
|
|
||||||
|
final Object jpaJdbcDriver = properties.get( AvailableSettings.JPA_JDBC_URL );
|
||||||
|
assertThat( (String) jpaJdbcDriver, containsString( "db2" ) );
|
||||||
|
|
||||||
|
// see if the values had the affect to adjust the `ConnectionProvider` used
|
||||||
|
final ConnectionProvider connectionProvider = emf.unwrap( SessionFactoryImplementor.class )
|
||||||
|
.getServiceRegistry()
|
||||||
|
.getService( ConnectionProvider.class );
|
||||||
|
assertThat( connectionProvider, instanceOf( DriverManagerConnectionProviderImpl.class ) );
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
emf.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
// @FailureExpected(
|
||||||
|
// jiraKey = "HHH-12858",
|
||||||
|
// message = "Even though the JDBC settings override a DataSource *property*, it" +
|
||||||
|
// " does not override a DataSource defined using the dedicated persistence.xml element"
|
||||||
|
// )
|
||||||
|
public void testPassingIntegrationJpaJdbcOverridesForJtaDataSourceElement() {
|
||||||
|
PersistenceProvider provider = new HibernatePersistenceProvider() {
|
||||||
|
@Override
|
||||||
|
public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map integrationOverrides) {
|
||||||
|
return super.createContainerEntityManagerFactory(
|
||||||
|
new DelegatingPersistenceUnitInfo( info ) {
|
||||||
|
// inject a JPA JTA DataSource setting into the PU
|
||||||
|
final DataSource puDataSource = new DataSourceStub( "puDataSource" );
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataSource getJtaDataSource() {
|
||||||
|
return puDataSource;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
integrationOverrides
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
final EntityManagerFactory emf = provider.createContainerEntityManagerFactory(
|
||||||
|
new PersistenceUnitInfoAdapter(),
|
||||||
|
// however, provide JPA connection settings as "integration settings", which according to JPA spec should override the persistence unit values.
|
||||||
|
// - note that it is unclear in the spec whether JDBC value in the integration settings should override
|
||||||
|
// a JTA DataSource (nor the reverse). However, that is a useful thing to support
|
||||||
|
ConnectionProviderBuilder.getJpaConnectionProviderProperties( "db2" )
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
final Map<String, Object> properties = emf.getProperties();
|
||||||
|
|
||||||
|
final Object hibernateJdbcDriver = properties.get( AvailableSettings.URL );
|
||||||
|
assertThat( hibernateJdbcDriver, notNullValue() );
|
||||||
|
|
||||||
|
final Object jpaJdbcDriver = properties.get( AvailableSettings.JPA_JDBC_URL );
|
||||||
|
assertThat( (String) jpaJdbcDriver, containsString( "db2" ) );
|
||||||
|
|
||||||
|
// see if the values had the affect to adjust the `ConnectionProvider` used
|
||||||
|
final ConnectionProvider connectionProvider = emf.unwrap( SessionFactoryImplementor.class )
|
||||||
|
.getServiceRegistry()
|
||||||
|
.getService( ConnectionProvider.class );
|
||||||
|
assertThat( connectionProvider, instanceOf( DriverManagerConnectionProviderImpl.class ) );
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
emf.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
// @FailureExpected(
|
||||||
|
// jiraKey = "HHH-12858",
|
||||||
|
// message = "So it appears any use of the persistence.xml `jta-data-source` or `non-jta-data-source` " +
|
||||||
|
// "have precedence over integration settings, which is also incorrect"
|
||||||
|
// )
|
||||||
|
public void testPassingIntegrationJpaDataSourceOverrideForJtaDataSourceElement() {
|
||||||
|
final DataSource puDataSource = new DataSourceStub( "puDataSource" );
|
||||||
|
final DataSource integrationDataSource = new DataSourceStub( "integrationDataSource" );
|
||||||
|
|
||||||
|
PersistenceProvider provider = new HibernatePersistenceProvider() {
|
||||||
|
@Override
|
||||||
|
public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map integrationOverrides) {
|
||||||
|
return super.createContainerEntityManagerFactory(
|
||||||
|
new DelegatingPersistenceUnitInfo( info ) {
|
||||||
|
@Override
|
||||||
|
public DataSource getJtaDataSource() {
|
||||||
|
// pretend the DataSource was defined using the `jta-data-source` element in persistence.xml
|
||||||
|
// - as opposed using `javax.persistence.jtaDataSource` under the `properties` element
|
||||||
|
return puDataSource;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
integrationOverrides
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
final Map integrationOverrides = new HashMap();
|
||||||
|
//noinspection unchecked
|
||||||
|
integrationOverrides.put( AvailableSettings.JPA_JTA_DATASOURCE, integrationDataSource );
|
||||||
|
|
||||||
|
final EntityManagerFactory emf = provider.createContainerEntityManagerFactory(
|
||||||
|
new PersistenceUnitInfoAdapter(),
|
||||||
|
integrationOverrides
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
final Map<String, Object> properties = emf.getProperties();
|
||||||
|
|
||||||
|
final Object datasource = properties.get( AvailableSettings.JPA_JTA_DATASOURCE );
|
||||||
|
assertThat( datasource, is( integrationDataSource ) );
|
||||||
|
|
||||||
|
// see if the values had the affect to adjust the `ConnectionProvider` used
|
||||||
|
final ConnectionProvider connectionProvider = emf.unwrap( SessionFactoryImplementor.class )
|
||||||
|
.getServiceRegistry()
|
||||||
|
.getService( ConnectionProvider.class );
|
||||||
|
assertThat( connectionProvider, instanceOf( DatasourceConnectionProviderImpl.class ) );
|
||||||
|
|
||||||
|
final DatasourceConnectionProviderImpl datasourceConnectionProvider = (DatasourceConnectionProviderImpl) connectionProvider;
|
||||||
|
assertThat( datasourceConnectionProvider.getDataSource(), is( integrationDataSource ) );
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
emf.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue( jiraKey = "HHH-13640" )
|
||||||
|
public void testIntegrationOverridesOfPersistenceXmlDataSource() {
|
||||||
|
|
||||||
|
// mimics a DataSource defined in the persistence.xml
|
||||||
|
final DataSourceStub dataSource = new DataSourceStub( "puDataSource" );
|
||||||
|
final PersistenceUnitInfoAdapter info = new PersistenceUnitInfoAdapter() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataSource getNonJtaDataSource() {
|
||||||
|
return dataSource;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Now create "integration Map" that overrides the DataSource to use
|
||||||
|
final DataSource override = new DataSourceStub( "integrationDataSource" );
|
||||||
|
final Map<String,Object> integrationSettings = new HashMap<>();
|
||||||
|
integrationSettings.put( AvailableSettings.JPA_NON_JTA_DATASOURCE, override );
|
||||||
|
|
||||||
|
final PersistenceProvider provider = new HibernatePersistenceProvider();
|
||||||
|
|
||||||
|
final EntityManagerFactory emf = provider.createContainerEntityManagerFactory(
|
||||||
|
info,
|
||||||
|
integrationSettings
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
final Map<String, Object> properties = emf.getProperties();
|
||||||
|
|
||||||
|
assertThat( properties.get( AvailableSettings.JPA_NON_JTA_DATASOURCE ), notNullValue() );
|
||||||
|
assertThat( properties.get( AvailableSettings.JPA_NON_JTA_DATASOURCE ), is( override ) );
|
||||||
|
|
||||||
|
final SessionFactoryImplementor sessionFactory = emf.unwrap( SessionFactoryImplementor.class );
|
||||||
|
final ConnectionProvider connectionProvider = sessionFactory.getServiceRegistry().getService( ConnectionProvider.class );
|
||||||
|
assertThat( connectionProvider, instanceOf( DatasourceConnectionProviderImpl.class ) );
|
||||||
|
|
||||||
|
final DatasourceConnectionProviderImpl dsProvider = (DatasourceConnectionProviderImpl) connectionProvider;
|
||||||
|
assertThat( dsProvider.getDataSource(), is( override ) );
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
emf.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue( jiraKey = "HHH-13640" )
|
||||||
|
public void testIntegrationOverridesOfPersistenceXmlDataSourceWithDriverManagerInfo() {
|
||||||
|
|
||||||
|
// mimics a DataSource defined in the persistence.xml
|
||||||
|
final DataSourceStub dataSource = new DataSourceStub( "puDataSource" );
|
||||||
|
final PersistenceUnitInfoAdapter info = new PersistenceUnitInfoAdapter() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataSource getNonJtaDataSource() {
|
||||||
|
return dataSource;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
final Map<String,Object> integrationSettings = new HashMap<>();
|
||||||
|
integrationSettings.put( AvailableSettings.JPA_JDBC_DRIVER, ConnectionProviderBuilder.DRIVER );
|
||||||
|
integrationSettings.put( AvailableSettings.JPA_JDBC_URL, ConnectionProviderBuilder.URL );
|
||||||
|
integrationSettings.put( AvailableSettings.JPA_JDBC_USER, ConnectionProviderBuilder.USER );
|
||||||
|
integrationSettings.put( AvailableSettings.JPA_JDBC_PASSWORD, ConnectionProviderBuilder.PASS );
|
||||||
|
|
||||||
|
final PersistenceProvider provider = new HibernatePersistenceProvider();
|
||||||
|
|
||||||
|
final EntityManagerFactory emf = provider.createContainerEntityManagerFactory(
|
||||||
|
info,
|
||||||
|
integrationSettings
|
||||||
|
);
|
||||||
|
|
||||||
|
final SessionFactoryImplementor sessionFactory = emf.unwrap( SessionFactoryImplementor.class );
|
||||||
|
final ConnectionProvider connectionProvider = sessionFactory.getServiceRegistry().getService( ConnectionProvider.class );
|
||||||
|
assertThat( connectionProvider, instanceOf( DriverManagerConnectionProviderImpl.class ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for Hibernate bootstrapping Hibernate
|
||||||
|
*/
|
||||||
|
package org.hibernate.orm.test.bootstrap;
|
|
@ -6,25 +6,15 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.testing.env;
|
package org.hibernate.testing.env;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.SQLFeatureNotSupportedException;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import javassist.scopedpool.SoftValueHashMap;
|
|
||||||
|
|
||||||
import org.hibernate.annotations.common.reflection.ReflectionUtil;
|
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl;
|
import org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl;
|
||||||
|
@ -38,27 +28,42 @@ import org.hibernate.testing.DialectCheck;
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||||
public class ConnectionProviderBuilder implements DialectCheck {
|
public class ConnectionProviderBuilder implements DialectCheck {
|
||||||
public static final String DRIVER = "org.h2.Driver";
|
public static final String DRIVER = "org.h2.Driver";
|
||||||
public static final String DATA_SOURCE = "org.h2.jdbcx.JdbcDataSource";
|
public static final String DATA_SOURCE = "org.h2.jdbcx.JdbcDataSource";
|
||||||
// public static final String URL = "jdbc:h2:mem:%s;DB_CLOSE_DELAY=-1;MVCC=TRUE";
|
// public static final String URL = "jdbc:h2:mem:%s;DB_CLOSE_DELAY=-1;MVCC=TRUE";
|
||||||
public static final String URL = "jdbc:h2:mem:%s;DB_CLOSE_DELAY=-1";
|
public static final String URL_FORMAT = "jdbc:h2:mem:%s;DB_CLOSE_DELAY=-1";
|
||||||
|
public static final String URL = URL_FORMAT;
|
||||||
public static final String USER = "sa";
|
public static final String USER = "sa";
|
||||||
public static final String PASS = "";
|
public static final String PASS = "";
|
||||||
|
|
||||||
public static Properties getConnectionProviderProperties(String dbName) {
|
public static Properties getConnectionProviderProperties(String dbName) {
|
||||||
Properties props = new Properties( null );
|
Properties props = new Properties( null );
|
||||||
props.put( Environment.DRIVER, DRIVER );
|
props.put( Environment.DRIVER, DRIVER );
|
||||||
props.put( Environment.URL, String.format( URL, dbName ) );
|
props.put( Environment.URL, String.format( URL_FORMAT, dbName ) );
|
||||||
props.put( Environment.USER, USER );
|
props.put( Environment.USER, USER );
|
||||||
props.put( Environment.PASS, PASS );
|
props.put( Environment.PASS, PASS );
|
||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Properties getJpaConnectionProviderProperties(String dbName) {
|
||||||
|
Properties props = new Properties( null );
|
||||||
|
props.put( Environment.JPA_JDBC_DRIVER, DRIVER );
|
||||||
|
props.put( Environment.JPA_JDBC_URL, String.format( URL_FORMAT, dbName ) );
|
||||||
|
props.put( Environment.JPA_JDBC_USER, USER );
|
||||||
|
props.put( Environment.JPA_JDBC_PASSWORD, PASS );
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
public static Properties getConnectionProviderProperties() {
|
public static Properties getConnectionProviderProperties() {
|
||||||
return getConnectionProviderProperties( "db1" );
|
return getConnectionProviderProperties( "db1" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Properties getJpaConnectionProviderProperties() {
|
||||||
|
return getJpaConnectionProviderProperties( "db1" );
|
||||||
|
}
|
||||||
|
|
||||||
public static DriverManagerConnectionProviderImpl buildConnectionProvider() {
|
public static DriverManagerConnectionProviderImpl buildConnectionProvider() {
|
||||||
return buildConnectionProvider( false );
|
return buildConnectionProvider( false );
|
||||||
}
|
}
|
||||||
|
@ -133,7 +138,7 @@ public class ConnectionProviderBuilder implements DialectCheck {
|
||||||
return connectionProxy;
|
return connectionProxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ConnectionInvocationHandler implements InvocationHandler {
|
private static class ConnectionInvocationHandler implements InvocationHandler {
|
||||||
|
|
||||||
private final Connection target;
|
private final Connection target;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.testing.jdbc;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl;
|
||||||
|
|
||||||
|
import org.hibernate.testing.env.ConnectionProviderBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class DataSourceStub implements DataSource {
|
||||||
|
private final String id;
|
||||||
|
private final DriverManagerConnectionProviderImpl connectionProvider;
|
||||||
|
private PrintWriter printWriter;
|
||||||
|
|
||||||
|
public DataSourceStub(String id) {
|
||||||
|
this.id = id;
|
||||||
|
connectionProvider = new DriverManagerConnectionProviderImpl();
|
||||||
|
connectionProvider.configure( ConnectionProviderBuilder.getConnectionProviderProperties() );
|
||||||
|
|
||||||
|
printWriter = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Connection getConnection() throws SQLException {
|
||||||
|
return connectionProvider.getConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Connection getConnection(String username, String password) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PrintWriter getLogWriter() {
|
||||||
|
return printWriter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLogWriter(PrintWriter out) {
|
||||||
|
this.printWriter = out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLoginTimeout(int seconds) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLoginTimeout() {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Logger getParentLogger() {
|
||||||
|
return Logger.getGlobal();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T unwrap(Class<T> iface) {
|
||||||
|
//noinspection unchecked
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWrapperFor(Class<?> iface) {
|
||||||
|
return iface.isAssignableFrom( getClass() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "DataSourceImpl(" + id + ")";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,110 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.testing.util.jpa;
|
||||||
|
|
||||||
|
import javax.persistence.SharedCacheMode;
|
||||||
|
import javax.persistence.ValidationMode;
|
||||||
|
import javax.persistence.spi.ClassTransformer;
|
||||||
|
import javax.persistence.spi.PersistenceUnitInfo;
|
||||||
|
import javax.persistence.spi.PersistenceUnitTransactionType;
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public class DelegatingPersistenceUnitInfo implements PersistenceUnitInfo {
|
||||||
|
private final PersistenceUnitInfo delegate;
|
||||||
|
|
||||||
|
public DelegatingPersistenceUnitInfo(PersistenceUnitInfo delegate) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPersistenceUnitName() {
|
||||||
|
return delegate.getPersistenceUnitName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPersistenceProviderClassName() {
|
||||||
|
return delegate.getPersistenceProviderClassName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PersistenceUnitTransactionType getTransactionType() {
|
||||||
|
return delegate.getTransactionType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataSource getJtaDataSource() {
|
||||||
|
return delegate.getJtaDataSource();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataSource getNonJtaDataSource() {
|
||||||
|
return delegate.getNonJtaDataSource();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getMappingFileNames() {
|
||||||
|
return delegate.getMappingFileNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<URL> getJarFileUrls() {
|
||||||
|
return delegate.getJarFileUrls();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public URL getPersistenceUnitRootUrl() {
|
||||||
|
return delegate.getPersistenceUnitRootUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getManagedClassNames() {
|
||||||
|
return delegate.getManagedClassNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean excludeUnlistedClasses() {
|
||||||
|
return delegate.excludeUnlistedClasses();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SharedCacheMode getSharedCacheMode() {
|
||||||
|
return delegate.getSharedCacheMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ValidationMode getValidationMode() {
|
||||||
|
return delegate.getValidationMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Properties getProperties() {
|
||||||
|
return delegate.getProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPersistenceXMLSchemaVersion() {
|
||||||
|
return delegate.getPersistenceXMLSchemaVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClassLoader getClassLoader() {
|
||||||
|
return delegate.getClassLoader();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addTransformer(ClassTransformer transformer) {
|
||||||
|
delegate.addTransformer( transformer );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClassLoader getNewTempClassLoader() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,117 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.testing.util.jpa;
|
||||||
|
|
||||||
|
import javax.persistence.SharedCacheMode;
|
||||||
|
import javax.persistence.ValidationMode;
|
||||||
|
import javax.persistence.spi.ClassTransformer;
|
||||||
|
import javax.persistence.spi.PersistenceUnitInfo;
|
||||||
|
import javax.persistence.spi.PersistenceUnitTransactionType;
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.hibernate.jpa.HibernatePersistenceProvider;
|
||||||
|
|
||||||
|
public class PersistenceUnitInfoAdapter implements PersistenceUnitInfo {
|
||||||
|
private final Properties properties;
|
||||||
|
|
||||||
|
public PersistenceUnitInfoAdapter() {
|
||||||
|
this( new Properties() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public PersistenceUnitInfoAdapter(Properties properties) {
|
||||||
|
this.properties = properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPersistenceUnitName() {
|
||||||
|
return "pu";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPersistenceProviderClassName() {
|
||||||
|
return HibernatePersistenceProvider.class.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PersistenceUnitTransactionType getTransactionType() {
|
||||||
|
return PersistenceUnitTransactionType.RESOURCE_LOCAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataSource getJtaDataSource() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataSource getNonJtaDataSource() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getMappingFileNames() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<URL> getJarFileUrls() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public URL getPersistenceUnitRootUrl() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getManagedClassNames() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean excludeUnlistedClasses() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SharedCacheMode getSharedCacheMode() {
|
||||||
|
return SharedCacheMode.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ValidationMode getValidationMode() {
|
||||||
|
return ValidationMode.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Properties getProperties() {
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPersistenceXMLSchemaVersion() {
|
||||||
|
return "2.1";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClassLoader getClassLoader() {
|
||||||
|
return PersistenceUnitInfoAdapter.class.getClassLoader();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addTransformer(ClassTransformer transformer) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClassLoader getNewTempClassLoader() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,130 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program 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 distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.testing.util.jpa;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
import javax.persistence.SharedCacheMode;
|
||||||
|
import javax.persistence.ValidationMode;
|
||||||
|
import javax.persistence.spi.ClassTransformer;
|
||||||
|
import javax.persistence.spi.PersistenceUnitInfo;
|
||||||
|
import javax.persistence.spi.PersistenceUnitTransactionType;
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.hibernate.jpa.HibernatePersistenceProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO : javadoc
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class PersistenceUnitInfoPropertiesWrapper implements PersistenceUnitInfo {
|
||||||
|
private Properties properties;
|
||||||
|
|
||||||
|
public PersistenceUnitInfoPropertiesWrapper() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public PersistenceUnitInfoPropertiesWrapper(Properties properties) {
|
||||||
|
this.properties = properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPersistenceUnitName() {
|
||||||
|
return "persistenceUnitAdapter";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPersistenceProviderClassName() {
|
||||||
|
return HibernatePersistenceProvider.class.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public PersistenceUnitTransactionType getTransactionType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataSource getJtaDataSource() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataSource getNonJtaDataSource() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getMappingFileNames() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<URL> getJarFileUrls() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public URL getPersistenceUnitRootUrl() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getManagedClassNames() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean excludeUnlistedClasses() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SharedCacheMode getSharedCacheMode() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValidationMode getValidationMode() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Properties getProperties() {
|
||||||
|
if ( properties == null ) {
|
||||||
|
properties = new Properties();
|
||||||
|
}
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPersistenceXMLSchemaVersion() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClassLoader getClassLoader() {
|
||||||
|
return Thread.currentThread().getContextClassLoader();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addTransformer(ClassTransformer transformer) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClassLoader getNewTempClassLoader() {
|
||||||
|
return Thread.currentThread().getContextClassLoader();
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,36 +6,11 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.orm.tooling.gradle;
|
package org.hibernate.orm.tooling.gradle;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLClassLoader;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.gradle.api.Action;
|
|
||||||
import org.gradle.api.GradleException;
|
|
||||||
import org.gradle.api.Plugin;
|
import org.gradle.api.Plugin;
|
||||||
import org.gradle.api.Project;
|
import org.gradle.api.Project;
|
||||||
import org.gradle.api.Task;
|
import org.gradle.api.Task;
|
||||||
import org.gradle.api.file.FileCollection;
|
|
||||||
import org.gradle.api.file.FileTree;
|
|
||||||
import org.gradle.api.logging.Logger;
|
|
||||||
import org.gradle.api.logging.Logging;
|
|
||||||
import org.gradle.api.tasks.SourceSet;
|
import org.gradle.api.tasks.SourceSet;
|
||||||
|
|
||||||
import org.hibernate.bytecode.enhance.spi.DefaultEnhancementContext;
|
|
||||||
import org.hibernate.bytecode.enhance.spi.EnhancementContext;
|
|
||||||
import org.hibernate.bytecode.enhance.spi.Enhancer;
|
|
||||||
import org.hibernate.bytecode.enhance.spi.UnloadedClass;
|
|
||||||
import org.hibernate.bytecode.enhance.spi.UnloadedField;
|
|
||||||
import org.hibernate.cfg.Environment;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Hibernate Gradle plugin. Adds Hibernate build-time capabilities into your Gradle-based build.
|
* The Hibernate Gradle plugin. Adds Hibernate build-time capabilities into your Gradle-based build.
|
||||||
*
|
*
|
||||||
|
@ -44,8 +19,6 @@ import org.hibernate.cfg.Environment;
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class HibernatePlugin implements Plugin<Project> {
|
public class HibernatePlugin implements Plugin<Project> {
|
||||||
private final Logger logger = Logging.getLogger( HibernatePlugin.class );
|
|
||||||
|
|
||||||
public void apply(Project project) {
|
public void apply(Project project) {
|
||||||
project.getPlugins().apply( "java" );
|
project.getPlugins().apply( "java" );
|
||||||
|
|
||||||
|
@ -55,16 +28,12 @@ public class HibernatePlugin implements Plugin<Project> {
|
||||||
project.getExtensions().add( "hibernate", hibernateExtension );
|
project.getExtensions().add( "hibernate", hibernateExtension );
|
||||||
|
|
||||||
project.afterEvaluate(
|
project.afterEvaluate(
|
||||||
p -> {
|
p -> applyEnhancement( p, hibernateExtension )
|
||||||
if ( hibernateExtension.enhance != null ) {
|
|
||||||
applyEnhancement( p, hibernateExtension );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyEnhancement(final Project project, final HibernateExtension hibernateExtension) {
|
private void applyEnhancement(final Project project, final HibernateExtension hibernateExtension) {
|
||||||
if ( !hibernateExtension.enhance.shouldApply() ) {
|
if ( hibernateExtension.enhance == null || ! hibernateExtension.enhance.shouldApply() ) {
|
||||||
project.getLogger().warn( "Skipping Hibernate bytecode enhancement since no feature is enabled" );
|
project.getLogger().warn( "Skipping Hibernate bytecode enhancement since no feature is enabled" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue