diff --git a/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java b/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java index ab9e3cb132..f70b16c472 100644 --- a/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java +++ b/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java @@ -769,12 +769,7 @@ public final class } Cacheable cacheableAnn = clazzToProcess.getAnnotation( Cacheable.class ); - SharedCacheMode mode = (SharedCacheMode) mappings.getConfigurationProperties().get( - "javax.persistence.sharedCache.mode" - ); - if ( mode == null ) { - mode = SharedCacheMode.UNSPECIFIED; - } + SharedCacheMode mode = determineSharedCacheMode( mappings ); switch ( mode ) { case ALL: { cacheAnn = buildCacheMock( clazzToProcess.getName(), mappings ); @@ -800,6 +795,33 @@ public final class return cacheAnn; } + private static SharedCacheMode determineSharedCacheMode(ExtendedMappings mappings) { + SharedCacheMode mode; + final Object value = mappings.getConfigurationProperties().get( "javax.persistence.sharedCache.mode" ); + if ( value == null ) { + log.debug( "no value specified for 'javax.persistence.sharedCache.mode'; using UNSPECIFIED" ); + mode = SharedCacheMode.UNSPECIFIED; + } + else { + if ( SharedCacheMode.class.isInstance( value ) ) { + mode = ( SharedCacheMode ) value; + } + else { + try { + mode = SharedCacheMode.valueOf( value.toString() ); + } + catch ( Exception e ) { + log.debug( + "Unable to resolve given mode name [" + value.toString() + + "]; using UNSPECIFIED : " + e.toString() + ); + mode = SharedCacheMode.UNSPECIFIED; + } + } + } + return mode; + } + private static Cache buildCacheMock(String region, ExtendedMappings mappings) { return new LocalCacheAnnotationImpl( region, determineCacheConcurrencyStrategy( mappings ) ); } diff --git a/entitymanager/src/main/java/org/hibernate/ejb/AvailableSettings.java b/entitymanager/src/main/java/org/hibernate/ejb/AvailableSettings.java index 44994578e2..b4f5ffdce8 100644 --- a/entitymanager/src/main/java/org/hibernate/ejb/AvailableSettings.java +++ b/entitymanager/src/main/java/org/hibernate/ejb/AvailableSettings.java @@ -146,6 +146,11 @@ public class AvailableSettings { */ public static final String VALIDATION_MODE = "javax.persistence.validation.mode"; + /** + * Used to pass along any discovered validator factory. + */ + public static final String VALIDATION_FACTORY = "javax.persistence.validation.factory"; + /** * Used to request (hint) a pessimistic lock scope. *

diff --git a/entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java b/entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java index c8a26dd900..2ed38f7e4a 100644 --- a/entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java +++ b/entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java @@ -54,6 +54,7 @@ import javax.persistence.EntityManagerFactory; import javax.persistence.EntityNotFoundException; import javax.persistence.MappedSuperclass; import javax.persistence.PersistenceException; +import javax.persistence.SharedCacheMode; import javax.persistence.spi.PersistenceUnitInfo; import javax.persistence.spi.PersistenceUnitTransactionType; import javax.sql.DataSource; @@ -161,6 +162,7 @@ public class Ejb3Configuration implements Serializable, Referenceable { * If used, be sure to not override the hibernate.connection.provider_class * property */ + @SuppressWarnings({ "JavaDoc", "unchecked" }) public void setDataSource(DataSource ds) { if ( ds != null ) { Map cpInjection = new HashMap(); @@ -173,10 +175,23 @@ public class Ejb3Configuration implements Serializable, Referenceable { /** * create a factory from a parsed persistence.xml * Especially the scanning of classes and additional jars is done already at this point. + *

+ * NOTE: public only for unit testing purposes; not a public API! + * + * @param metadata The information parsed from the persistence.xml + * @param overridesIn Any explicitly passed config settings + * + * @return this */ - private Ejb3Configuration configure(PersistenceMetadata metadata, Map overrides) { + @SuppressWarnings({ "unchecked" }) + public Ejb3Configuration configure(PersistenceMetadata metadata, Map overridesIn) { log.debug( "Creating Factory: {}", metadata.getName() ); + Map overrides = new HashMap(); + if ( overridesIn != null ) { + overrides.putAll( overridesIn ); + } + Map workingVars = new HashMap(); workingVars.put( AvailableSettings.PERSISTENCE_UNIT_NAME, metadata.getName() ); this.persistenceUnitName = metadata.getName(); @@ -218,20 +233,46 @@ public class Ejb3Configuration implements Serializable, Referenceable { if ( metadata.getHbmfiles().size() > 0 ) { workingVars.put( AvailableSettings.HBXML_FILES, metadata.getHbmfiles() ); } - if ( metadata.getValidationMode() != null) { - workingVars.put( AvailableSettings.VALIDATION_MODE, metadata.getValidationMode() ); - } - if ( metadata.getSharedCacheMode() != null) { - workingVars.put( AvailableSettings.SHARED_CACHE_MODE, metadata.getSharedCacheMode() ); - } + Properties props = new Properties(); props.putAll( metadata.getProps() ); - if ( overrides != null ) { - for ( Map.Entry entry : (Set) overrides.entrySet() ) { - Object value = entry.getValue(); - props.put( entry.getKey(), value == null ? "" : value ); //alter null, not allowed in properties - } + + // validation factory + final Object validationFactory = overrides.get( AvailableSettings.VALIDATION_FACTORY ); + if ( validationFactory != null ) { + props.put( AvailableSettings.VALIDATION_FACTORY, validationFactory ); } + overrides.remove( AvailableSettings.VALIDATION_FACTORY ); + + // validation-mode (overrides has precedence) + { + final Object integrationValue = overrides.get( AvailableSettings.VALIDATION_MODE ); + if ( integrationValue != null ) { + props.put( AvailableSettings.VALIDATION_MODE, integrationValue.toString() ); + } + else if ( metadata.getValidationMode() != null ) { + props.put( AvailableSettings.VALIDATION_MODE, metadata.getValidationMode() ); + } + overrides.remove( AvailableSettings.VALIDATION_MODE ); + } + + // shared-cache-mode (overrides has precedence) + { + final Object integrationValue = overrides.get( AvailableSettings.SHARED_CACHE_MODE ); + if ( integrationValue != null ) { + props.put( AvailableSettings.SHARED_CACHE_MODE, integrationValue.toString() ); + } + else if ( metadata.getSharedCacheMode() != null ) { + props.put( AvailableSettings.SHARED_CACHE_MODE, metadata.getSharedCacheMode() ); + } + overrides.remove( AvailableSettings.SHARED_CACHE_MODE ); + } + + for ( Map.Entry entry : (Set) overrides.entrySet() ) { + Object value = entry.getValue(); + props.put( entry.getKey(), value == null ? "" : value ); //alter null, not allowed in properties + } + configure( props, workingVars ); return this; } @@ -246,8 +287,12 @@ public class Ejb3Configuration implements Serializable, Referenceable { * * @param persistenceUnitName persistence unit name * @param integration properties passed to the persistence provider + * * @return configured Ejb3Configuration or null if no persistence unit match + * + * @see HibernatePersistence#createEntityManagerFactory(String, java.util.Map) */ + @SuppressWarnings({ "unchecked" }) public Ejb3Configuration configure(String persistenceUnitName, Map integration) { try { log.debug( "Look up for persistence unit: {}", persistenceUnitName ); @@ -416,9 +461,18 @@ public class Ejb3Configuration implements Serializable, Referenceable { } /** - * Process configuration from a PersistenceUnitInfo object - * Typically called by the container + * Process configuration from a PersistenceUnitInfo object; typically called by the container + * via {@link javax.persistence.spi.PersistenceProvider#createContainerEntityManagerFactory}. + * In Hibernate EM, this correlates to {@link HibernatePersistence#createContainerEntityManagerFactory} + * + * @param info The persistence unit info passed in by the container (usually from processing a persistence.xml). + * @param integration The map of integration properties from the container to configure the provider. + * + * @return The configured EJB3Configurartion object + * + * @see HibernatePersistence#createContainerEntityManagerFactory */ + @SuppressWarnings({ "unchecked" }) public Ejb3Configuration configure(PersistenceUnitInfo info, Map integration) { if ( log.isDebugEnabled() ) { log.debug( "Processing {}", LogHelper.logPersistenceUnitInfo( info ) ); @@ -427,19 +481,26 @@ public class Ejb3Configuration implements Serializable, Referenceable { log.info( "Processing PersistenceUnitInfo [\n\tname: {}\n\t...]", info.getPersistenceUnitName() ); } + // Spec says the passed map may be null, so handle that to make further processing easier... integration = integration != null ? Collections.unmodifiableMap( integration ) : CollectionHelper.EMPTY_MAP; + + // See if we (Hibernate) are the persistence provider String provider = (String) integration.get( AvailableSettings.PROVIDER ); - if ( provider == null ) provider = info.getPersistenceProviderClassName(); + if ( provider == null ) { + provider = info.getPersistenceProviderClassName(); + } if ( provider != null && ! provider.trim().startsWith( IMPLEMENTATION_NAME ) ) { log.info( "Required a different provider: {}", provider ); return null; } + + // set the classloader, passed in by the container in info, to set as the TCCL so that + // Hibernate uses it to properly resolve class references. if ( info.getClassLoader() == null ) { throw new IllegalStateException( "[PersistenceUnit: " + info.getPersistenceUnitName() == null ? "" : info.getPersistenceUnitName() + "] " + "PersistenceUnitInfo.getClassLoader() id null" ); } - //set the classloader Thread thread = Thread.currentThread(); ClassLoader contextClassLoader = thread.getContextClassLoader(); boolean sameClassLoader = info.getClassLoader().equals( contextClassLoader ); @@ -451,6 +512,10 @@ public class Ejb3Configuration implements Serializable, Referenceable { overridenClassLoader = null; } + // Best I can tell, 'workingVars' is some form of additional configuration contract. + // But it does not correlate 1-1 to EMF/SF settings. It really is like a set of de-typed + // additional configuration info. I think it makes better sense to define this as an actual + // contract if that was in fact the intent; the code here is pretty confusing. try { Map workingVars = new HashMap(); workingVars.put( AvailableSettings.PERSISTENCE_UNIT_NAME, info.getPersistenceUnitName() ); @@ -460,7 +525,9 @@ public class Ejb3Configuration implements Serializable, Referenceable { List hbmFiles = new ArrayList(); List packages = new ArrayList(); List xmlFiles = new ArrayList( 50 ); - if ( info.getMappingFileNames() != null ) xmlFiles.addAll( info.getMappingFileNames() ); + if ( info.getMappingFileNames() != null ) { + xmlFiles.addAll( info.getMappingFileNames() ); + } //Should always be true if the container is not dump boolean searchForORMFiles = ! xmlFiles.contains( META_INF_ORM_XML ); @@ -481,9 +548,7 @@ public class Ejb3Configuration implements Serializable, Referenceable { setDetectedArtifactsOnScanningContext( context, info.getProperties(), null, info.excludeUnlistedClasses() ); scanForClasses( context, packages, entities, hbmFiles ); - Properties properties = info.getProperties() != null ? - info.getProperties() : - new Properties(); + Properties properties = info.getProperties() != null ? info.getProperties() : new Properties(); ConfigurationHelper.overrideProperties( properties, integration ); //FIXME entities is used to enhance classes and to collect annotated entities this should not be mixed @@ -500,16 +565,32 @@ public class Ejb3Configuration implements Serializable, Referenceable { workingVars.put( AvailableSettings.XML_FILE_NAMES, xmlFiles ); if ( hbmFiles.size() > 0 ) workingVars.put( AvailableSettings.HBXML_FILES, hbmFiles ); - //validation-mode - final Object validationMode = info.getValidationMode(); - if ( validationMode != null) { - workingVars.put( AvailableSettings.VALIDATION_MODE, validationMode ); + // validation factory + final Object validationFactory = integration.get( AvailableSettings.VALIDATION_FACTORY ); + if ( validationFactory != null ) { + properties.put( AvailableSettings.VALIDATION_FACTORY, validationFactory ); } - //shared-cache-mode - final Object sharedCacheMode = info.getSharedCacheMode(); - if ( sharedCacheMode != null) { - workingVars.put( AvailableSettings.SHARED_CACHE_MODE, sharedCacheMode ); + // validation-mode (integration has precedence) + { + final Object integrationValue = integration.get( AvailableSettings.VALIDATION_MODE ); + if ( integrationValue != null ) { + properties.put( AvailableSettings.VALIDATION_MODE, integrationValue.toString() ); + } + else if ( info.getValidationMode() != null ) { + properties.put( AvailableSettings.VALIDATION_MODE, info.getValidationMode().name() ); + } + } + + // shared-cache-mode (integration has precedence) + { + final Object integrationValue = integration.get( AvailableSettings.SHARED_CACHE_MODE ); + if ( integrationValue != null ) { + properties.put( AvailableSettings.SHARED_CACHE_MODE, integrationValue.toString() ); + } + else if ( info.getSharedCacheMode() != null ) { + properties.put( AvailableSettings.SHARED_CACHE_MODE, info.getSharedCacheMode().name() ); + } } //datasources @@ -837,12 +918,20 @@ public class Ejb3Configuration implements Serializable, Referenceable { } /** - * create a factory from a canonical workingVars map and the overriden properties + * Configures this configuration object from 2 distinctly different sources. * + * @param properties These are the properties that came from the user, either via + * a persistence.xml or explicitly passed in to one of our + * {@link javax.persistence.spi.PersistenceProvider}/{@link HibernatePersistence} contracts. + * @param workingVars Is collection of settings which need to be handled similarly + * between the 2 main bootstrap methods, but where the values are determine very differently + * by each bootstrap method. todo eventually make this a contract (class/interface) + * + * @return The configured configuration + * + * @see HibernatePersistence */ - private Ejb3Configuration configure( - Properties properties, Map workingVars - ) { + private Ejb3Configuration configure(Properties properties, Map workingVars) { //TODO check for people calling more than once this method (except buildEMF) if (isConfigurationProcessed) return this; isConfigurationProcessed = true; diff --git a/entitymanager/src/main/java/org/hibernate/ejb/HibernatePersistence.java b/entitymanager/src/main/java/org/hibernate/ejb/HibernatePersistence.java index 968357d64a..b2a57c8b9f 100755 --- a/entitymanager/src/main/java/org/hibernate/ejb/HibernatePersistence.java +++ b/entitymanager/src/main/java/org/hibernate/ejb/HibernatePersistence.java @@ -26,6 +26,7 @@ package org.hibernate.ejb; import java.util.Map; import javax.persistence.EntityManagerFactory; import javax.persistence.spi.LoadState; +import javax.persistence.spi.PersistenceProvider; import javax.persistence.spi.PersistenceUnitInfo; import javax.persistence.spi.ProviderUtil; @@ -36,36 +37,52 @@ import org.hibernate.ejb.util.PersistenceUtilHelper; * * @author Gavin King */ -public class HibernatePersistence implements javax.persistence.spi.PersistenceProvider { - - //The following properties are for Internal use only - /** - * link to the alternative Hibernate configuration file - * Internal use only - */ - +public class HibernatePersistence extends AvailableSettings implements PersistenceProvider { /** - * Get an entity manager factory by its entity manager name and given the - * appropriate extra properties. Those proeprties override the one get through - * the peristence.xml file. + * Get an entity manager factory by its entity manager name, using the specified + * properties (they override any found in the peristence.xml file). + *

+ * This is the form used in JSE environments. * * @param persistenceUnitName entity manager name - * @param overridenProperties properties passed to the persistence provider + * @param properties The explicit property values + * * @return initialized EntityManagerFactory */ - public EntityManagerFactory createEntityManagerFactory(String persistenceUnitName, Map overridenProperties) { + public EntityManagerFactory createEntityManagerFactory(String persistenceUnitName, Map properties) { Ejb3Configuration cfg = new Ejb3Configuration(); - Ejb3Configuration configured = cfg.configure( persistenceUnitName, overridenProperties ); + Ejb3Configuration configured = cfg.configure( persistenceUnitName, properties ); return configured != null ? configured.buildEntityManagerFactory() : null; } - public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map map) { + /** + * Create an entity manager factory from the given persistence unit info, using the specified + * properties (they override any on the PUI). + *

+ * This is the form used by the container in a JEE environment. + * + * @param info The persistence unit information + * @param properties The explicit property values + * + * @return initialized EntityManagerFactory + */ + public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map properties) { Ejb3Configuration cfg = new Ejb3Configuration(); - Ejb3Configuration configured = cfg.configure( info, map ); + Ejb3Configuration configured = cfg.configure( info, properties ); return configured != null ? configured.buildEntityManagerFactory() : null; } + /** + * create a factory from a canonical version + * @deprecated + */ + public EntityManagerFactory createEntityManagerFactory(Map properties) { + // This is used directly by JBoss so don't remove until further notice. bill@jboss.org + Ejb3Configuration cfg = new Ejb3Configuration(); + return cfg.createEntityManagerFactory( properties ); + } + private final ProviderUtil providerUtil = new ProviderUtil() { public LoadState isLoadedWithoutReference(Object proxy, String property) { return PersistenceUtilHelper.isLoadedWithoutReference( proxy, property ); @@ -80,18 +97,11 @@ public class HibernatePersistence implements javax.persistence.spi.PersistencePr } }; + /** + * {@inheritDoc} + */ public ProviderUtil getProviderUtil() { return providerUtil; } - /** - * create a factory from a canonical version - * @deprecated - */ - public EntityManagerFactory createEntityManagerFactory(Map properties) { - // This is used directly by JBoss so don't remove until further notice. bill@jboss.org - Ejb3Configuration cfg = new Ejb3Configuration(); - return cfg.createEntityManagerFactory( properties ); - } - } \ No newline at end of file diff --git a/entitymanager/src/test/java/org/hibernate/ejb/test/ejb3configuration/ConfigurationObjectSettingTest.java b/entitymanager/src/test/java/org/hibernate/ejb/test/ejb3configuration/ConfigurationObjectSettingTest.java new file mode 100644 index 0000000000..0f2648b785 --- /dev/null +++ b/entitymanager/src/test/java/org/hibernate/ejb/test/ejb3configuration/ConfigurationObjectSettingTest.java @@ -0,0 +1,249 @@ +/* + * 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.ejb.test.ejb3configuration; + +import java.util.Collections; +import java.util.Map; +import javax.persistence.SharedCacheMode; +import javax.persistence.ValidationMode; + +import org.hibernate.HibernateException; +import org.hibernate.ejb.AvailableSettings; +import org.hibernate.ejb.Ejb3Configuration; +import org.hibernate.ejb.packaging.PersistenceMetadata; + +/** + * Test passing along various config settings that take objects other than strings as values. + * + * @author Steve Ebersole + */ +public class ConfigurationObjectSettingTest extends junit.framework.TestCase { + public void testContainerBootstrapSharedCacheMode() { + // first, via the integration vars + PersistenceUnitInfoAdapter empty = new PersistenceUnitInfoAdapter(); + { + // as object + Ejb3Configuration cfg = new Ejb3Configuration(); + Ejb3Configuration configured = cfg.configure( + empty, + Collections.singletonMap( AvailableSettings.SHARED_CACHE_MODE, SharedCacheMode.DISABLE_SELECTIVE ) + ); + assertEquals( SharedCacheMode.DISABLE_SELECTIVE.name(), configured.getProperties().get( AvailableSettings.SHARED_CACHE_MODE ) ); + } + { + // as string + Ejb3Configuration cfg = new Ejb3Configuration(); + Ejb3Configuration configured = cfg.configure( + empty, + Collections.singletonMap( AvailableSettings.SHARED_CACHE_MODE, SharedCacheMode.DISABLE_SELECTIVE.name() ) + ); + assertEquals( SharedCacheMode.DISABLE_SELECTIVE.name(), configured.getProperties().get( AvailableSettings.SHARED_CACHE_MODE ) ); + } + + // next, via the PUI + PersistenceUnitInfoAdapter adapter = new PersistenceUnitInfoAdapter() { + @Override + public SharedCacheMode getSharedCacheMode() { + return SharedCacheMode.ENABLE_SELECTIVE; + } + }; + { + Ejb3Configuration cfg = new Ejb3Configuration(); + Ejb3Configuration configured = cfg.configure( adapter, null ); + assertEquals( SharedCacheMode.ENABLE_SELECTIVE.name(), configured.getProperties().get( AvailableSettings.SHARED_CACHE_MODE ) ); + } + + // via both, integration vars should take precedence + { + Ejb3Configuration cfg = new Ejb3Configuration(); + Ejb3Configuration configured = cfg.configure( + adapter, + Collections.singletonMap( AvailableSettings.SHARED_CACHE_MODE, SharedCacheMode.DISABLE_SELECTIVE ) + ); + assertEquals( SharedCacheMode.DISABLE_SELECTIVE.name(), configured.getProperties().get( AvailableSettings.SHARED_CACHE_MODE ) ); + } + } + + public void testContainerBootstrapValidationMode() { + // first, via the integration vars + PersistenceUnitInfoAdapter empty = new PersistenceUnitInfoAdapter(); + { + // as object + Ejb3Configuration cfg = new Ejb3Configuration(); + Ejb3Configuration configured = cfg.configure( + empty, + Collections.singletonMap( AvailableSettings.VALIDATION_MODE, ValidationMode.CALLBACK ) + ); + assertEquals( ValidationMode.CALLBACK.name(), configured.getProperties().get( AvailableSettings.VALIDATION_MODE ) ); + } + { + // as string + Ejb3Configuration cfg = new Ejb3Configuration(); + Ejb3Configuration configured = cfg.configure( + empty, + Collections.singletonMap( AvailableSettings.VALIDATION_MODE, ValidationMode.CALLBACK.name() ) + ); + assertEquals( ValidationMode.CALLBACK.name(), configured.getProperties().get( AvailableSettings.VALIDATION_MODE ) ); + } + + // next, via the PUI + PersistenceUnitInfoAdapter adapter = new PersistenceUnitInfoAdapter() { + @Override + public ValidationMode getValidationMode() { + return ValidationMode.CALLBACK; + } + }; + { + Ejb3Configuration cfg = new Ejb3Configuration(); + Ejb3Configuration configured = cfg.configure( adapter, null ); + assertEquals( ValidationMode.CALLBACK.name(), configured.getProperties().get( AvailableSettings.VALIDATION_MODE ) ); + } + + // via both, integration vars should take precedence + { + Ejb3Configuration cfg = new Ejb3Configuration(); + Ejb3Configuration configured = cfg.configure( + adapter, + Collections.singletonMap( AvailableSettings.VALIDATION_MODE, ValidationMode.NONE ) + ); + assertEquals( ValidationMode.NONE.name(), configured.getProperties().get( AvailableSettings.VALIDATION_MODE ) ); + } + } + + public void testContainerBootstrapValidationFactory() { + final Object token = new Object(); + PersistenceUnitInfoAdapter adapter = new PersistenceUnitInfoAdapter(); + Ejb3Configuration cfg = new Ejb3Configuration(); + try { + cfg.configure( + adapter, + Collections.singletonMap( AvailableSettings.VALIDATION_FACTORY, token ) + ); + fail( "Was expecting error as token did not implement ValidatorFactory" ); + } + catch ( HibernateException e ) { + // probably the condition we want but unfortunately the exception is not specific + // and the pertinent info is in a cause + } + } + + public void testStandaloneBootstrapSharedCacheMode() { + // first, via the integration vars + PersistenceMetadata metadata = new PersistenceMetadata(); + { + // as object + Ejb3Configuration cfg = new Ejb3Configuration(); + Ejb3Configuration configured = cfg.configure( + metadata, + Collections.singletonMap( AvailableSettings.SHARED_CACHE_MODE, SharedCacheMode.DISABLE_SELECTIVE ) + ); + assertEquals( SharedCacheMode.DISABLE_SELECTIVE.name(), configured.getProperties().get( AvailableSettings.SHARED_CACHE_MODE ) ); + } + { + // as string + Ejb3Configuration cfg = new Ejb3Configuration(); + Ejb3Configuration configured = cfg.configure( + metadata, + Collections.singletonMap( AvailableSettings.SHARED_CACHE_MODE, SharedCacheMode.DISABLE_SELECTIVE.name() ) + ); + assertEquals( SharedCacheMode.DISABLE_SELECTIVE.name(), configured.getProperties().get( AvailableSettings.SHARED_CACHE_MODE ) ); + } + + // next, via the PM + metadata.setSharedCacheMode( SharedCacheMode.ENABLE_SELECTIVE.name() ); + { + Ejb3Configuration cfg = new Ejb3Configuration(); + Ejb3Configuration configured = cfg.configure( metadata, null ); + assertEquals( SharedCacheMode.ENABLE_SELECTIVE.name(), configured.getProperties().get( AvailableSettings.SHARED_CACHE_MODE ) ); + } + + // via both, integration vars should take precedence + { + Ejb3Configuration cfg = new Ejb3Configuration(); + Ejb3Configuration configured = cfg.configure( + metadata, + Collections.singletonMap( AvailableSettings.SHARED_CACHE_MODE, SharedCacheMode.DISABLE_SELECTIVE ) + ); + assertEquals( SharedCacheMode.DISABLE_SELECTIVE.name(), configured.getProperties().get( AvailableSettings.SHARED_CACHE_MODE ) ); + } + } + + public void testStandaloneBootstrapValidationMode() { + // first, via the integration vars + PersistenceMetadata metadata = new PersistenceMetadata(); + { + // as object + Ejb3Configuration cfg = new Ejb3Configuration(); + Ejb3Configuration configured = cfg.configure( + metadata, + Collections.singletonMap( AvailableSettings.VALIDATION_MODE, ValidationMode.CALLBACK ) + ); + assertEquals( ValidationMode.CALLBACK.name(), configured.getProperties().get( AvailableSettings.VALIDATION_MODE ) ); + } + { + // as string + Ejb3Configuration cfg = new Ejb3Configuration(); + Ejb3Configuration configured = cfg.configure( + metadata, + Collections.singletonMap( AvailableSettings.VALIDATION_MODE, ValidationMode.CALLBACK.name() ) + ); + assertEquals( ValidationMode.CALLBACK.name(), configured.getProperties().get( AvailableSettings.VALIDATION_MODE ) ); + } + + // next, via the PUI + metadata.setValidationMode( ValidationMode.AUTO.name() ); + { + Ejb3Configuration cfg = new Ejb3Configuration(); + Ejb3Configuration configured = cfg.configure( metadata, null ); + assertEquals( ValidationMode.AUTO.name(), configured.getProperties().get( AvailableSettings.VALIDATION_MODE ) ); + } + + // via both, integration vars should take precedence + { + Ejb3Configuration cfg = new Ejb3Configuration(); + Ejb3Configuration configured = cfg.configure( + metadata, + Collections.singletonMap( AvailableSettings.VALIDATION_MODE, ValidationMode.NONE ) + ); + assertEquals( ValidationMode.NONE.name(), configured.getProperties().get( AvailableSettings.VALIDATION_MODE ) ); + } + } + + public void testStandaloneBootstrapValidationFactory() { + final Object token = new Object(); + PersistenceMetadata metadata = new PersistenceMetadata(); + Ejb3Configuration cfg = new Ejb3Configuration(); + try { + cfg.configure( + metadata, + Collections.singletonMap( AvailableSettings.VALIDATION_FACTORY, token ) + ); + fail( "Was expecting error as token did not implement ValidatorFactory" ); + } + catch ( HibernateException e ) { + // probably the condition we want but unfortunately the exception is not specific + // and the pertinent info is in a cause + } + } +} diff --git a/entitymanager/src/test/java/org/hibernate/ejb/test/ejb3configuration/PersistenceUnitInfoAdapter.java b/entitymanager/src/test/java/org/hibernate/ejb/test/ejb3configuration/PersistenceUnitInfoAdapter.java new file mode 100644 index 0000000000..2e322ca1c4 --- /dev/null +++ b/entitymanager/src/test/java/org/hibernate/ejb/test/ejb3configuration/PersistenceUnitInfoAdapter.java @@ -0,0 +1,116 @@ +/* + * 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.ejb.test.ejb3configuration; + +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.ejb.HibernatePersistence; + +/** + * TODO : javadoc + * + * @author Steve Ebersole + */ +public class PersistenceUnitInfoAdapter implements PersistenceUnitInfo { + private Properties properties; + + public String getPersistenceUnitName() { + return "persistenceUnitAdapter"; + } + + public String getPersistenceProviderClassName() { + return HibernatePersistence.class.getName(); + } + + public PersistenceUnitTransactionType getTransactionType() { + return null; + } + + public DataSource getJtaDataSource() { + return null; + } + + public DataSource getNonJtaDataSource() { + return null; + } + + public List getMappingFileNames() { + return Collections.emptyList(); + } + + public List getJarFileUrls() { + return Collections.emptyList(); + } + + public URL getPersistenceUnitRootUrl() { + return null; + } + + public List 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(); + } +}