Created
January 6, 2014 20:02
-
-
Save gbadner/8288905 to your computer and use it in GitHub Desktop.
BaseCoreFunctionalTestCase conflict
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Hibernate, Relational Persistence for Idiomatic Java | |
* | |
* Copyright (c) 2011, 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.junit4; | |
import static org.junit.Assert.fail; | |
import java.io.InputStream; | |
import java.sql.Blob; | |
import java.sql.Clob; | |
import java.sql.Connection; | |
import java.sql.SQLException; | |
import java.util.HashMap; | |
import java.util.Iterator; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.Properties; | |
import org.hibernate.HibernateException; | |
import org.hibernate.Interceptor; | |
import org.hibernate.Session; | |
import org.hibernate.boot.registry.BootstrapServiceRegistry; | |
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder; | |
import org.hibernate.boot.registry.StandardServiceRegistryBuilder; | |
import org.hibernate.boot.registry.internal.StandardServiceRegistryImpl; | |
import org.hibernate.cache.spi.access.AccessType; | |
import org.hibernate.cfg.AvailableSettings; | |
import org.hibernate.cfg.Configuration; | |
import org.hibernate.cfg.Environment; | |
import org.hibernate.cfg.Mappings; | |
import org.hibernate.dialect.Dialect; | |
import org.hibernate.dialect.H2Dialect; | |
import org.hibernate.engine.config.spi.ConfigurationService; | |
import org.hibernate.engine.spi.SessionFactoryImplementor; | |
import org.hibernate.engine.spi.SessionImplementor; | |
import org.hibernate.internal.util.StringHelper; | |
import org.hibernate.internal.util.config.ConfigurationHelper; | |
import org.hibernate.jdbc.AbstractReturningWork; | |
import org.hibernate.jdbc.Work; | |
import org.hibernate.mapping.Collection; | |
import org.hibernate.mapping.PersistentClass; | |
import org.hibernate.mapping.Property; | |
import org.hibernate.mapping.SimpleValue; | |
import org.hibernate.metamodel.MetadataSources; | |
import org.hibernate.metamodel.spi.MetadataImplementor; | |
import org.hibernate.metamodel.spi.binding.AbstractPluralAttributeBinding; | |
import org.hibernate.metamodel.spi.binding.AttributeBinding; | |
import org.hibernate.metamodel.spi.binding.Caching; | |
import org.hibernate.metamodel.spi.binding.EntityBinding; | |
import org.hibernate.metamodel.spi.binding.PluralAttributeBinding; | |
import org.hibernate.testing.AfterClassOnce; | |
import org.hibernate.testing.BeforeClassOnce; | |
import org.hibernate.testing.OnExpectedFailure; | |
import org.hibernate.testing.OnFailure; | |
import org.hibernate.testing.SkipLog; | |
import org.hibernate.testing.cache.CachingRegionFactory; | |
import org.hibernate.type.Type; | |
import org.junit.After; | |
import org.junit.Before; | |
/** | |
* Applies functional testing logic for core Hibernate testing on top of {@link BaseUnitTestCase} | |
* | |
* @author Steve Ebersole | |
*/ | |
public abstract class BaseCoreFunctionalTestCase extends BaseUnitTestCase { | |
public static final String VALIDATE_DATA_CLEANUP = "hibernate.test.validateDataCleanup"; | |
public static final String USE_NEW_METADATA_MAPPINGS = "hibernate.test.new_metadata_mappings"; | |
public static final Dialect DIALECT = Dialect.getDialect(); | |
private boolean isMetadataUsed; | |
private Configuration configuration; | |
private MetadataImplementor metadataImplementor; | |
private StandardServiceRegistryImpl serviceRegistry; | |
private SessionFactoryImplementor sessionFactory; | |
protected Session session; | |
protected static Dialect getDialect() { | |
return DIALECT; | |
} | |
protected Configuration configuration() { | |
return configuration; | |
} | |
protected MetadataImplementor metadata() { | |
return metadataImplementor; | |
} | |
protected EntityBinding getEntityBinding(Class<?> clazz) { | |
return metadataImplementor.getEntityBinding( clazz.getName() ); | |
} | |
protected EntityBinding getRootEntityBinding(Class<?> clazz) { | |
return metadataImplementor.getRootEntityBinding( clazz.getName() ); | |
} | |
protected Iterator<PluralAttributeBinding> getCollectionBindings() { | |
return metadataImplementor.getCollectionBindings().iterator(); | |
} | |
protected StandardServiceRegistryImpl serviceRegistry() { | |
return serviceRegistry; | |
} | |
protected SessionFactoryImplementor sessionFactory() { | |
return sessionFactory; | |
} | |
protected Session openSession() throws HibernateException { | |
session = sessionFactory().openSession(); | |
return session; | |
} | |
protected Session openSession(Interceptor interceptor) throws HibernateException { | |
session = sessionFactory().withOptions().interceptor( interceptor ).openSession(); | |
return session; | |
} | |
// before/after test class ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
@BeforeClassOnce | |
@SuppressWarnings( {"UnusedDeclaration"}) | |
protected void buildSessionFactory() { | |
// for now, build the configuration to get all the property settings | |
configuration = constructAndConfigureConfiguration(); | |
BootstrapServiceRegistry bootRegistry = buildBootstrapServiceRegistry(); | |
serviceRegistry = buildServiceRegistry( bootRegistry, configuration ); | |
isMetadataUsed = serviceRegistry.getService( ConfigurationService.class ).getSetting( | |
USE_NEW_METADATA_MAPPINGS, | |
new ConfigurationService.Converter<Boolean>() { | |
@Override | |
public Boolean convert(Object value) { | |
return Boolean.parseBoolean( ( String ) value ); | |
} | |
}, | |
true | |
); | |
if ( isMetadataUsed ) { | |
metadataImplementor = buildMetadata( bootRegistry, serviceRegistry ); | |
afterConstructAndConfigureMetadata( metadataImplementor ); | |
applyCacheSettings( metadataImplementor ); | |
sessionFactory = ( SessionFactoryImplementor ) metadataImplementor.buildSessionFactory(); | |
} | |
else { | |
// this is done here because Configuration does not currently support 4.0 xsd | |
afterConstructAndConfigureConfiguration( configuration ); | |
sessionFactory = ( SessionFactoryImplementor ) configuration.buildSessionFactory( serviceRegistry ); | |
} | |
afterSessionFactoryBuilt(); | |
} | |
protected void rebuildSessionFactory() { | |
if ( sessionFactory == null ) { | |
return; | |
} | |
try { | |
sessionFactory.close(); | |
} | |
catch (Exception ignore) { | |
} | |
buildSessionFactory(); | |
} | |
protected void afterConstructAndConfigureMetadata(MetadataImplementor metadataImplementor) { | |
} | |
private MetadataImplementor buildMetadata( | |
BootstrapServiceRegistry bootRegistry, | |
StandardServiceRegistryImpl serviceRegistry) { | |
MetadataSources sources = new MetadataSources( bootRegistry ); | |
addMappings( sources ); | |
return (MetadataImplementor) sources.getMetadataBuilder( serviceRegistry ).build(); | |
} | |
<<<<<<< HEAD | |
// TODO: is this still needed? | |
protected Configuration buildConfiguration() { | |
Configuration cfg = constructAndConfigureConfiguration(); | |
afterConstructAndConfigureConfiguration( cfg ); | |
return cfg; | |
} | |
protected Configuration constructAndConfigureConfiguration() { | |
======= | |
private Configuration constructAndConfigureConfiguration() { | |
>>>>>>> HHH-7666 Replace unit tests' use of configuration() | |
Configuration cfg = constructConfiguration(); | |
configure( cfg ); | |
return cfg; | |
} | |
private void afterConstructAndConfigureConfiguration(Configuration cfg) { | |
addMappings( cfg ); | |
cfg.buildMappings(); | |
applyCacheSettings( cfg ); | |
afterConfigurationBuilt( cfg ); | |
} | |
protected Configuration constructConfiguration() { | |
Configuration configuration = new Configuration() | |
.setProperty(Environment.CACHE_REGION_FACTORY, CachingRegionFactory.class.getName() ); | |
configuration.setProperty( AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS, "true" ); | |
if ( createSchema() ) { | |
configuration.setProperty( Environment.HBM2DDL_AUTO, "create-drop" ); | |
final String secondSchemaName = createSecondSchema(); | |
if ( StringHelper.isNotEmpty( secondSchemaName ) ) { | |
if ( !( getDialect() instanceof H2Dialect ) ) { | |
throw new UnsupportedOperationException( "Only H2 dialect supports creation of second schema." ); | |
} | |
Helper.createH2Schema( secondSchemaName, configuration ); | |
} | |
} | |
configuration.setProperty( Environment.DIALECT, getDialect().getClass().getName() ); | |
return configuration; | |
} | |
protected void configure(Configuration configuration) { | |
} | |
protected void addMappings(Configuration configuration) { | |
String[] mappings = getMappings(); | |
if ( mappings != null ) { | |
for ( String mapping : mappings ) { | |
configuration.addResource( | |
getBaseForMappings() + mapping, | |
getClass().getClassLoader() | |
); | |
} | |
} | |
Class<?>[] annotatedClasses = getAnnotatedClasses(); | |
if ( annotatedClasses != null ) { | |
for ( Class<?> annotatedClass : annotatedClasses ) { | |
configuration.addAnnotatedClass( annotatedClass ); | |
} | |
} | |
String[] annotatedPackages = getAnnotatedPackages(); | |
if ( annotatedPackages != null ) { | |
for ( String annotatedPackage : annotatedPackages ) { | |
configuration.addPackage( annotatedPackage ); | |
} | |
} | |
String[] xmlFiles = getXmlFiles(); | |
if ( xmlFiles != null ) { | |
for ( String xmlFile : xmlFiles ) { | |
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream( xmlFile ); | |
configuration.addInputStream( is ); | |
} | |
} | |
} | |
protected void addMappings(MetadataSources sources) { | |
String[] mappings = getMappings(); | |
if ( mappings != null ) { | |
for ( String mapping : mappings ) { | |
sources.addResource( | |
getBaseForMappings() + mapping | |
); | |
} | |
} | |
Class<?>[] annotatedClasses = getAnnotatedClasses(); | |
if ( annotatedClasses != null ) { | |
for ( Class<?> annotatedClass : annotatedClasses ) { | |
sources.addAnnotatedClass( annotatedClass ); | |
} | |
} | |
String[] annotatedPackages = getAnnotatedPackages(); | |
if ( annotatedPackages != null ) { | |
for ( String annotatedPackage : annotatedPackages ) { | |
sources.addPackage( annotatedPackage ); | |
} | |
} | |
String[] xmlFiles = getXmlFiles(); | |
if ( xmlFiles != null ) { | |
for ( String xmlFile : xmlFiles ) { | |
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream( xmlFile ); | |
sources.addInputStream( is ); | |
} | |
} | |
} | |
protected static final String[] NO_MAPPINGS = new String[0]; | |
protected String[] getMappings() { | |
return NO_MAPPINGS; | |
} | |
protected String getBaseForMappings() { | |
return "org/hibernate/test/"; | |
} | |
protected static final Class<?>[] NO_CLASSES = new Class[0]; | |
protected Class<?>[] getAnnotatedClasses() { | |
return NO_CLASSES; | |
} | |
protected String[] getAnnotatedPackages() { | |
return NO_MAPPINGS; | |
} | |
protected String[] getXmlFiles() { | |
// todo : rename to getOrmXmlFiles() | |
return NO_MAPPINGS; | |
} | |
protected void applyCacheSettings(MetadataImplementor metadataImplementor){ | |
if( StringHelper.isEmpty(getCacheConcurrencyStrategy())){ | |
return; | |
} | |
for( EntityBinding entityBinding : metadataImplementor.getEntityBindings()){ | |
boolean hasLob = false; | |
for( AttributeBinding attributeBinding : entityBinding.getAttributeBindingClosure()){ | |
if ( attributeBinding.getAttribute().isSingular() ) { | |
Type type = attributeBinding.getHibernateTypeDescriptor().getResolvedTypeMapping(); | |
String typeName = type.getName(); | |
if ( "blob".equals( typeName ) || "clob".equals( typeName ) ) { | |
hasLob = true; | |
} | |
if ( Blob.class.getName().equals( typeName ) || Clob.class.getName().equals( typeName ) ) { | |
hasLob = true; | |
} | |
} | |
} | |
if ( !hasLob && !entityBinding.getHierarchyDetails().isExplicitPolymorphism() && overrideCacheStrategy() ) { | |
Caching caching = entityBinding.getHierarchyDetails().getCaching(); | |
if ( caching == null ) { | |
caching = new Caching(); | |
} | |
caching.setRegion( entityBinding.getEntity().getName() ); | |
caching.setCacheLazyProperties( true ); | |
caching.setAccessType( AccessType.fromExternalName( getCacheConcurrencyStrategy() ) ); | |
entityBinding.getHierarchyDetails().setCaching( caching ); | |
} | |
for( AttributeBinding attributeBinding : entityBinding.getAttributeBindingClosure()){ | |
if ( !attributeBinding.getAttribute().isSingular() ) { | |
AbstractPluralAttributeBinding binding = AbstractPluralAttributeBinding.class.cast( attributeBinding ); | |
Caching caching = binding.getCaching(); | |
if(caching == null){ | |
caching = new Caching( ); | |
} | |
caching.setRegion( StringHelper.qualify( entityBinding.getEntity().getName() , attributeBinding.getAttribute().getName() ) ); | |
caching.setCacheLazyProperties( true ); | |
caching.setAccessType( AccessType.fromExternalName( getCacheConcurrencyStrategy() ) ); | |
binding.setCaching( caching ); | |
} | |
} | |
} | |
} | |
protected void applyCacheSettings(Configuration configuration) { | |
if ( getCacheConcurrencyStrategy() != null ) { | |
Iterator itr = configuration.getClassMappings(); | |
while ( itr.hasNext() ) { | |
PersistentClass clazz = (PersistentClass) itr.next(); | |
Iterator props = clazz.getPropertyClosureIterator(); | |
boolean hasLob = false; | |
while ( props.hasNext() ) { | |
Property prop = (Property) props.next(); | |
if ( prop.getValue().isSimpleValue() ) { | |
String type = ( (SimpleValue) prop.getValue() ).getTypeName(); | |
if ( "blob".equals(type) || "clob".equals(type) ) { | |
hasLob = true; | |
} | |
if ( Blob.class.getName().equals(type) || Clob.class.getName().equals(type) ) { | |
hasLob = true; | |
} | |
} | |
} | |
if ( !hasLob && !clazz.isInherited() && overrideCacheStrategy() ) { | |
configuration.setCacheConcurrencyStrategy( clazz.getEntityName(), getCacheConcurrencyStrategy() ); | |
} | |
} | |
itr = configuration.getCollectionMappings(); | |
while ( itr.hasNext() ) { | |
Collection coll = (Collection) itr.next(); | |
configuration.setCollectionCacheConcurrencyStrategy( coll.getRole(), getCacheConcurrencyStrategy() ); | |
} | |
} | |
} | |
protected boolean overrideCacheStrategy() { | |
return true; | |
} | |
protected String getCacheConcurrencyStrategy() { | |
return null; | |
} | |
protected void afterConfigurationBuilt(Configuration configuration) { | |
afterConfigurationBuilt( configuration.createMappings(), getDialect() ); | |
} | |
protected void afterConfigurationBuilt(Mappings mappings, Dialect dialect) { | |
} | |
protected BootstrapServiceRegistry buildBootstrapServiceRegistry() { | |
final BootstrapServiceRegistryBuilder builder = new BootstrapServiceRegistryBuilder(); | |
prepareBootstrapRegistryBuilder( builder ); | |
return builder.build(); | |
} | |
protected void prepareBootstrapRegistryBuilder(BootstrapServiceRegistryBuilder builder) { | |
} | |
protected StandardServiceRegistryImpl buildServiceRegistry(BootstrapServiceRegistry bootRegistry, Configuration configuration) { | |
Properties properties = new Properties(); | |
properties.putAll( configuration.getProperties() ); | |
Environment.verifyProperties( properties ); | |
ConfigurationHelper.resolvePlaceHolders( properties ); | |
StandardServiceRegistryBuilder registryBuilder = new StandardServiceRegistryBuilder( bootRegistry ).applySettings( properties ); | |
prepareBasicRegistryBuilder( registryBuilder ); | |
return (StandardServiceRegistryImpl) registryBuilder.build(); | |
} | |
protected void prepareBasicRegistryBuilder(StandardServiceRegistryBuilder serviceRegistryBuilder) { | |
} | |
protected void afterSessionFactoryBuilt() { | |
} | |
protected boolean createSchema() { | |
return true; | |
} | |
/** | |
* Feature supported only by H2 dialect. | |
* @return Provide not empty name to create second schema. | |
*/ | |
protected String createSecondSchema() { | |
return null; | |
} | |
protected boolean rebuildSessionFactoryOnError() { | |
return true; | |
} | |
@AfterClassOnce | |
@SuppressWarnings( {"UnusedDeclaration"}) | |
protected void releaseSessionFactory() { | |
if ( sessionFactory == null ) { | |
return; | |
} | |
sessionFactory.close(); | |
sessionFactory = null; | |
configuration = null; | |
if(serviceRegistry == null){ | |
return; | |
} | |
serviceRegistry.destroy(); | |
serviceRegistry=null; | |
} | |
@OnFailure | |
@OnExpectedFailure | |
@SuppressWarnings( {"UnusedDeclaration"}) | |
public void onFailure() { | |
if ( rebuildSessionFactoryOnError() ) { | |
rebuildSessionFactory(); | |
} | |
} | |
// before/after each test ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
@Before | |
public final void beforeTest() throws Exception { | |
prepareTest(); | |
} | |
protected void prepareTest() throws Exception { | |
} | |
@After | |
public final void afterTest() throws Exception { | |
if ( isCleanupTestDataRequired() ) { | |
cleanupTestData(); | |
} | |
cleanupTest(); | |
cleanupSession(); | |
assertAllDataRemoved(); | |
} | |
protected void cleanupCache() { | |
if ( sessionFactory != null ) { | |
sessionFactory.getCache().evictAllRegions(); | |
} | |
} | |
protected boolean isCleanupTestDataRequired() { return false; } | |
protected void cleanupTestData() throws Exception { | |
Session s = openSession(); | |
s.beginTransaction(); | |
s.createQuery( "delete from java.lang.Object" ).executeUpdate(); | |
s.getTransaction().commit(); | |
s.close(); | |
} | |
private void cleanupSession() { | |
if ( session != null && ! ( (SessionImplementor) session ).isClosed() ) { | |
if ( session.isConnected() ) { | |
session.doWork( new RollbackWork() ); | |
} | |
session.close(); | |
} | |
session = null; | |
} | |
public class RollbackWork implements Work { | |
public void execute(Connection connection) throws SQLException { | |
connection.rollback(); | |
} | |
} | |
protected void cleanupTest() throws Exception { | |
} | |
@SuppressWarnings( {"UnnecessaryBoxing", "UnnecessaryUnboxing"}) | |
protected void assertAllDataRemoved() { | |
if ( !createSchema() ) { | |
return; // no tables were created... | |
} | |
if ( !Boolean.getBoolean( VALIDATE_DATA_CLEANUP ) ) { | |
return; | |
} | |
Session tmpSession = sessionFactory.openSession(); | |
try { | |
List list = tmpSession.createQuery( "select o from java.lang.Object o" ).list(); | |
Map<String,Integer> items = new HashMap<String,Integer>(); | |
if ( !list.isEmpty() ) { | |
for ( Object element : list ) { | |
Integer l = items.get( tmpSession.getEntityName( element ) ); | |
if ( l == null ) { | |
l = 0; | |
} | |
l = l + 1 ; | |
items.put( tmpSession.getEntityName( element ), l ); | |
System.out.println( "Data left: " + element ); | |
} | |
fail( "Data is left in the database: " + items.toString() ); | |
} | |
} | |
finally { | |
try { | |
tmpSession.close(); | |
} | |
catch( Throwable t ) { | |
// intentionally empty | |
} | |
} | |
} | |
protected boolean readCommittedIsolationMaintained(String scenario) { | |
int isolation = java.sql.Connection.TRANSACTION_READ_UNCOMMITTED; | |
Session testSession = null; | |
try { | |
testSession = openSession(); | |
isolation = testSession.doReturningWork( | |
new AbstractReturningWork<Integer>() { | |
@Override | |
public Integer execute(Connection connection) throws SQLException { | |
return connection.getTransactionIsolation(); | |
} | |
} | |
); | |
} | |
catch( Throwable ignore ) { | |
} | |
finally { | |
if ( testSession != null ) { | |
try { | |
testSession.close(); | |
} | |
catch( Throwable ignore ) { | |
} | |
} | |
} | |
if ( isolation < java.sql.Connection.TRANSACTION_READ_COMMITTED ) { | |
SkipLog.reportSkip( "environment does not support at least read committed isolation", scenario ); | |
return false; | |
} | |
else { | |
return true; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment