From 5b0b822717f0beb3c35d1492e20e2c3330484a2d Mon Sep 17 00:00:00 2001 From: Christian Beikov Date: Thu, 18 Mar 2021 11:16:28 +0100 Subject: [PATCH] Move tests to orm/test and fix query cache stats, native query variable substitution and named query support as loader --- gradle/databases.gradle | 9 +- .../java/org/hibernate/boot/Metadata.java | 7 + .../InFlightMetadataCollectorImpl.java | 5 + .../hibernate/boot/internal/MetadataImpl.java | 5 + .../boot/spi/AbstractDelegatingMetadata.java | 5 + .../AbstractSharedSessionContract.java | 2 +- .../internal/SessionFactoryImpl.java | 16 +- ...SingleIdEntityLoaderProvidedQueryImpl.java | 27 +- .../entity/AbstractEntityPersister.java | 17 +- .../internal/NamedObjectRepositoryImpl.java | 51 +- .../QueryInterpretationCacheDisabledImpl.java | 21 +- .../QueryInterpretationCacheStandardImpl.java | 27 +- .../query/named/NamedObjectRepository.java | 8 + .../org/hibernate/query/spi/QueryEngine.java | 28 +- .../query/sql/internal/NativeQueryImpl.java | 5 +- .../query/sql/internal/SQLQueryParser.java | 261 ++++++++ .../query/sqm/internal/QuerySqmImpl.java | 20 +- .../stat/internal/QueryStatisticsImpl.java | 4 +- .../stat/internal/StatsNamedContainer.java | 6 +- ...onnectionProviderValidationConfigTest.java | 65 -- .../connection/ConnectionCreatorTest.java | 2 +- ...roviderTransactionIsolationConfigTest.java | 2 +- ...onnectionProviderValidationConfigTest.java | 60 ++ .../DriverManagerRegistrationTest.java | 6 +- .../test}/connection/PropertiesTest.java | 2 +- .../test}/graph/AbstractEntityGraphTest.java | 3 +- .../test}/graph/EntityGraphsTest.java | 3 +- .../test}/graph/GraphParsingTestEntity.java | 2 +- .../graph/GraphParsingTestSubentity.java | 2 +- ...AbstractSchemaSubstitutionFormulaTest.java | 43 +- .../CustomSqlSchemaResolvingIdentityTest.java | 39 +- .../entity/CustomSqlSchemaResolvingTest.java | 40 +- ...laTemplateEmptySchemaSubstitutionTest.java | 5 +- ...FormulaTemplateSchemaSubstitutionTest.java | 34 ++ .../entity/JoinFormulaImplicitJoinTest.java | 46 +- .../internal/ProcedureCallImplTest.java | 34 ++ .../property/BasicPropertyAccessorTest.java | 2 +- .../property/DirectPropertyAccessorTest.java | 52 ++ .../property/GetAndIsVariantGetterTest.java | 2 +- ...iantGetterWithTransientAnnotationTest.java | 38 +- .../{ => orm/test}/property/Item.java | 2 +- .../{ => orm/test}/property/Order.java | 2 +- .../PropertyAccessStrategyMapTest.java | 2 +- .../access/spi/GetterFieldImplTest.java | 20 +- .../test}/secure/JaccIntegratorTest.java | 47 +- .../EntityProxySerializationTest.java | 576 ++++++++---------- .../GetterSetterSerializationTest.java | 7 +- .../MapProxySerializationTest.java | 424 ++++++------- .../SessionFactorySerializationTest.java | 2 +- .../test}/serialization/entity/AnEntity.java | 2 +- .../test}/serialization/entity/PK.java | 2 +- .../test}/service/ServiceContributorTest.java | 2 +- .../test}/service/ServiceRegistryTest.java | 5 +- .../ServiceRegistryClosingCascadeTest.java | 2 +- .../AssociateEntityWithTwoSessionsTest.java | 33 +- .../SessionWithSharedConnectionTest.java | 133 ++-- .../ConcurrentQueryStatisticsTest.java | 4 +- .../internal/ConcurrentStatisticsTest.java | 45 ++ .../QueryPlanCacheStatisticsTest.java | 101 ++- ...tsNamedContainerNullComputedValueTest.java | 4 +- ...FormulaTemplateSchemaSubstitutionTest.java | 45 -- .../internal/ProcedureCallImplTest.java | 39 -- .../property/DirectPropertyAccessorTest.java | 55 -- .../internal/ConcurrentStatisticsTest.java | 59 -- .../serialization/DynamicMapMappings.hbm.xml | 66 +- .../org/hibernate/property/TheEntity.hbm.xml | 2 +- hibernate-testing/hibernate-testing.gradle | 5 - .../BasicEntityManagerFactoryScopeTests.java | 14 +- .../BasicSessionFactoryScopeTests.java | 7 +- .../src/test/resources/hibernate.properties | 27 + 70 files changed, 1467 insertions(+), 1273 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/query/sql/internal/SQLQueryParser.java delete mode 100644 hibernate-core/src/test/java/org/hibernate/connection/DriverManagerConnectionProviderValidationConfigTest.java rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/connection/ConnectionCreatorTest.java (98%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/connection/DriverManagerConnectionProviderTransactionIsolationConfigTest.java (96%) create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/connection/DriverManagerConnectionProviderValidationConfigTest.java rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/connection/DriverManagerRegistrationTest.java (94%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/connection/PropertiesTest.java (97%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/graph/AbstractEntityGraphTest.java (97%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/graph/EntityGraphsTest.java (99%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/graph/GraphParsingTestEntity.java (97%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/graph/GraphParsingTestSubentity.java (88%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/persister/entity/AbstractSchemaSubstitutionFormulaTest.java (73%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/persister/entity/CustomSqlSchemaResolvingIdentityTest.java (74%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/persister/entity/CustomSqlSchemaResolvingTest.java (74%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/persister/entity/FormulaTemplateEmptySchemaSubstitutionTest.java (88%) create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/persister/entity/FormulaTemplateSchemaSubstitutionTest.java rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/persister/entity/JoinFormulaImplicitJoinTest.java (80%) create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/procedure/internal/ProcedureCallImplTest.java rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/property/BasicPropertyAccessorTest.java (98%) create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/property/DirectPropertyAccessorTest.java rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/property/GetAndIsVariantGetterTest.java (99%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/property/GetAndIsVariantGetterWithTransientAnnotationTest.java (75%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/property/Item.java (93%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/property/Order.java (96%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/property/PropertyAccessStrategyMapTest.java (97%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/property/access/spi/GetterFieldImplTest.java (55%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/secure/JaccIntegratorTest.java (77%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/serialization/EntityProxySerializationTest.java (64%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/serialization/GetterSetterSerializationTest.java (96%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/serialization/MapProxySerializationTest.java (58%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/serialization/SessionFactorySerializationTest.java (98%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/serialization/entity/AnEntity.java (92%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/serialization/entity/PK.java (93%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/service/ServiceContributorTest.java (98%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/service/ServiceRegistryTest.java (97%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/service/internal/ServiceRegistryClosingCascadeTest.java (96%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/session/AssociateEntityWithTwoSessionsTest.java (78%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/sharedSession/SessionWithSharedConnectionTest.java (71%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/stat/internal/ConcurrentQueryStatisticsTest.java (92%) create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/stat/internal/ConcurrentStatisticsTest.java rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/stat/internal/QueryPlanCacheStatisticsTest.java (81%) rename hibernate-core/src/test/java/org/hibernate/{ => orm/test}/stat/internal/StatsNamedContainerNullComputedValueTest.java (87%) delete mode 100644 hibernate-core/src/test/java/org/hibernate/persister/entity/FormulaTemplateSchemaSubstitutionTest.java delete mode 100644 hibernate-core/src/test/java/org/hibernate/procedure/internal/ProcedureCallImplTest.java delete mode 100644 hibernate-core/src/test/java/org/hibernate/property/DirectPropertyAccessorTest.java delete mode 100644 hibernate-core/src/test/java/org/hibernate/stat/internal/ConcurrentStatisticsTest.java rename hibernate-core/src/test/resources/org/hibernate/{ => orm}/test/serialization/DynamicMapMappings.hbm.xml (96%) create mode 100644 hibernate-testing/src/test/resources/hibernate.properties diff --git a/gradle/databases.gradle b/gradle/databases.gradle index 9c902cbfce..bcd01909ae 100644 --- a/gradle/databases.gradle +++ b/gradle/databases.gradle @@ -50,20 +50,13 @@ ext { 'jdbc.url' : 'jdbc:postgresql://127.0.0.1/hibernate_orm_test?preparedStatementCacheQueries=0' ], pgsql_ci : [ - 'db.dialect' : 'org.hibernate.dialect.PostgreSQL95Dialect', + 'db.dialect' : 'org.hibernate.dialect.PostgreSQLDialect', 'jdbc.driver': 'org.postgresql.Driver', 'jdbc.user' : 'hibernate_orm_test', 'jdbc.pass' : 'hibernate_orm_test', // Disable prepared statement caching due to https://www.postgresql.org/message-id/CAEcMXhmmRd4-%2BNQbnjDT26XNdUoXdmntV9zdr8%3DTu8PL9aVCYg%40mail.gmail.com 'jdbc.url' : 'jdbc:postgresql://' + dbHost + '/hibernate_orm_test?preparedStatementCacheQueries=0' ], - pgsql_ci : [ - 'db.dialect' : 'org.hibernate.dialect.PostgreSQLDialect', - 'jdbc.driver': 'org.postgresql.Driver', - 'jdbc.user' : 'hibernate_orm_test', - 'jdbc.pass' : 'hibernate_orm_test', - 'jdbc.url' : 'jdbc:postgresql://' + dbHost + '/hibernate_orm_test' - ], mysql : [ 'db.dialect' : 'org.hibernate.dialect.MySQLDialect', 'jdbc.driver': 'com.mysql.jdbc.Driver', diff --git a/hibernate-core/src/main/java/org/hibernate/boot/Metadata.java b/hibernate-core/src/main/java/org/hibernate/boot/Metadata.java index df90ee8931..664b9f3cb4 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/Metadata.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/Metadata.java @@ -136,6 +136,13 @@ public interface Metadata extends Mapping { */ void visitNamedNativeQueryDefinitions(Consumer definitionConsumer); + /** + * Retrieve named procedure metadata. + * + * @return The named procedure metadata, or {@code null} + */ + NamedProcedureCallDefinition getNamedProcedureCallMapping(String name); + /** * Visit all named callable query definitions */ diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java index 49c540c228..cdd0cb57ff 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java @@ -634,6 +634,11 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector // Named stored-procedure handling + @Override + public NamedProcedureCallDefinition getNamedProcedureCallMapping(String name) { + return namedProcedureCallMap.get( name ); + } + @Override public void visitNamedProcedureCallDefinition(Consumer definitionConsumer) { namedProcedureCallMap.values().forEach( definitionConsumer ); diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/MetadataImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/MetadataImpl.java index 639b3993a8..7d3a094791 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/internal/MetadataImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/MetadataImpl.java @@ -251,6 +251,11 @@ public class MetadataImpl implements MetadataImplementor, Serializable { namedNativeQueryMap.values().forEach( definitionConsumer ); } + @Override + public NamedProcedureCallDefinition getNamedProcedureCallMapping(String name) { + return namedProcedureCallMap.get( name ); + } + @Override public void visitNamedProcedureCallDefinition(Consumer definitionConsumer) { namedProcedureCallMap.values().forEach( definitionConsumer ); diff --git a/hibernate-core/src/main/java/org/hibernate/boot/spi/AbstractDelegatingMetadata.java b/hibernate-core/src/main/java/org/hibernate/boot/spi/AbstractDelegatingMetadata.java index 70c267bf3c..fe7f9b3ecb 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/spi/AbstractDelegatingMetadata.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/spi/AbstractDelegatingMetadata.java @@ -139,6 +139,11 @@ public abstract class AbstractDelegatingMetadata implements MetadataImplementor delegate.visitNamedNativeQueryDefinitions( definitionConsumer ); } + @Override + public NamedProcedureCallDefinition getNamedProcedureCallMapping(String name) { + return delegate.getNamedProcedureCallMapping( name ); + } + @Override public void visitNamedProcedureCallDefinition(Consumer definitionConsumer) { delegate.visitNamedProcedureCallDefinition( definitionConsumer ); diff --git a/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java b/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java index 5af009c9cc..cf266dbf42 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java @@ -795,7 +795,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont if ( namedHqlDescriptor != null ) { HqlQueryImplementor query = namedHqlDescriptor.toQuery( this, resultType ); - query.setComment( "dynamic native SQL query" ); + query.setComment( "dynamic HQL query" ); applyQuerySettingsAndHints( query ); return query; } diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java index 5d6e312975..68afb4501f 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java @@ -111,6 +111,7 @@ import org.hibernate.persister.entity.Loadable; import org.hibernate.procedure.spi.ProcedureCallImplementor; import org.hibernate.proxy.EntityNotFoundDelegate; import org.hibernate.proxy.HibernateProxyHelper; +import org.hibernate.query.QueryLogging; import org.hibernate.query.hql.spi.HqlQueryImplementor; import org.hibernate.query.spi.QueryEngine; import org.hibernate.query.spi.QueryImplementor; @@ -312,7 +313,18 @@ public class SessionFactoryImpl implements SessionFactoryImplementor { this.queryEngine.prepare( this, bootMetamodel, bootstrapContext ); if ( options.isNamedQueryStartupCheckingEnabled() ) { - queryEngine.getNamedObjectRepository().checkNamedQueries( queryEngine ); + final Map errors = queryEngine.getNamedObjectRepository().checkNamedQueries( queryEngine ); + + if ( !errors.isEmpty() ) { + StringBuilder failingQueries = new StringBuilder( "Errors in named queries: " ); + String sep = ""; + for ( Map.Entry entry : errors.entrySet() ) { + QueryLogging.QUERY_MESSAGE_LOGGER.namedQueryError( entry.getKey(), entry.getValue() ); + failingQueries.append( sep ).append( entry.getKey() ); + sep = ", "; + } + throw new HibernateException( failingQueries.toString() ); + } } SchemaManagementToolCoordinator.process( @@ -814,7 +826,7 @@ public class SessionFactoryImpl implements SessionFactoryImplementor { cacheAccess.close(); } - if ( runtimeMetamodels != null ) { + if ( runtimeMetamodels != null && runtimeMetamodels.getMappingMetamodel() != null ) { final JdbcConnectionAccess jdbcConnectionAccess = jdbcServices.getBootstrapJdbcConnectionAccess(); runtimeMetamodels.getMappingMetamodel().visitEntityDescriptors( entityPersister -> { diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SingleIdEntityLoaderProvidedQueryImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SingleIdEntityLoaderProvidedQueryImpl.java index b770f24000..cc9df8b2c8 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SingleIdEntityLoaderProvidedQueryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SingleIdEntityLoaderProvidedQueryImpl.java @@ -7,15 +7,12 @@ package org.hibernate.loader.ast.internal; import org.hibernate.LockOptions; -import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.loader.ast.spi.SingleIdEntityLoader; import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.query.named.NamedQueryMemento; -import org.hibernate.query.named.NamedObjectRepository; import org.hibernate.query.spi.QueryImplementor; -import org.hibernate.query.sql.spi.NamedNativeQueryMemento; /** * Implementation of SingleIdEntityLoader for cases where the application has @@ -29,27 +26,9 @@ public class SingleIdEntityLoaderProvidedQueryImpl implements SingleIdEntityL public SingleIdEntityLoaderProvidedQueryImpl( EntityMappingType entityDescriptor, - String loadQueryName, - SessionFactoryImplementor sessionFactory) { + NamedQueryMemento namedQueryMemento) { this.entityDescriptor = entityDescriptor; - - this.namedQueryMemento = resolveNamedQuery( loadQueryName, sessionFactory ); - if ( namedQueryMemento == null ) { - throw new IllegalArgumentException( "Could not resolve named load-query [" + entityDescriptor.getEntityName() + "] : " + loadQueryName ); - } - } - - private static NamedQueryMemento resolveNamedQuery( - String queryName, - SessionFactoryImplementor sf) { - final NamedObjectRepository namedObjectRepository = sf.getQueryEngine().getNamedObjectRepository(); - - final NamedNativeQueryMemento nativeQueryMemento = namedObjectRepository.getNativeQueryMemento( queryName ); - if ( nativeQueryMemento != null ) { - return nativeQueryMemento; - } - - return namedObjectRepository.getHqlQueryMemento( queryName ); + this.namedQueryMemento = namedQueryMemento; } @Override @@ -65,7 +44,7 @@ public class SingleIdEntityLoaderProvidedQueryImpl implements SingleIdEntityL entityDescriptor.getMappedJavaTypeDescriptor().getJavaTypeClass() ); - query.setParameter( 0, pkValue ); + query.setParameter( 1, pkValue ); return query.uniqueResult(); } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index 8157248bdb..29d6e02a2e 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -135,6 +135,7 @@ import org.hibernate.mapping.BasicValue; import org.hibernate.mapping.Column; import org.hibernate.mapping.Component; import org.hibernate.mapping.DependantValue; +import org.hibernate.mapping.Formula; import org.hibernate.mapping.IndexedConsumer; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; @@ -188,6 +189,8 @@ import org.hibernate.property.access.spi.PropertyAccess; import org.hibernate.property.access.spi.Setter; import org.hibernate.query.ComparisonOperator; import org.hibernate.query.NavigablePath; +import org.hibernate.query.named.NamedQueryMemento; +import org.hibernate.query.sql.internal.SQLQueryParser; import org.hibernate.query.sqm.mutation.internal.SqmMutationStrategyHelper; import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy; import org.hibernate.sql.Alias; @@ -748,10 +751,15 @@ public abstract class AbstractEntityPersister rowIdName = bootDescriptor.getRootTable().getRowId(); if ( bootDescriptor.getLoaderName() != null ) { + // We must resolve the named query on-demand through the boot model because it isn't initialized yet + final NamedQueryMemento namedQueryMemento = factory.getQueryEngine().getNamedObjectRepository() + .resolve( factory, creationContext.getBootModel(), bootDescriptor.getLoaderName() ); + if ( namedQueryMemento == null ) { + throw new IllegalArgumentException( "Could not resolve named load-query [" + getEntityName() + "] : " + bootDescriptor.getLoaderName() ); + } singleIdEntityLoader = new SingleIdEntityLoaderProvidedQueryImpl( this, - bootDescriptor.getLoaderName(), - factory + namedQueryMemento ); } else if ( batchSize > 1 ) { @@ -849,8 +857,7 @@ public abstract class AbstractEntityPersister colAliases[k] = thing.getAlias( dialect, prop.getValue().getTable() ); if ( thing.isFormula() ) { foundFormula = true; - // ( (Formula) thing ).setFormula( substituteBrackets( ( (Formula) thing ).getFormula() ) ); - // TODO: uncomment the above statement when this#substituteBrackets(String) is implemented + ( (Formula) thing ).setFormula( substituteBrackets( ( (Formula) thing ).getFormula() ) ); formulaTemplates[k] = thing.getTemplate( dialect, factory.getQueryEngine().getSqmFunctionRegistry() ); } else { @@ -4562,7 +4569,7 @@ public abstract class AbstractEntityPersister } private String substituteBrackets(String sql) { - throw new NotYetImplementedFor6Exception( getClass() ); + return new SQLQueryParser( sql, null, getFactory() ).process(); } public final void postInstantiate() throws MappingException { diff --git a/hibernate-core/src/main/java/org/hibernate/query/internal/NamedObjectRepositoryImpl.java b/hibernate-core/src/main/java/org/hibernate/query/internal/NamedObjectRepositoryImpl.java index 43674971d5..5ea1073708 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/internal/NamedObjectRepositoryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/internal/NamedObjectRepositoryImpl.java @@ -11,6 +11,9 @@ import java.util.Map; import java.util.function.Consumer; import org.hibernate.HibernateException; +import org.hibernate.boot.query.NamedHqlQueryDefinition; +import org.hibernate.boot.query.NamedNativeQueryDefinition; +import org.hibernate.boot.query.NamedProcedureCallDefinition; import org.hibernate.boot.spi.BootstrapContext; import org.hibernate.boot.spi.MetadataImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor; @@ -18,6 +21,7 @@ import org.hibernate.procedure.spi.NamedCallableQueryMemento; import org.hibernate.query.hql.HqlTranslator; import org.hibernate.query.hql.spi.NamedHqlQueryMemento; import org.hibernate.query.named.NamedObjectRepository; +import org.hibernate.query.named.NamedQueryMemento; import org.hibernate.query.named.NamedResultSetMappingMemento; import org.hibernate.query.spi.QueryEngine; import org.hibernate.query.spi.QueryInterpretationCache; @@ -127,6 +131,44 @@ public class NamedObjectRepositoryImpl implements NamedObjectRepository { // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Prepare repository for use + @Override + public NamedQueryMemento resolve( + SessionFactoryImplementor sessionFactory, + MetadataImplementor bootMetamodel, + String registrationName) { + NamedQueryMemento namedQuery = hqlMementoMap.get( registrationName ); + if ( namedQuery != null ) { + return namedQuery; + } + namedQuery = sqlMementoMap.get( registrationName ); + if ( namedQuery != null ) { + return namedQuery; + } + namedQuery = callableMementoMap.get( registrationName ); + if ( namedQuery != null ) { + return namedQuery; + } + final NamedHqlQueryDefinition namedHqlQueryDefinition = bootMetamodel.getNamedHqlQueryMapping( registrationName ); + if ( namedHqlQueryDefinition != null ) { + final NamedHqlQueryMemento resolved = namedHqlQueryDefinition.resolve( sessionFactory ); + hqlMementoMap.put( namedHqlQueryDefinition.getRegistrationName(), resolved ); + return resolved; + } + final NamedNativeQueryDefinition namedNativeQueryDefinition = bootMetamodel.getNamedNativeQueryMapping( registrationName ); + if ( namedNativeQueryDefinition != null ) { + final NamedNativeQueryMemento resolved = namedNativeQueryDefinition.resolve( sessionFactory ); + sqlMementoMap.put( namedNativeQueryDefinition.getRegistrationName(), resolved ); + return resolved; + } + final NamedProcedureCallDefinition namedCallableQueryDefinition = bootMetamodel.getNamedProcedureCallMapping( registrationName ); + if ( namedCallableQueryDefinition != null ) { + final NamedCallableQueryMemento resolved = namedCallableQueryDefinition.resolve( sessionFactory ); + callableMementoMap.put( namedCallableQueryDefinition.getRegistrationName(), resolved ); + return resolved; + } + return null; + } + @Override public void prepare( SessionFactoryImplementor sessionFactory, @@ -184,10 +226,11 @@ public class NamedObjectRepositoryImpl implements NamedObjectRepository { for ( NamedHqlQueryMemento hqlMemento : hqlMementoMap.values() ) { try { log.debugf( "Checking named HQL query: %s", hqlMemento.getRegistrationName() ); - hqlMemento.validate( queryEngine ); - - // todo (6.0) : need to cache these; however atm that requires producing a SqmQueryImpl - // queryEngine.getQueryInterpretationCache().getHQLQueryPlan( hqlMemento.getQueryString(), false, Collections.EMPTY_MAP ); + String queryString = hqlMemento.getHqlString(); + interpretationCache.resolveHqlInterpretation( + queryString, + s -> queryEngine.getHqlTranslator().translate( queryString ) + ); } catch ( HibernateException e ) { errors.put( hqlMemento.getRegistrationName(), e ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/internal/QueryInterpretationCacheDisabledImpl.java b/hibernate-core/src/main/java/org/hibernate/query/internal/QueryInterpretationCacheDisabledImpl.java index a9714e0fb9..a566bd235e 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/internal/QueryInterpretationCacheDisabledImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/internal/QueryInterpretationCacheDisabledImpl.java @@ -6,6 +6,7 @@ */ package org.hibernate.query.internal; +import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.function.Supplier; @@ -17,15 +18,18 @@ import org.hibernate.query.spi.SelectQueryPlan; import org.hibernate.query.sql.spi.ParameterInterpretation; import org.hibernate.query.sqm.internal.DomainParameterXref; import org.hibernate.query.sqm.tree.SqmStatement; +import org.hibernate.stat.spi.StatisticsImplementor; /** * @author Steve Ebersole */ public class QueryInterpretationCacheDisabledImpl implements QueryInterpretationCache { - /** - * Singleton access - */ - public static final QueryInterpretationCacheDisabledImpl INSTANCE = new QueryInterpretationCacheDisabledImpl(); + + private final Supplier statisticsSupplier; + + public QueryInterpretationCacheDisabledImpl(Supplier statisticsSupplier) { + this.statisticsSupplier = statisticsSupplier; + } @Override public int getNumberOfCachedHqlInterpretations() { @@ -53,6 +57,9 @@ public class QueryInterpretationCacheDisabledImpl implements QueryInterpretation @Override public HqlInterpretation resolveHqlInterpretation(String queryString, Function> creator) { + StatisticsImplementor statistics = statisticsSupplier.get(); + final boolean stats = statistics.isStatisticsEnabled(); + final long startTime = ( stats ) ? System.nanoTime() : 0L; final SqmStatement sqmStatement = creator.apply( queryString ); final DomainParameterXref domainParameterXref; @@ -66,6 +73,12 @@ public class QueryInterpretationCacheDisabledImpl implements QueryInterpretation parameterMetadata = new ParameterMetadataImpl( domainParameterXref.getQueryParameters() ); } + if ( stats ) { + final long endTime = System.nanoTime(); + final long microseconds = TimeUnit.MICROSECONDS.convert( endTime - startTime, TimeUnit.NANOSECONDS ); + statistics.queryCompiled( queryString, microseconds ); + } + return new HqlInterpretation() { @Override public SqmStatement getSqmStatement() { diff --git a/hibernate-core/src/main/java/org/hibernate/query/internal/QueryInterpretationCacheStandardImpl.java b/hibernate-core/src/main/java/org/hibernate/query/internal/QueryInterpretationCacheStandardImpl.java index cc955b9271..7ae94b9206 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/internal/QueryInterpretationCacheStandardImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/internal/QueryInterpretationCacheStandardImpl.java @@ -6,6 +6,7 @@ */ package org.hibernate.query.internal; +import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.function.Supplier; @@ -21,6 +22,7 @@ import org.hibernate.query.spi.SimpleHqlInterpretationImpl; import org.hibernate.query.sql.spi.ParameterInterpretation; import org.hibernate.query.sqm.internal.DomainParameterXref; import org.hibernate.query.sqm.tree.SqmStatement; +import org.hibernate.stat.spi.StatisticsImplementor; import org.jboss.logging.Logger; @@ -52,13 +54,15 @@ public class QueryInterpretationCacheStandardImpl implements QueryInterpretation private final BoundedConcurrentHashMap hqlInterpretationCache; private final BoundedConcurrentHashMap nativeQueryParamCache; + private final Supplier statisticsSupplier; - public QueryInterpretationCacheStandardImpl(int maxQueryPlanCount) { + public QueryInterpretationCacheStandardImpl(int maxQueryPlanCount, Supplier statisticsSupplier) { log.debugf( "Starting QueryPlanCache(%s)", maxQueryPlanCount ); - queryPlanCache = new BoundedConcurrentHashMap<>( maxQueryPlanCount, 20, BoundedConcurrentHashMap.Eviction.LIRS ); - hqlInterpretationCache = new BoundedConcurrentHashMap<>( maxQueryPlanCount, 20, BoundedConcurrentHashMap.Eviction.LIRS ); - nativeQueryParamCache = new BoundedConcurrentHashMap<>( maxQueryPlanCount, 20, BoundedConcurrentHashMap.Eviction.LIRS ); + this.queryPlanCache = new BoundedConcurrentHashMap<>( maxQueryPlanCount, 20, BoundedConcurrentHashMap.Eviction.LIRS ); + this.hqlInterpretationCache = new BoundedConcurrentHashMap<>( maxQueryPlanCount, 20, BoundedConcurrentHashMap.Eviction.LIRS ); + this.nativeQueryParamCache = new BoundedConcurrentHashMap<>( maxQueryPlanCount, 20, BoundedConcurrentHashMap.Eviction.LIRS ); + this.statisticsSupplier = statisticsSupplier; } @Override @@ -103,9 +107,14 @@ public class QueryInterpretationCacheStandardImpl implements QueryInterpretation String queryString, Function> creator) { log.tracef( "QueryPlan#resolveHqlInterpretation( `%s` )", queryString ); - + final StatisticsImplementor statistics = statisticsSupplier.get(); + final boolean stats = statistics.isStatisticsEnabled(); + final long startTime = ( stats ) ? System.nanoTime() : 0L; final HqlInterpretation cached = hqlInterpretationCache.get( queryString ); if ( cached != null ) { + if ( stats ) { + statistics.queryPlanCacheHit( queryString ); + } return cached; } @@ -129,6 +138,12 @@ public class QueryInterpretationCacheStandardImpl implements QueryInterpretation parameterMetadata, domainParameterXref); hqlInterpretationCache.put( queryString, interpretation ); + + if ( stats ) { + final long endTime = System.nanoTime(); + final long microseconds = TimeUnit.MICROSECONDS.convert( endTime - startTime, TimeUnit.NANOSECONDS ); + statistics.queryCompiled( queryString, microseconds ); + } return interpretation; } @@ -155,6 +170,8 @@ public class QueryInterpretationCacheStandardImpl implements QueryInterpretation @Override public void close() { // todo (6.0) : clear maps/caches and LOG + hqlInterpretationCache.clear(); + nativeQueryParamCache.clear(); queryPlanCache.clear(); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/named/NamedObjectRepository.java b/hibernate-core/src/main/java/org/hibernate/query/named/NamedObjectRepository.java index e70959a02d..bfe7a68589 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/named/NamedObjectRepository.java +++ b/hibernate-core/src/main/java/org/hibernate/query/named/NamedObjectRepository.java @@ -69,6 +69,14 @@ public interface NamedObjectRepository { */ Map checkNamedQueries(QueryEngine queryPlanCache); + /** + * Resolve the named query with the given name. + */ + NamedQueryMemento resolve( + SessionFactoryImplementor sessionFactory, + MetadataImplementor bootMetamodel, + String registrationName); + /** * Prepare for runtime use */ diff --git a/hibernate-core/src/main/java/org/hibernate/query/spi/QueryEngine.java b/hibernate-core/src/main/java/org/hibernate/query/spi/QueryEngine.java index a6f4f7d991..5256f35f52 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/spi/QueryEngine.java +++ b/hibernate-core/src/main/java/org/hibernate/query/spi/QueryEngine.java @@ -6,7 +6,6 @@ */ package org.hibernate.query.spi; -import org.hibernate.HibernateException; import org.hibernate.Incubating; import org.hibernate.boot.spi.BootstrapContext; import org.hibernate.boot.spi.MetadataImplementor; @@ -18,7 +17,6 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.CoreLogging; import org.hibernate.internal.util.config.ConfigurationHelper; import org.hibernate.metamodel.model.domain.JpaMetamodel; -import org.hibernate.query.QueryLogging; import org.hibernate.query.criteria.ValueHandlingMode; import org.hibernate.query.hql.HqlTranslator; import org.hibernate.query.hql.internal.StandardHqlTranslator; @@ -34,6 +32,7 @@ import org.hibernate.query.sqm.spi.SqmCreationContext; import org.hibernate.query.sqm.sql.SqmTranslatorFactory; import org.hibernate.query.sqm.sql.StandardSqmTranslatorFactory; import org.hibernate.service.ServiceRegistry; +import org.hibernate.stat.spi.StatisticsImplementor; import java.util.Map; import java.util.function.Supplier; @@ -75,7 +74,7 @@ public class QueryEngine { hqlTranslator, sqmTranslatorFactory, sessionFactory.getServiceRegistry().getService( NativeQueryInterpreter.class ), - buildInterpretationCache( sessionFactory.getProperties() ), + buildInterpretationCache( sessionFactory::getStatistics, sessionFactory.getProperties() ), dialect, queryEngineOptions.getCustomSqmFunctionRegistry(), sessionFactory.getServiceRegistry() @@ -196,6 +195,7 @@ public class QueryEngine { ); this.interpretationCache = buildInterpretationCache( + () -> serviceRegistry.getService( StatisticsImplementor.class ), serviceRegistry.getService( ConfigurationService.class ).getSettings() ); } @@ -275,7 +275,7 @@ public class QueryEngine { return new StandardSqmTranslatorFactory(); } - private static QueryInterpretationCache buildInterpretationCache(Map properties) { + private static QueryInterpretationCache buildInterpretationCache(Supplier statisticsSupplier, Map properties) { final boolean explicitUseCache = ConfigurationHelper.getBoolean( AvailableSettings.QUERY_PLAN_CACHE_ENABLED, properties, @@ -293,11 +293,11 @@ public class QueryEngine { ? explicitMaxPlanSize : QueryInterpretationCacheStandardImpl.DEFAULT_QUERY_PLAN_MAX_COUNT; - return new QueryInterpretationCacheStandardImpl( size ); + return new QueryInterpretationCacheStandardImpl( size, statisticsSupplier ); } else { // disabled - return QueryInterpretationCacheDisabledImpl.INSTANCE; + return new QueryInterpretationCacheDisabledImpl( statisticsSupplier ); } } @@ -306,22 +306,6 @@ public class QueryEngine { MetadataImplementor bootMetamodel, BootstrapContext bootstrapContext) { namedObjectRepository.prepare( sessionFactory, bootMetamodel, bootstrapContext ); - - //checking for named queries - if ( sessionFactory.getSessionFactoryOptions().isNamedQueryStartupCheckingEnabled() ) { - final Map errors = namedObjectRepository.checkNamedQueries( this ); - - if ( !errors.isEmpty() ) { - StringBuilder failingQueries = new StringBuilder( "Errors in named queries: " ); - String sep = ""; - for ( Map.Entry entry : errors.entrySet() ) { - QueryLogging.QUERY_MESSAGE_LOGGER.namedQueryError( entry.getKey(), entry.getValue() ); - failingQueries.append( sep ).append( entry.getKey() ); - sep = ", "; - } - throw new HibernateException( failingQueries.toString() ); - } - } } public NamedObjectRepository getNamedObjectRepository() { diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java index a7d0f3bb0f..f60e3c8318 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java @@ -289,12 +289,13 @@ public class NativeQueryImpl sqlString, s -> { final ParameterRecognizerImpl parameterRecognizer = new ParameterRecognizerImpl( session.getFactory() ); + final String sql = new SQLQueryParser( sqlString, null, session.getFactory() ).process(); session.getFactory().getServiceRegistry() .getService( NativeQueryInterpreter.class ) - .recognizeParameters( sqlString, parameterRecognizer ); + .recognizeParameters( sql, parameterRecognizer ); - return new ParameterInterpretationImpl( sqlString, parameterRecognizer ); + return new ParameterInterpretationImpl( sql, parameterRecognizer ); } ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/SQLQueryParser.java b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/SQLQueryParser.java new file mode 100644 index 0000000000..c799f9e038 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/SQLQueryParser.java @@ -0,0 +1,261 @@ +/* + * 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 . + */ +package org.hibernate.query.sql.internal; + +import java.util.Map; +import java.util.regex.Pattern; + +import org.hibernate.QueryException; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.collection.SQLLoadableCollection; +import org.hibernate.persister.entity.SQLLoadable; + +/** + * @author Gavin King + * @author Max Andersen + * @author Steve Ebersole + * @author Paul Benedict + */ +public class SQLQueryParser { + private static final Pattern PREPARED_STATEMENT_PATTERN = Pattern.compile( "^\\{.*?\\}$" ); + private static final String HIBERNATE_PLACEHOLDER_PREFIX = "h-"; + private static final String DOMAIN_PLACEHOLDER = "h-domain"; + private static final String CATALOG_PLACEHOLDER = "h-catalog"; + private static final String SCHEMA_PLACEHOLDER = "h-schema"; + + private final SessionFactoryImplementor factory; + private final String originalQueryString; + private final ParserContext context; + + private long aliasesFound; + + interface ParserContext { + boolean isEntityAlias(String aliasName); + SQLLoadable getEntityPersisterByAlias(String alias); + String getEntitySuffixByAlias(String alias); + boolean isCollectionAlias(String aliasName); + SQLLoadableCollection getCollectionPersisterByAlias(String alias); + String getCollectionSuffixByAlias(String alias); + Map getPropertyResultsMapByAlias(String alias); + } + + public SQLQueryParser(String queryString, ParserContext context, SessionFactoryImplementor factory) { + this.originalQueryString = queryString; + this.context = context; + this.factory = factory; + } + + public boolean queryHasAliases() { + return aliasesFound>0; + } + + protected String getOriginalQueryString() { + return originalQueryString; + } + + public String process() { + return substituteBrackets( originalQueryString ); + } + + // TODO: should "record" how many properties we have referred to - and if we + // don't get them all we throw an exception! Way better than trial and error ;) + protected String substituteBrackets(String sqlQuery) throws QueryException { + + if ( PREPARED_STATEMENT_PATTERN.matcher( sqlQuery.trim() ).matches() ) { + return sqlQuery; + } + + StringBuilder result = new StringBuilder( sqlQuery.length() + 20 ); + int left, right; + + // replace {....} with corresponding column aliases + for ( int curr = 0; curr < sqlQuery.length(); curr = right + 1 ) { + if ( ( left = sqlQuery.indexOf( '{', curr ) ) < 0 ) { + // No additional open braces found in the string, append the + // rest of the string in its entirety and quit this loop + result.append( sqlQuery.substring( curr ) ); + break; + } + + // append everything up until the next encountered open brace + result.append( sqlQuery.substring( curr, left ) ); + + if ( ( right = sqlQuery.indexOf( '}', left + 1 ) ) < 0 ) { + throw new QueryException( "Unmatched braces for alias path", sqlQuery ); + } + + final String aliasPath = sqlQuery.substring( left + 1, right ); + boolean isPlaceholder = aliasPath.startsWith( HIBERNATE_PLACEHOLDER_PREFIX ); + + if ( isPlaceholder ) { + // Domain replacement + if ( DOMAIN_PLACEHOLDER.equals( aliasPath ) ) { + final String catalogName = factory.getSettings().getDefaultCatalogName(); + if ( catalogName != null ) { + result.append( catalogName ); + result.append( "." ); + } + final String schemaName = factory.getSettings().getDefaultSchemaName(); + if ( schemaName != null ) { + result.append( schemaName ); + result.append( "." ); + } + } + // Schema replacement + else if ( SCHEMA_PLACEHOLDER.equals( aliasPath ) ) { + final String schemaName = factory.getSettings().getDefaultSchemaName(); + if ( schemaName != null ) { + result.append(schemaName); + result.append("."); + } + } + // Catalog replacement + else if ( CATALOG_PLACEHOLDER.equals( aliasPath ) ) { + final String catalogName = factory.getSettings().getDefaultCatalogName(); + if ( catalogName != null ) { + result.append( catalogName ); + result.append( "." ); + } + } + else { + throw new QueryException( "Unknown placeholder ", aliasPath ); + } + } + else if (context != null) { + int firstDot = aliasPath.indexOf( '.' ); + if ( firstDot == -1 ) { + if ( context.isEntityAlias( aliasPath ) ) { + // it is a simple table alias {foo} + result.append( aliasPath ); + aliasesFound++; + } + else { + // passing through anything we do not know : to support jdbc escape sequences HB-898 + result.append( '{' ).append(aliasPath).append( '}' ); + } + } + else { + final String aliasName = aliasPath.substring( 0, firstDot ); + if ( context.isCollectionAlias( aliasName ) ) { + // The current alias is referencing the collection to be eagerly fetched + String propertyName = aliasPath.substring( firstDot + 1 ); + result.append( resolveCollectionProperties( aliasName, propertyName ) ); + aliasesFound++; + } + else if ( context.isEntityAlias( aliasName ) ) { + // it is a property reference {foo.bar} + String propertyName = aliasPath.substring( firstDot + 1 ); + result.append( resolveProperties( aliasName, propertyName ) ); + aliasesFound++; + } + else { + // passing through anything we do not know : to support jdbc escape sequences HB-898 + result.append( '{' ).append(aliasPath).append( '}' ); + } + } + } + else { + result.append( '{' ).append(aliasPath).append( '}' ); + } + } + + // Possibly handle :something parameters for the query ? + + return result.toString(); + } + + private String resolveCollectionProperties( + String aliasName, + String propertyName) { + + Map fieldResults = context.getPropertyResultsMapByAlias( aliasName ); + SQLLoadableCollection collectionPersister = context.getCollectionPersisterByAlias( aliasName ); + String collectionSuffix = context.getCollectionSuffixByAlias( aliasName ); + + if ( "*".equals( propertyName ) ) { + if( !fieldResults.isEmpty() ) { + throw new QueryException("Using return-propertys together with * syntax is not supported."); + } + + String selectFragment = collectionPersister.selectFragment( aliasName, collectionSuffix ); + aliasesFound++; + return selectFragment + + ", " + + resolveProperties( aliasName, propertyName ); + } + else if ( "element.*".equals( propertyName ) ) { + return resolveProperties( aliasName, "*" ); + } + else { + String[] columnAliases; + + // Let return-properties override whatever the persister has for aliases. + columnAliases = ( String[] ) fieldResults.get(propertyName); + if ( columnAliases==null ) { + columnAliases = collectionPersister.getCollectionPropertyColumnAliases( propertyName, collectionSuffix ); + } + + if ( columnAliases == null || columnAliases.length == 0 ) { + throw new QueryException( + "No column name found for property [" + propertyName + "] for alias [" + aliasName + "]", + originalQueryString + ); + } + if ( columnAliases.length != 1 ) { + // TODO: better error message since we actually support composites if names are explicitly listed. + throw new QueryException( + "SQL queries only support properties mapped to a single column - property [" + + propertyName + "] is mapped to " + columnAliases.length + " columns.", + originalQueryString + ); + } + aliasesFound++; + return columnAliases[0]; + + } + } + private String resolveProperties(String aliasName, String propertyName) { + Map fieldResults = context.getPropertyResultsMapByAlias( aliasName ); + SQLLoadable persister = context.getEntityPersisterByAlias( aliasName ); + String suffix = context.getEntitySuffixByAlias( aliasName ); + + if ( "*".equals( propertyName ) ) { + if( !fieldResults.isEmpty() ) { + throw new QueryException("Using return-propertys together with * syntax is not supported."); + } + aliasesFound++; + return persister.selectFragment( aliasName, suffix ) ; + } + else { + + String[] columnAliases; + + // Let return-propertiess override whatever the persister has for aliases. + columnAliases = (String[]) fieldResults.get( propertyName ); + if ( columnAliases == null ) { + columnAliases = persister.getSubclassPropertyColumnAliases( propertyName, suffix ); + } + + if ( columnAliases == null || columnAliases.length == 0 ) { + throw new QueryException( + "No column name found for property [" + propertyName + "] for alias [" + aliasName + "]", + originalQueryString + ); + } + if ( columnAliases.length != 1 ) { + // TODO: better error message since we actually support composites if names are explicitly listed. + throw new QueryException( + "SQL queries only support properties mapped to a single column - property [" + propertyName + "] is mapped to " + columnAliases.length + " columns.", + originalQueryString + ); + } + aliasesFound++; + return columnAliases[0]; + } + } + +} diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/QuerySqmImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/QuerySqmImpl.java index f532305788..bc280d9931 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/QuerySqmImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/QuerySqmImpl.java @@ -45,6 +45,7 @@ import org.hibernate.query.spi.HqlInterpretation; import org.hibernate.query.spi.MutableQueryOptions; import org.hibernate.query.spi.NonSelectQueryPlan; import org.hibernate.query.spi.ParameterMetadataImplementor; +import org.hibernate.query.spi.QueryEngine; import org.hibernate.query.spi.QueryInterpretationCache; import org.hibernate.query.spi.QueryOptions; import org.hibernate.query.spi.QueryParameterBindings; @@ -110,8 +111,14 @@ public class QuerySqmImpl this.hqlString = memento.getHqlString(); final SessionFactoryImplementor factory = producer.getFactory(); + final QueryEngine queryEngine = factory.getQueryEngine(); + final QueryInterpretationCache interpretationCache = queryEngine.getInterpretationCache(); + final HqlInterpretation hqlInterpretation = interpretationCache.resolveHqlInterpretation( + hqlString, + s -> queryEngine.getHqlTranslator().translate( hqlString ) + ); - this.sqmStatement = factory.getQueryEngine().getHqlTranslator().translate( hqlString ); + this.sqmStatement = hqlInterpretation.getSqmStatement(); if ( resultType != null ) { if ( sqmStatement instanceof SqmDmlStatement ) { @@ -119,15 +126,8 @@ public class QuerySqmImpl } } this.resultType = resultType; - - if ( sqmStatement.getSqmParameters().isEmpty() ) { - this.domainParameterXref = DomainParameterXref.empty(); - this.parameterMetadata = ParameterMetadataImpl.EMPTY; - } - else { - this.domainParameterXref = DomainParameterXref.from( sqmStatement ); - this.parameterMetadata = new ParameterMetadataImpl( domainParameterXref.getQueryParameters() ); - } + this.domainParameterXref = hqlInterpretation.getDomainParameterXref(); + this.parameterMetadata = hqlInterpretation.getParameterMetadata(); this.parameterBindings = QueryParameterBindingsImpl.from( parameterMetadata, producer.getFactory() ); diff --git a/hibernate-core/src/main/java/org/hibernate/stat/internal/QueryStatisticsImpl.java b/hibernate-core/src/main/java/org/hibernate/stat/internal/QueryStatisticsImpl.java index fb78dd4975..a84ec73d04 100644 --- a/hibernate-core/src/main/java/org/hibernate/stat/internal/QueryStatisticsImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/stat/internal/QueryStatisticsImpl.java @@ -41,7 +41,7 @@ public class QueryStatisticsImpl implements QueryStatistics { private final Lock readLock; private final Lock writeLock; - QueryStatisticsImpl(String query) { + public QueryStatisticsImpl(String query) { this.query = query; ReadWriteLock lock = new ReentrantReadWriteLock(); this.readLock = lock.readLock(); @@ -159,7 +159,7 @@ public class QueryStatisticsImpl implements QueryStatistics { * @param rows rows count returned * @param time time taken */ - void executed(long rows, long time) { + public void executed(long rows, long time) { // read lock is enough, concurrent updates are supported by the underlying type AtomicLong // this only guards executed(long, long) to be called, when another thread is executing getExecutionAvgTime() readLock.lock(); diff --git a/hibernate-core/src/main/java/org/hibernate/stat/internal/StatsNamedContainer.java b/hibernate-core/src/main/java/org/hibernate/stat/internal/StatsNamedContainer.java index dcf195a056..9d3f3c79ac 100644 --- a/hibernate-core/src/main/java/org/hibernate/stat/internal/StatsNamedContainer.java +++ b/hibernate-core/src/main/java/org/hibernate/stat/internal/StatsNamedContainer.java @@ -23,21 +23,21 @@ import org.hibernate.internal.util.collections.BoundedConcurrentHashMap; * * @author Sanne Grinovero */ -final class StatsNamedContainer { +public final class StatsNamedContainer { private final ConcurrentMap map; /** * Creates a bounded container - based on BoundedConcurrentHashMap */ - StatsNamedContainer(int capacity, int concurrencyLevel) { + public StatsNamedContainer(int capacity, int concurrencyLevel) { this.map = new BoundedConcurrentHashMap( capacity, concurrencyLevel, BoundedConcurrentHashMap.Eviction.LRU ); } /** * Creates an unbounded container - based on ConcurrentHashMap */ - StatsNamedContainer() { + public StatsNamedContainer() { this.map = new ConcurrentHashMap<>( ); } diff --git a/hibernate-core/src/test/java/org/hibernate/connection/DriverManagerConnectionProviderValidationConfigTest.java b/hibernate-core/src/test/java/org/hibernate/connection/DriverManagerConnectionProviderValidationConfigTest.java deleted file mode 100644 index b33b527edb..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/connection/DriverManagerConnectionProviderValidationConfigTest.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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 . - */ -package org.hibernate.connection; - -import java.util.Map; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; - -import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl; -import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; - -import org.junit.Test; - -import static org.hibernate.testing.transaction.TransactionUtil.doInJPA; -import static org.junit.Assert.assertTrue; - -/** - * @author Vlad Mihalcea - */ -public class DriverManagerConnectionProviderValidationConfigTest extends BaseEntityManagerFunctionalTestCase { - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { - Event.class - }; - } - - @Override - protected void addConfigOptions(Map options) { - options.put( DriverManagerConnectionProviderImpl.VALIDATION_INTERVAL, 1L ); - } - - @Test - public void test() { - doInJPA( this::entityManagerFactory, entityManager -> { - Event event = new Event(); - entityManager.persist( event ); - - assertTrue( Thread.getAllStackTraces() - .keySet() - .stream() - .filter( thread -> thread.getName() - .equals( "Hibernate Connection Pool Validation Thread" ) && thread.isDaemon() ) - .map( Thread::isDaemon ) - .findAny() - .isPresent() ); - } ); - } - - @Entity(name = "Event") - public static class Event { - - @Id - @GeneratedValue - private Long id; - - private String name; - } -} \ No newline at end of file diff --git a/hibernate-core/src/test/java/org/hibernate/connection/ConnectionCreatorTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/connection/ConnectionCreatorTest.java similarity index 98% rename from hibernate-core/src/test/java/org/hibernate/connection/ConnectionCreatorTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/connection/ConnectionCreatorTest.java index 953b1bc258..087dbe4182 100644 --- a/hibernate-core/src/test/java/org/hibernate/connection/ConnectionCreatorTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/connection/ConnectionCreatorTest.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.connection; +package org.hibernate.orm.test.connection; import java.sql.Connection; import java.sql.Driver; diff --git a/hibernate-core/src/test/java/org/hibernate/connection/DriverManagerConnectionProviderTransactionIsolationConfigTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/connection/DriverManagerConnectionProviderTransactionIsolationConfigTest.java similarity index 96% rename from hibernate-core/src/test/java/org/hibernate/connection/DriverManagerConnectionProviderTransactionIsolationConfigTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/connection/DriverManagerConnectionProviderTransactionIsolationConfigTest.java index 2feec30ebe..5f61bf4fd8 100644 --- a/hibernate-core/src/test/java/org/hibernate/connection/DriverManagerConnectionProviderTransactionIsolationConfigTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/connection/DriverManagerConnectionProviderTransactionIsolationConfigTest.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.connection; +package org.hibernate.orm.test.connection; import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl; import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/connection/DriverManagerConnectionProviderValidationConfigTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/connection/DriverManagerConnectionProviderValidationConfigTest.java new file mode 100644 index 0000000000..1a7b56c251 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/connection/DriverManagerConnectionProviderValidationConfigTest.java @@ -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 . + */ +package org.hibernate.orm.test.connection; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl; + +import org.hibernate.testing.orm.junit.EntityManagerFactoryScope; +import org.hibernate.testing.orm.junit.Jpa; +import org.hibernate.testing.orm.junit.Setting; + +import org.junit.jupiter.api.Test; + +import static org.junit.Assert.assertTrue; + +/** + * @author Vlad Mihalcea + */ +@Jpa( + annotatedClasses = { DriverManagerConnectionProviderValidationConfigTest.Event.class }, + integrationSettings = @Setting(name = DriverManagerConnectionProviderImpl.VALIDATION_INTERVAL, value = "1") +) +public class DriverManagerConnectionProviderValidationConfigTest { + + @Test + public void test(EntityManagerFactoryScope scope) { + scope.inTransaction( + entityManager -> { + Event event = new Event(); + entityManager.persist( event ); + + assertTrue( Thread.getAllStackTraces() + .keySet() + .stream() + .filter( thread -> thread.getName() + .equals( "Hibernate Connection Pool Validation Thread" ) && thread.isDaemon() ) + .map( Thread::isDaemon ) + .findAny() + .isPresent() ); + } + ); + } + + @Entity(name = "Event") + public static class Event { + + @Id + @GeneratedValue + private Long id; + + private String name; + } +} \ No newline at end of file diff --git a/hibernate-core/src/test/java/org/hibernate/connection/DriverManagerRegistrationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/connection/DriverManagerRegistrationTest.java similarity index 94% rename from hibernate-core/src/test/java/org/hibernate/connection/DriverManagerRegistrationTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/connection/DriverManagerRegistrationTest.java index 4cc3df61b4..d54cd45c6e 100644 --- a/hibernate-core/src/test/java/org/hibernate/connection/DriverManagerRegistrationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/connection/DriverManagerRegistrationTest.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.connection; +package org.hibernate.orm.test.connection; import java.sql.Connection; import java.sql.Driver; @@ -34,7 +34,7 @@ public class DriverManagerRegistrationTest extends BaseUnitTestCase { @Test public void testDriverRegistrationUsingLoadClassFails() { - final String driverClassName = "org.hibernate.connection.DriverManagerRegistrationTest$TestDriver1"; + final String driverClassName = "org.hibernate.orm.test.connection.DriverManagerRegistrationTest$TestDriver1"; final String url = "jdbc:hibernate:test"; try { @@ -55,7 +55,7 @@ public class DriverManagerRegistrationTest extends BaseUnitTestCase { @Test public void testDriverRegistrationUsingClassForNameSucceeds() { - final String driverClassName = "org.hibernate.connection.DriverManagerRegistrationTest$TestDriver2"; + final String driverClassName = "org.hibernate.orm.test.connection.DriverManagerRegistrationTest$TestDriver2"; final String url = "jdbc:hibernate:test2"; try { Class.forName( driverClassName, true, determineClassLoader() ); diff --git a/hibernate-core/src/test/java/org/hibernate/connection/PropertiesTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/connection/PropertiesTest.java similarity index 97% rename from hibernate-core/src/test/java/org/hibernate/connection/PropertiesTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/connection/PropertiesTest.java index 0e6c331ad5..aba106adc8 100644 --- a/hibernate-core/src/test/java/org/hibernate/connection/PropertiesTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/connection/PropertiesTest.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.connection; +package org.hibernate.orm.test.connection; import java.util.Properties; import org.junit.Assert; diff --git a/hibernate-core/src/test/java/org/hibernate/graph/AbstractEntityGraphTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/graph/AbstractEntityGraphTest.java similarity index 97% rename from hibernate-core/src/test/java/org/hibernate/graph/AbstractEntityGraphTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/graph/AbstractEntityGraphTest.java index 74c59a04d5..9e80d66cc2 100644 --- a/hibernate-core/src/test/java/org/hibernate/graph/AbstractEntityGraphTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/graph/AbstractEntityGraphTest.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.graph; +package org.hibernate.orm.test.graph; import java.util.Collection; import java.util.List; @@ -14,6 +14,7 @@ import javax.persistence.EntityGraph; import javax.persistence.EntityManager; import javax.persistence.Subgraph; +import org.hibernate.graph.GraphParser; import org.hibernate.graph.spi.RootGraphImplementor; import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; diff --git a/hibernate-core/src/test/java/org/hibernate/graph/EntityGraphsTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/graph/EntityGraphsTest.java similarity index 99% rename from hibernate-core/src/test/java/org/hibernate/graph/EntityGraphsTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/graph/EntityGraphsTest.java index 7a53e9fbeb..7860aa9c8b 100644 --- a/hibernate-core/src/test/java/org/hibernate/graph/EntityGraphsTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/graph/EntityGraphsTest.java @@ -4,11 +4,12 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.graph; +package org.hibernate.orm.test.graph; import javax.persistence.EntityGraph; import javax.persistence.EntityManager; +import org.hibernate.graph.EntityGraphs; import org.hibernate.graph.spi.RootGraphImplementor; import org.hibernate.testing.TestForIssue; diff --git a/hibernate-core/src/test/java/org/hibernate/graph/GraphParsingTestEntity.java b/hibernate-core/src/test/java/org/hibernate/orm/test/graph/GraphParsingTestEntity.java similarity index 97% rename from hibernate-core/src/test/java/org/hibernate/graph/GraphParsingTestEntity.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/graph/GraphParsingTestEntity.java index 00f68bb8ee..f8be91706a 100644 --- a/hibernate-core/src/test/java/org/hibernate/graph/GraphParsingTestEntity.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/graph/GraphParsingTestEntity.java @@ -1,4 +1,4 @@ -package org.hibernate.graph; +package org.hibernate.orm.test.graph; import java.util.Map; import javax.persistence.Basic; diff --git a/hibernate-core/src/test/java/org/hibernate/graph/GraphParsingTestSubentity.java b/hibernate-core/src/test/java/org/hibernate/orm/test/graph/GraphParsingTestSubentity.java similarity index 88% rename from hibernate-core/src/test/java/org/hibernate/graph/GraphParsingTestSubentity.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/graph/GraphParsingTestSubentity.java index 188c24352a..e01d69f2ea 100644 --- a/hibernate-core/src/test/java/org/hibernate/graph/GraphParsingTestSubentity.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/graph/GraphParsingTestSubentity.java @@ -1,4 +1,4 @@ -package org.hibernate.graph; +package org.hibernate.orm.test.graph; import javax.persistence.Basic; import javax.persistence.Entity; diff --git a/hibernate-core/src/test/java/org/hibernate/persister/entity/AbstractSchemaSubstitutionFormulaTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/persister/entity/AbstractSchemaSubstitutionFormulaTest.java similarity index 73% rename from hibernate-core/src/test/java/org/hibernate/persister/entity/AbstractSchemaSubstitutionFormulaTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/persister/entity/AbstractSchemaSubstitutionFormulaTest.java index 6ffb4cf4b8..909f815f10 100644 --- a/hibernate-core/src/test/java/org/hibernate/persister/entity/AbstractSchemaSubstitutionFormulaTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/persister/entity/AbstractSchemaSubstitutionFormulaTest.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.persister.entity; +package org.hibernate.orm.test.persister.entity; import javax.persistence.Column; import javax.persistence.Entity; @@ -14,31 +14,39 @@ import javax.persistence.ManyToOne; import javax.persistence.Table; import org.hibernate.annotations.Formula; -import org.hibernate.dialect.H2Dialect; +import org.hibernate.persister.entity.AbstractEntityPersister; -import org.hibernate.testing.RequiresDialect; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; -import org.junit.Test; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.FailureExpected; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; + +import org.junit.jupiter.api.Test; -import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; /** * @author Mykhaylo Gnylorybov */ -public abstract class AbstractSchemaSubstitutionFormulaTest extends BaseCoreFunctionalTestCase { +@DomainModel(annotatedClasses = { + AbstractSchemaSubstitutionFormulaTest.FooBar.class, + AbstractSchemaSubstitutionFormulaTest.Bar.class, + AbstractSchemaSubstitutionFormulaTest.Foo.class +}) +@SessionFactory +public abstract class AbstractSchemaSubstitutionFormulaTest { protected static final String SCHEMA_PLACEHOLDER = "h-schema"; @Test - public void test() { + public void test(SessionFactoryScope scope) { final String className = FooBar.class.getName(); - final AbstractEntityPersister persister = (AbstractEntityPersister) sessionFactory() + final AbstractEntityPersister persister = (AbstractEntityPersister) scope.getSessionFactory() .getMetamodel().entityPersister( className ); - final String formula = persister.getSubclassFormulaTemplateClosure()[0]; + final String formula = persister.getSubclassPropertyFormulaTemplateClosure()[persister.getPropertyIndex( "isValid" )][0]; + validate( formula ); - doInHibernate( this::sessionFactory, session -> { + scope.inTransaction( session -> { Foo foo = new Foo(); foo.id = 1; foo.name = "fooName"; @@ -57,7 +65,7 @@ public abstract class AbstractSchemaSubstitutionFormulaTest extends BaseCoreFunc session.persist( fooBar ); } ); - doInHibernate( this::sessionFactory, session -> { + scope.inTransaction( session -> { FooBar entity = session.find( FooBar.class, 3 ); assertTrue( "Invalid result of formula expression: ", entity.isValid ); } ); @@ -67,15 +75,6 @@ public abstract class AbstractSchemaSubstitutionFormulaTest extends BaseCoreFunc abstract void validate(String formula); - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { - FooBar.class, - Bar.class, - Foo.class - }; - } - @Entity(name = "FOOBAR") @Table(name = "FOOBAR") public static class FooBar { diff --git a/hibernate-core/src/test/java/org/hibernate/persister/entity/CustomSqlSchemaResolvingIdentityTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/persister/entity/CustomSqlSchemaResolvingIdentityTest.java similarity index 74% rename from hibernate-core/src/test/java/org/hibernate/persister/entity/CustomSqlSchemaResolvingIdentityTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/persister/entity/CustomSqlSchemaResolvingIdentityTest.java index bb54388a2f..839f7eaf81 100644 --- a/hibernate-core/src/test/java/org/hibernate/persister/entity/CustomSqlSchemaResolvingIdentityTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/persister/entity/CustomSqlSchemaResolvingIdentityTest.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.persister.entity; +package org.hibernate.orm.test.persister.entity; import javax.persistence.Entity; import javax.persistence.GeneratedValue; @@ -20,12 +20,18 @@ import org.hibernate.annotations.SQLDelete; import org.hibernate.annotations.SQLInsert; import org.hibernate.annotations.SQLUpdate; import org.hibernate.dialect.H2Dialect; +import org.hibernate.persister.entity.AbstractEntityPersister; +import org.hibernate.persister.entity.SingleTableEntityPersister; import org.hibernate.testing.RequiresDialect; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; -import org.junit.Test; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.FailureExpected; +import org.hibernate.testing.orm.junit.NotImplementedYet; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; + +import org.junit.jupiter.api.Test; -import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -33,22 +39,19 @@ import static org.junit.Assert.assertNull; /** * @author Laabidi RAISSI */ +@DomainModel(annotatedClasses = { + CustomSqlSchemaResolvingIdentityTest.CustomEntity.class, CustomSqlSchemaResolvingIdentityTest.Dummy.class +}) +@SessionFactory @RequiresDialect(H2Dialect.class) -public class CustomSqlSchemaResolvingIdentityTest extends BaseCoreFunctionalTestCase { - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[]{ - CustomEntity.class, Dummy.class - }; - } +public class CustomSqlSchemaResolvingIdentityTest { @Test - public void testSchemaNotReplacedInCustomSQL() throws Exception { + public void testSchemaNotReplacedInCustomSQL(SessionFactoryScope scope) throws Exception { String className = CustomEntity.class.getName(); - final AbstractEntityPersister persister = (AbstractEntityPersister) sessionFactory().getEntityPersister( className ); + final AbstractEntityPersister persister = (AbstractEntityPersister) scope.getSessionFactory().getEntityPersister( className ); String insertQuery = persister.getSQLInsertStrings()[0]; String updateQuery = persister.getSQLUpdateStrings()[0]; String deleteQuery = persister.getSQLDeleteStrings()[0]; @@ -62,26 +65,26 @@ public class CustomSqlSchemaResolvingIdentityTest extends BaseCoreFunctionalTest assertEquals( "Incorrect custom SQL for update in Entity: " + className, "UPDATE FOO SET name = ? WHERE id = ? ", updateQuery ); - CustomEntity _entitty = doInHibernate( this::sessionFactory, session -> { + CustomEntity _entitty = scope.fromTransaction( session -> { CustomEntity entity = new CustomEntity(); session.persist( entity ); return entity; } ); - doInHibernate( this::sessionFactory, session -> { + scope.inTransaction( session -> { CustomEntity entity = session.find( CustomEntity.class, 1 ); assertNotNull(entity); entity.name = "Vlad"; } ); - doInHibernate( this::sessionFactory, session -> { + scope.inTransaction( session -> { CustomEntity entity = session.find( CustomEntity.class, _entitty.id ); session.delete( entity ); } ); - doInHibernate( this::sessionFactory, session -> { + scope.inTransaction( session -> { CustomEntity entity = session.find( CustomEntity.class, _entitty.id ); assertNull(entity); } ); diff --git a/hibernate-core/src/test/java/org/hibernate/persister/entity/CustomSqlSchemaResolvingTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/persister/entity/CustomSqlSchemaResolvingTest.java similarity index 74% rename from hibernate-core/src/test/java/org/hibernate/persister/entity/CustomSqlSchemaResolvingTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/persister/entity/CustomSqlSchemaResolvingTest.java index 2abb3bca27..8743da7926 100644 --- a/hibernate-core/src/test/java/org/hibernate/persister/entity/CustomSqlSchemaResolvingTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/persister/entity/CustomSqlSchemaResolvingTest.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.persister.entity; +package org.hibernate.orm.test.persister.entity; import javax.persistence.Entity; import javax.persistence.Id; @@ -17,11 +17,16 @@ import org.hibernate.annotations.ResultCheckStyle; import org.hibernate.annotations.SQLDelete; import org.hibernate.annotations.SQLInsert; import org.hibernate.annotations.SQLUpdate; +import org.hibernate.persister.entity.AbstractEntityPersister; +import org.hibernate.persister.entity.SingleTableEntityPersister; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; -import org.junit.Test; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.NotImplementedYet; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; + +import org.junit.jupiter.api.Test; -import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -29,21 +34,18 @@ import static org.junit.Assert.assertNull; /** * @author Laabidi RAISSI */ -public class CustomSqlSchemaResolvingTest extends BaseCoreFunctionalTestCase { - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[]{ - CustomEntity.class, Dummy.class - }; - } +@DomainModel(annotatedClasses = { + CustomSqlSchemaResolvingTest.CustomEntity.class, CustomSqlSchemaResolvingTest.Dummy.class +}) +@SessionFactory +public class CustomSqlSchemaResolvingTest { @Test - public void testSchemaNotReplacedInCustomSQL() throws Exception { + public void testSchemaNotReplacedInCustomSQL(SessionFactoryScope scope) throws Exception { String className = CustomEntity.class.getName(); - - final AbstractEntityPersister persister = (AbstractEntityPersister) sessionFactory().getEntityPersister( className ); + + final AbstractEntityPersister persister = (AbstractEntityPersister) scope.getSessionFactory().getEntityPersister( className ); String insertQuery = persister.getSQLInsertStrings()[0]; String updateQuery = persister.getSQLUpdateStrings()[0]; String deleteQuery = persister.getSQLDeleteStrings()[0]; @@ -57,25 +59,25 @@ public class CustomSqlSchemaResolvingTest extends BaseCoreFunctionalTestCase { assertEquals( "Incorrect custom SQL for update in Entity: " + className, "UPDATE FOO SET name = ? WHERE id = ? ", updateQuery ); - doInHibernate( this::sessionFactory, session -> { + scope.inTransaction( session -> { CustomEntity entity = new CustomEntity(); entity.id = 1; session.persist( entity ); } ); - doInHibernate( this::sessionFactory, session -> { + scope.inTransaction( session -> { CustomEntity entity = session.find( CustomEntity.class, 1 ); assertNotNull(entity); entity.name = "Vlad"; } ); - doInHibernate( this::sessionFactory, session -> { + scope.inTransaction( session -> { CustomEntity entity = session.find( CustomEntity.class, 1 ); session.delete( entity ); } ); - doInHibernate( this::sessionFactory, session -> { + scope.inTransaction( session -> { CustomEntity entity = session.find( CustomEntity.class, 1 ); assertNull(entity); } ); diff --git a/hibernate-core/src/test/java/org/hibernate/persister/entity/FormulaTemplateEmptySchemaSubstitutionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/persister/entity/FormulaTemplateEmptySchemaSubstitutionTest.java similarity index 88% rename from hibernate-core/src/test/java/org/hibernate/persister/entity/FormulaTemplateEmptySchemaSubstitutionTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/persister/entity/FormulaTemplateEmptySchemaSubstitutionTest.java index 843d9bcf49..077f7577d5 100644 --- a/hibernate-core/src/test/java/org/hibernate/persister/entity/FormulaTemplateEmptySchemaSubstitutionTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/persister/entity/FormulaTemplateEmptySchemaSubstitutionTest.java @@ -4,11 +4,12 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.persister.entity; +package org.hibernate.orm.test.persister.entity; import org.hibernate.dialect.H2Dialect; -import org.hibernate.testing.RequiresDialect; + +import org.hibernate.testing.orm.junit.RequiresDialect; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/persister/entity/FormulaTemplateSchemaSubstitutionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/persister/entity/FormulaTemplateSchemaSubstitutionTest.java new file mode 100644 index 0000000000..0929176485 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/persister/entity/FormulaTemplateSchemaSubstitutionTest.java @@ -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 . + */ +package org.hibernate.orm.test.persister.entity; + +import org.hibernate.cfg.AvailableSettings; +import org.hibernate.dialect.H2Dialect; + + +import org.hibernate.testing.orm.junit.RequiresDialect; +import org.hibernate.testing.orm.junit.ServiceRegistry; +import org.hibernate.testing.orm.junit.Setting; + +import static org.junit.Assert.assertEquals; + +@RequiresDialect(H2Dialect.class) +@ServiceRegistry(settings = { + @Setting( name = AvailableSettings.DEFAULT_SCHEMA, value = FormulaTemplateSchemaSubstitutionTest.CUSTOM_SCHEMA), + @Setting( name = AvailableSettings.HBM2DDL_CREATE_SCHEMAS, value = "true") +}) +public class FormulaTemplateSchemaSubstitutionTest extends AbstractSchemaSubstitutionFormulaTest { + + static final String CUSTOM_SCHEMA = "CUSTOM_SCHEMA"; + + @Override + void validate(String formula) { + assertEquals( "Formula should not contain {} characters", + 4, formula.split( CUSTOM_SCHEMA + ".", -1 ).length - 1 + ); + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/persister/entity/JoinFormulaImplicitJoinTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/persister/entity/JoinFormulaImplicitJoinTest.java similarity index 80% rename from hibernate-core/src/test/java/org/hibernate/persister/entity/JoinFormulaImplicitJoinTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/persister/entity/JoinFormulaImplicitJoinTest.java index 6d01787f22..e298eda14e 100644 --- a/hibernate-core/src/test/java/org/hibernate/persister/entity/JoinFormulaImplicitJoinTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/persister/entity/JoinFormulaImplicitJoinTest.java @@ -1,10 +1,6 @@ -package org.hibernate.persister.entity; - -import static org.hibernate.testing.transaction.TransactionUtil.doInJPA; +package org.hibernate.orm.test.persister.entity; import java.util.List; -import java.util.Map; - import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; @@ -18,31 +14,25 @@ import org.hibernate.annotations.JoinColumnOrFormula; import org.hibernate.annotations.JoinColumnsOrFormulas; import org.hibernate.annotations.JoinFormula; import org.hibernate.cfg.AvailableSettings; -import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; + import org.hibernate.testing.TestForIssue; -import org.junit.Before; -import org.junit.Test; +import org.hibernate.testing.orm.junit.EntityManagerFactoryScope; +import org.hibernate.testing.orm.junit.Jpa; +import org.hibernate.testing.orm.junit.Setting; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; @TestForIssue(jiraKey = "HHH-14223") -public class JoinFormulaImplicitJoinTest extends BaseEntityManagerFunctionalTestCase { - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { - Person.class, PersonVersion.class - }; - } +@Jpa(annotatedClasses = { + JoinFormulaImplicitJoinTest.Person.class, JoinFormulaImplicitJoinTest.PersonVersion.class +}, properties = { + @Setting(name = AvailableSettings.GLOBALLY_QUOTED_IDENTIFIERS, value = "true") +}) +public class JoinFormulaImplicitJoinTest { - @Override - protected void addConfigOptions(Map options) { - options.put( - AvailableSettings.GLOBALLY_QUOTED_IDENTIFIERS, - Boolean.TRUE - ); - } - - @Before - public void setUp() { - doInJPA( this::entityManagerFactory, entityManager -> { + @BeforeEach + public void setUp(EntityManagerFactoryScope scope) { + scope.inTransaction(entityManager -> { final Person person = new Person(); entityManager.persist(person); @@ -61,8 +51,8 @@ public class JoinFormulaImplicitJoinTest extends BaseEntityManagerFunctionalTest } @Test - public void testImplicitJoin() { - doInJPA( this::entityManagerFactory, entityManager -> { + public void testImplicitJoin(EntityManagerFactoryScope scope) { + scope.inTransaction(entityManager -> { entityManager.createQuery( "SELECT person\n" + "FROM Person AS person\n" + diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/procedure/internal/ProcedureCallImplTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/procedure/internal/ProcedureCallImplTest.java new file mode 100644 index 0000000000..06bf1486cb --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/procedure/internal/ProcedureCallImplTest.java @@ -0,0 +1,34 @@ +package org.hibernate.orm.test.procedure.internal; + +import java.util.stream.Stream; +import javax.persistence.Query; + +import org.hibernate.dialect.H2Dialect; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.orm.junit.EntityManagerFactoryScope; +import org.hibernate.testing.orm.junit.Jpa; +import org.hibernate.testing.orm.junit.NotImplementedYet; +import org.hibernate.testing.orm.junit.RequiresDialect; +import org.junit.Assert; +import org.junit.jupiter.api.Test; + +/** + * @author Nathan Xu + */ +@Jpa +public class ProcedureCallImplTest { + + @Test + @TestForIssue( jiraKey = "HHH-13644" ) + @RequiresDialect( H2Dialect.class ) + @NotImplementedYet(reason = "org.hibernate.procedure.internal.ProcedureCallImpl.buildOutputs not yet implemented") + public void testNoNullPointerExceptionThrown(EntityManagerFactoryScope scope) { + scope.inTransaction( em -> { + em.createNativeQuery("CREATE ALIAS GET_RANDOM_VALUE FOR \"java.lang.Math.random\";").executeUpdate(); + Query query = em.createStoredProcedureQuery("GET_RANDOM_VALUE"); + Stream stream = query.getResultStream(); + Assert.assertEquals(1, stream.count()); + } ); + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/property/BasicPropertyAccessorTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/property/BasicPropertyAccessorTest.java similarity index 98% rename from hibernate-core/src/test/java/org/hibernate/property/BasicPropertyAccessorTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/property/BasicPropertyAccessorTest.java index a556a0fb23..eed3ff8545 100644 --- a/hibernate-core/src/test/java/org/hibernate/property/BasicPropertyAccessorTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/property/BasicPropertyAccessorTest.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.property; +package org.hibernate.orm.test.property; import org.hibernate.property.access.internal.PropertyAccessStrategyBasicImpl; import org.hibernate.property.access.spi.PropertyAccess; diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/property/DirectPropertyAccessorTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/property/DirectPropertyAccessorTest.java new file mode 100644 index 0000000000..fc0a112bf9 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/property/DirectPropertyAccessorTest.java @@ -0,0 +1,52 @@ +/* + * 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 . + */ +package org.hibernate.orm.test.property; + + +import org.hibernate.Hibernate; +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; + +import org.junit.jupiter.api.Test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * @author Michael Rudolf + */ +@DomainModel(annotatedClasses = { + Order.class, + Item.class +}) +@SessionFactory +public class DirectPropertyAccessorTest { + @Test + @TestForIssue( jiraKey="HHH-3718" ) + public void testDirectIdPropertyAccess(SessionFactoryScope scope) throws Exception { + scope.inTransaction( s -> { + Item i = new Item(); + s.persist( i ); + Order o = new Order(); + o.setOrderNumber( 1 ); + o.getItems().add( i ); + s.persist( o ); + s.flush(); + s.clear(); + + o = ( Order ) s.load( Order.class, 1 ); + assertFalse( Hibernate.isInitialized( o ) ); + o.getOrderNumber(); + // If you mapped with field access, any method, except id, call initializes the proxy + assertFalse( Hibernate.isInitialized( o ) ); + o.getName(); + assertTrue( Hibernate.isInitialized( o ) ); + } ); + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/property/GetAndIsVariantGetterTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/property/GetAndIsVariantGetterTest.java similarity index 99% rename from hibernate-core/src/test/java/org/hibernate/property/GetAndIsVariantGetterTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/property/GetAndIsVariantGetterTest.java index 86ffd4a585..26cff8ef1a 100644 --- a/hibernate-core/src/test/java/org/hibernate/property/GetAndIsVariantGetterTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/property/GetAndIsVariantGetterTest.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.property; +package org.hibernate.orm.test.property; import javax.persistence.Access; import javax.persistence.AccessType; diff --git a/hibernate-core/src/test/java/org/hibernate/property/GetAndIsVariantGetterWithTransientAnnotationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/property/GetAndIsVariantGetterWithTransientAnnotationTest.java similarity index 75% rename from hibernate-core/src/test/java/org/hibernate/property/GetAndIsVariantGetterWithTransientAnnotationTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/property/GetAndIsVariantGetterWithTransientAnnotationTest.java index 4416c47774..d139e1e808 100644 --- a/hibernate-core/src/test/java/org/hibernate/property/GetAndIsVariantGetterWithTransientAnnotationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/property/GetAndIsVariantGetterWithTransientAnnotationTest.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.property; +package org.hibernate.orm.test.property; import javax.persistence.Entity; import javax.persistence.Id; @@ -12,9 +12,11 @@ import javax.persistence.Table; import javax.persistence.Transient; import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; -import org.hibernate.testing.transaction.TransactionUtil; -import org.junit.Test; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; + +import org.junit.jupiter.api.Test; import static org.hamcrest.core.Is.is; import static org.hamcrest.core.IsNull.nullValue; @@ -23,49 +25,49 @@ import static org.junit.Assert.assertThat; /** * @author Andrea Boriero */ +@SessionFactory +@DomainModel(annotatedClasses = { + GetAndIsVariantGetterWithTransientAnnotationTest.TestEntity.class, + GetAndIsVariantGetterWithTransientAnnotationTest.SecondTestEntity.class +}) @TestForIssue(jiraKey = "HHH-11716") -public class GetAndIsVariantGetterWithTransientAnnotationTest extends BaseCoreFunctionalTestCase { - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] {TestEntity.class, SecondTestEntity.class}; - } +public class GetAndIsVariantGetterWithTransientAnnotationTest { @Test - public void testGetAndIsVariantCanHaveDifferentReturnValueWhenOneHasATransientAnnotation() { - TransactionUtil.doInHibernate( this::sessionFactory, session1 -> { + public void testGetAndIsVariantCanHaveDifferentReturnValueWhenOneHasATransientAnnotation(SessionFactoryScope scope) { + scope.inTransaction( session1 -> { TestEntity entity = new TestEntity(); entity.setId( 1L ); entity.setChecked( true ); session1.save( entity ); } ); - TransactionUtil.doInHibernate( this::sessionFactory, session1 -> { + scope.inTransaction( session1 -> { final TestEntity entity = session1.find( TestEntity.class, 1L ); assertThat( entity.isChecked(), is( true ) ); } ); - TransactionUtil.doInHibernate( this::sessionFactory, session1 -> { + scope.inTransaction( session1 -> { final TestEntity entity = session1.find( TestEntity.class, 1L ); entity.setChecked( null ); } ); - TransactionUtil.doInHibernate( this::sessionFactory, session1 -> { + scope.inTransaction( session1 -> { final TestEntity entity = session1.find( TestEntity.class, 1L ); assertThat( entity.isChecked(), is( nullValue() ) ); } ); } @Test - public void testBothGetterAndIsVariantAreIgnoredWhenMarkedTransient() { - TransactionUtil.doInHibernate( this::sessionFactory, session1 -> { + public void testBothGetterAndIsVariantAreIgnoredWhenMarkedTransient(SessionFactoryScope scope) { + scope.inTransaction( session1 -> { SecondTestEntity entity = new SecondTestEntity(); entity.setId( 1L ); entity.setChecked( true ); session1.save( entity ); } ); - TransactionUtil.doInHibernate( this::sessionFactory, session1 -> { + scope.inTransaction( session1 -> { final SecondTestEntity entity = session1.find( SecondTestEntity.class, 1L ); assertThat( entity.getChecked(), is( nullValue() ) ); } ); diff --git a/hibernate-core/src/test/java/org/hibernate/property/Item.java b/hibernate-core/src/test/java/org/hibernate/orm/test/property/Item.java similarity index 93% rename from hibernate-core/src/test/java/org/hibernate/property/Item.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/property/Item.java index 0e680c40cd..2b56a672d0 100644 --- a/hibernate-core/src/test/java/org/hibernate/property/Item.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/property/Item.java @@ -7,7 +7,7 @@ // $Id$ -package org.hibernate.property; +package org.hibernate.orm.test.property; import java.io.Serializable; import javax.persistence.Entity; diff --git a/hibernate-core/src/test/java/org/hibernate/property/Order.java b/hibernate-core/src/test/java/org/hibernate/orm/test/property/Order.java similarity index 96% rename from hibernate-core/src/test/java/org/hibernate/property/Order.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/property/Order.java index b9de55781a..73d1c8cd7c 100644 --- a/hibernate-core/src/test/java/org/hibernate/property/Order.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/property/Order.java @@ -7,7 +7,7 @@ // $Id$ -package org.hibernate.property; +package org.hibernate.orm.test.property; import java.io.Serializable; import java.util.HashSet; diff --git a/hibernate-core/src/test/java/org/hibernate/property/PropertyAccessStrategyMapTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/property/PropertyAccessStrategyMapTest.java similarity index 97% rename from hibernate-core/src/test/java/org/hibernate/property/PropertyAccessStrategyMapTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/property/PropertyAccessStrategyMapTest.java index 1571ba5471..a45c574900 100644 --- a/hibernate-core/src/test/java/org/hibernate/property/PropertyAccessStrategyMapTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/property/PropertyAccessStrategyMapTest.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.property; +package org.hibernate.orm.test.property; import java.util.Date; import java.util.HashMap; diff --git a/hibernate-core/src/test/java/org/hibernate/property/access/spi/GetterFieldImplTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/property/access/spi/GetterFieldImplTest.java similarity index 55% rename from hibernate-core/src/test/java/org/hibernate/property/access/spi/GetterFieldImplTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/property/access/spi/GetterFieldImplTest.java index 1d20672fd7..3ba9276f4d 100644 --- a/hibernate-core/src/test/java/org/hibernate/property/access/spi/GetterFieldImplTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/property/access/spi/GetterFieldImplTest.java @@ -1,7 +1,11 @@ -package org.hibernate.property.access.spi; +package org.hibernate.orm.test.property.access.spi; import java.lang.reflect.Field; +import org.hibernate.property.access.spi.Getter; +import org.hibernate.property.access.spi.GetterFieldImpl; + +import org.junit.Assert; import org.junit.Test; import static org.junit.Assert.assertEquals; @@ -15,13 +19,13 @@ public class GetterFieldImplTest { public void testGet() throws Exception { Target target = new Target(); - assertEquals( true, getter( "active" ).get( target ) ); - assertEquals( (byte) 2, getter( "children" ).get( target ) ); - assertEquals( 'M', getter( "gender" ).get( target ) ); - assertEquals( Integer.MAX_VALUE, getter( "code" ).get( target ) ); - assertEquals( Long.MAX_VALUE, getter( "id" ).get( target ) ); - assertEquals( (short) 34, getter( "age" ).get( target ) ); - assertEquals( "John Doe", getter( "name" ).get( target ) ); + Assert.assertEquals( true, getter( "active" ).get( target ) ); + Assert.assertEquals( (byte) 2, getter( "children" ).get( target ) ); + Assert.assertEquals( 'M', getter( "gender" ).get( target ) ); + Assert.assertEquals( Integer.MAX_VALUE, getter( "code" ).get( target ) ); + Assert.assertEquals( Long.MAX_VALUE, getter( "id" ).get( target ) ); + Assert.assertEquals( (short) 34, getter( "age" ).get( target ) ); + Assert.assertEquals( "John Doe", getter( "name" ).get( target ) ); } private static class Target { diff --git a/hibernate-core/src/test/java/org/hibernate/secure/JaccIntegratorTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/secure/JaccIntegratorTest.java similarity index 77% rename from hibernate-core/src/test/java/org/hibernate/secure/JaccIntegratorTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/secure/JaccIntegratorTest.java index e27160755a..5274a0095f 100644 --- a/hibernate-core/src/test/java/org/hibernate/secure/JaccIntegratorTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/secure/JaccIntegratorTest.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.secure; +package org.hibernate.orm.test.secure; import java.security.CodeSource; import java.security.Permission; @@ -13,7 +13,6 @@ import java.security.Policy; import java.security.ProtectionDomain; import java.security.Provider; import java.util.Collections; -import java.util.Map; import javax.persistence.Entity; import javax.persistence.Id; import javax.security.auth.Subject; @@ -22,37 +21,33 @@ import javax.security.jacc.PolicyContextException; import javax.security.jacc.PolicyContextHandler; import org.hibernate.cfg.AvailableSettings; -import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; import org.hibernate.testing.TestForIssue; -import org.junit.Test; +import org.hibernate.testing.orm.junit.EntityManagerFactoryScope; +import org.hibernate.testing.orm.junit.Jpa; +import org.hibernate.testing.orm.junit.Setting; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -import static org.hibernate.testing.transaction.TransactionUtil.doInJPA; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; /** * @author Vlad Mihalcea */ +@Jpa(annotatedClasses = { + JaccIntegratorTest.Person.class +}, properties = { + @Setting( name = AvailableSettings.JACC_ENABLED, value = "true"), + @Setting( name = AvailableSettings.JACC_CONTEXT_ID, value = "JACC_CONTEXT_ID"), + @Setting( name = "hibernate.jacc.allowed.org.hibernate.secure.Customer", value = "insert") +}) @TestForIssue( jiraKey = "HHH-11805" ) -public class JaccIntegratorTest extends BaseEntityManagerFunctionalTestCase { +public class JaccIntegratorTest { - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { - Person.class, - }; - } - - @Override - protected void addConfigOptions(Map options) { - options.put( AvailableSettings.JACC_ENABLED, Boolean.TRUE.toString() ); - options.put( AvailableSettings.JACC_CONTEXT_ID, "JACC_CONTEXT_ID" ); - options.put( "hibernate.jacc.allowed.org.hibernate.secure.Customer", "insert" ); - } - - @Override - protected void afterEntityManagerFactoryBuilt() { + @BeforeEach + protected void afterEntityManagerFactoryBuilt(EntityManagerFactoryScope scope) { + scope.getEntityManagerFactory(); PolicyContextHandler policyContextHandler = new PolicyContextHandler() { @Override public Object getContext(String key, Object data) throws PolicyContextException { @@ -129,10 +124,10 @@ public class JaccIntegratorTest extends BaseEntityManagerFunctionalTestCase { } @Test - public void testAllow() { + public void testAllow(EntityManagerFactoryScope scope) { setPolicy( true ); - doInJPA( this::entityManagerFactory, entityManager -> { + scope.inTransaction( entityManager -> { Person person = new Person(); person.id = 1L; person.name = "John Doe"; @@ -142,11 +137,11 @@ public class JaccIntegratorTest extends BaseEntityManagerFunctionalTestCase { } @Test - public void testDisallow() { + public void testDisallow(EntityManagerFactoryScope scope) { setPolicy( false ); try { - doInJPA( this::entityManagerFactory, entityManager -> { + scope.inTransaction( entityManager -> { Person person = new Person(); person.id = 1L; person.name = "John Doe"; diff --git a/hibernate-core/src/test/java/org/hibernate/serialization/EntityProxySerializationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/serialization/EntityProxySerializationTest.java similarity index 64% rename from hibernate-core/src/test/java/org/hibernate/serialization/EntityProxySerializationTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/serialization/EntityProxySerializationTest.java index 566e368116..84e7b2e4b0 100644 --- a/hibernate-core/src/test/java/org/hibernate/serialization/EntityProxySerializationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/serialization/EntityProxySerializationTest.java @@ -1,320 +1,258 @@ -/* - * 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 . - */ -package org.hibernate.serialization; - -import java.io.Serializable; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; - -import org.hibernate.Hibernate; -import org.hibernate.Session; -import org.hibernate.Transaction; -import org.hibernate.annotations.Fetch; -import org.hibernate.annotations.FetchMode; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; -import org.hibernate.annotations.LazyToOne; -import org.hibernate.annotations.LazyToOneOption; -import org.hibernate.cfg.AvailableSettings; -import org.hibernate.cfg.Configuration; -import org.hibernate.internal.util.SerializationHelper; -import org.hibernate.proxy.AbstractLazyInitializer; -import org.hibernate.proxy.HibernateProxy; - -import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; -import org.junit.Before; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -/** - * @author Selaron - */ -public class EntityProxySerializationTest extends BaseCoreFunctionalTestCase { - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { SimpleEntity.class, ChildEntity.class }; - } - - @Override - protected void configure(final Configuration configuration) { - // enable LL without TX, which used to cause problems when serializing proxies (see HHH-12720) - configuration.setProperty( AvailableSettings.ENABLE_LAZY_LOAD_NO_TRANS, Boolean.TRUE.toString() ); - } - - /** - * Prepare and persist a {@link SimpleEntity} with two {@link ChildEntity}. - */ - @Before - public void prepare() { - final Session s = openSession(); - - final Transaction t = s.beginTransaction(); - - try { - final Number count = (Number) s.createQuery("SELECT count(ID) FROM SimpleEntity").getSingleResult(); - if (count.longValue() > 0L) { - // entity already added previously - return; - } - - final SimpleEntity entity = new SimpleEntity(); - entity.setId( 1L ); - entity.setName( "TheParent" ); - - final ChildEntity c1 = new ChildEntity(); - c1.setId( 1L ); - c1.setParent( entity ); - - final ChildEntity c2 = new ChildEntity(); - c2.setId( 2L ); - c2.setParent( entity ); - - s.save( entity ); - s.save( c1 ); - s.save( c2 ); - } - finally { - t.commit(); - s.close(); - } - } - - /** - * Tests that serializing an initialized proxy will serialize the target instead. - */ - @SuppressWarnings("unchecked") - @Test - public void testInitializedProxySerializationIfTargetInPersistenceContext() { - final Session s = openSession(); - - final Transaction t = s.beginTransaction(); - try { - final ChildEntity child = s.find( ChildEntity.class, 1L ); - - final SimpleEntity parent = child.getParent(); - - // assert we have an uninitialized proxy - assertTrue( parent instanceof HibernateProxy ); - assertFalse( Hibernate.isInitialized( parent ) ); - - // Initialize the proxy - parent.getName(); - assertTrue( Hibernate.isInitialized( parent ) ); - - // serialize/deserialize the proxy - final SimpleEntity deserializedParent = (SimpleEntity) SerializationHelper.clone( parent ); - - // assert the deserialized object is no longer a proxy, but the target of the proxy - assertFalse( deserializedParent instanceof HibernateProxy ); - assertEquals( "TheParent", deserializedParent.getName() ); - } - finally { - if ( t.isActive() ) { - t.rollback(); - } - s.close(); - } - } - - /** - * Tests that serializing a proxy which is not initialized - * but whose target has been (separately) added to the persistence context - * will serialize the target instead. - */ - @SuppressWarnings("unchecked") - @Test - public void testUninitializedProxySerializationIfTargetInPersistenceContext() { - final Session s = openSession(); - - final Transaction t = s.beginTransaction(); - try { - final ChildEntity child = s.find( ChildEntity.class, 1L ); - - final SimpleEntity parent = child.getParent(); - - // assert we have an uninitialized proxy - assertTrue( parent instanceof HibernateProxy ); - assertFalse( Hibernate.isInitialized( parent ) ); - - // Load the target of the proxy without the proxy being made aware of it - s.detach( parent ); - s.find( SimpleEntity.class, 1L ); - s.update( parent ); - - // assert we still have an uninitialized proxy - assertFalse( Hibernate.isInitialized( parent ) ); - - // serialize/deserialize the proxy - final SimpleEntity deserializedParent = (SimpleEntity) SerializationHelper.clone( parent ); - - // assert the deserialized object is no longer a proxy, but the target of the proxy - assertFalse( deserializedParent instanceof HibernateProxy ); - assertEquals( "TheParent", deserializedParent.getName() ); - } - finally { - if ( t.isActive() ) { - t.rollback(); - } - s.close(); - } - } - - /** - * Tests that lazy loading without transaction nor open session is generally - * working. The magic is done by {@link AbstractLazyInitializer} who opens a - * temporary session. - */ - @SuppressWarnings("unchecked") - @Test - public void testProxyInitializationWithoutTX() { - final Session s = openSession(); - - final Transaction t = s.beginTransaction(); - try { - final ChildEntity child = s.find( ChildEntity.class, 1L ); - - final SimpleEntity parent = child.getParent(); - - t.rollback(); - session.close(); - - // assert we have an uninitialized proxy - assertTrue( parent instanceof HibernateProxy ); - assertFalse( Hibernate.isInitialized( parent ) ); - - assertEquals( "TheParent", parent.getName() ); - - // assert we have an initialized proxy now - assertTrue( Hibernate.isInitialized( parent ) ); - } - finally { - if ( t.isActive() ) { - t.rollback(); - } - s.close(); - } - } - - /** - * Tests that lazy loading without transaction nor open session is generally - * working. The magic is done by {@link AbstractLazyInitializer} who opens a - * temporary session. - */ - @SuppressWarnings("unchecked") - @Test - @TestForIssue(jiraKey = "HHH-12720") - public void testProxyInitializationWithoutTXAfterDeserialization() { - final Session s = openSession(); - - final Transaction t = s.beginTransaction(); - try { - final ChildEntity child = s.find( ChildEntity.class, 1L ); - - final SimpleEntity parent = child.getParent(); - - // destroy AbstractLazyInitializer internal state - final SimpleEntity deserializedParent = (SimpleEntity) SerializationHelper.clone( parent ); - - t.rollback(); - session.close(); - - // assert we have an uninitialized proxy - assertTrue( deserializedParent instanceof HibernateProxy ); - assertFalse( Hibernate.isInitialized( deserializedParent ) ); - - assertEquals( "TheParent", deserializedParent.getName() ); - - // assert we have an initialized proxy now - assertTrue( Hibernate.isInitialized( deserializedParent ) ); - } - finally { - if ( t.isActive() ) { - t.rollback(); - } - s.close(); - } - } - - @Entity(name = "SimpleEntity") - static class SimpleEntity implements Serializable { - - private Long id; - - private String name; - - Set children = new HashSet<>(); - - @Id - public Long getId() { - return id; - } - - public void setId(final Long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(final String name) { - this.name = name; - } - - @OneToMany(targetEntity = ChildEntity.class, mappedBy = "parent") - @LazyCollection(LazyCollectionOption.EXTRA) - @Fetch(FetchMode.SELECT) - public Set getChildren() { - return children; - } - - public void setChildren(final Set children) { - this.children = children; - } - - } - - @Entity(name = "ChildEntity") - static class ChildEntity { - private Long id; - - private SimpleEntity parent; - - @Id - public Long getId() { - return id; - } - - public void setId(final Long id) { - this.id = id; - } - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn - @LazyToOne(LazyToOneOption.PROXY) - public SimpleEntity getParent() { - return parent; - } - - public void setParent(final SimpleEntity parent) { - this.parent = parent; - } - - } +/* + * 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 . + */ +package org.hibernate.orm.test.serialization; + +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; + +import org.hibernate.Hibernate; +import org.hibernate.annotations.Fetch; +import org.hibernate.annotations.FetchMode; +import org.hibernate.annotations.LazyCollection; +import org.hibernate.annotations.LazyCollectionOption; +import org.hibernate.annotations.LazyToOne; +import org.hibernate.annotations.LazyToOneOption; +import org.hibernate.cfg.AvailableSettings; +import org.hibernate.internal.util.SerializationHelper; +import org.hibernate.proxy.AbstractLazyInitializer; +import org.hibernate.proxy.HibernateProxy; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.ServiceRegistry; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.hibernate.testing.orm.junit.Setting; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * @author Selaron + */ +@DomainModel(annotatedClasses = { + EntityProxySerializationTest.SimpleEntity.class, EntityProxySerializationTest.ChildEntity.class +}) +@SessionFactory +@ServiceRegistry(settings = { + @Setting( name = AvailableSettings.ENABLE_LAZY_LOAD_NO_TRANS, value = "true" ) +}) +public class EntityProxySerializationTest { + + /** + * Prepare and persist a {@link SimpleEntity} with two {@link ChildEntity}. + */ + @BeforeEach + public void prepare(SessionFactoryScope scope) { + scope.inTransaction( s -> { + final Number count = (Number) s.createQuery("SELECT count(ID) FROM SimpleEntity").getSingleResult(); + if (count.longValue() > 0L) { + // entity already added previously + return; + } + + final SimpleEntity entity = new SimpleEntity(); + entity.setId( 1L ); + entity.setName( "TheParent" ); + + final ChildEntity c1 = new ChildEntity(); + c1.setId( 1L ); + c1.setParent( entity ); + + final ChildEntity c2 = new ChildEntity(); + c2.setId( 2L ); + c2.setParent( entity ); + + s.save( entity ); + s.save( c1 ); + s.save( c2 ); + } ); + } + + /** + * Tests that serializing an initialized proxy will serialize the target instead. + */ + @Test + public void testInitializedProxySerializationIfTargetInPersistenceContext(SessionFactoryScope scope) { + scope.inTransaction( s -> { + final ChildEntity child = s.find( ChildEntity.class, 1L ); + + final SimpleEntity parent = child.getParent(); + + // assert we have an uninitialized proxy + assertTrue( parent instanceof HibernateProxy ); + assertFalse( Hibernate.isInitialized( parent ) ); + + // Initialize the proxy + parent.getName(); + assertTrue( Hibernate.isInitialized( parent ) ); + + // serialize/deserialize the proxy + final SimpleEntity deserializedParent = (SimpleEntity) SerializationHelper.clone( parent ); + + // assert the deserialized object is no longer a proxy, but the target of the proxy + assertFalse( deserializedParent instanceof HibernateProxy ); + assertEquals( "TheParent", deserializedParent.getName() ); + } ); + } + + /** + * Tests that serializing a proxy which is not initialized + * but whose target has been (separately) added to the persistence context + * will serialize the target instead. + */ + @Test + public void testUninitializedProxySerializationIfTargetInPersistenceContext(SessionFactoryScope scope) { + scope.inTransaction( s -> { + final ChildEntity child = s.find( ChildEntity.class, 1L ); + + final SimpleEntity parent = child.getParent(); + + // assert we have an uninitialized proxy + assertTrue( parent instanceof HibernateProxy ); + assertFalse( Hibernate.isInitialized( parent ) ); + + // Load the target of the proxy without the proxy being made aware of it + s.detach( parent ); + s.find( SimpleEntity.class, 1L ); + s.update( parent ); + + // assert we still have an uninitialized proxy + assertFalse( Hibernate.isInitialized( parent ) ); + + // serialize/deserialize the proxy + final SimpleEntity deserializedParent = (SimpleEntity) SerializationHelper.clone( parent ); + + // assert the deserialized object is no longer a proxy, but the target of the proxy + assertFalse( deserializedParent instanceof HibernateProxy ); + assertEquals( "TheParent", deserializedParent.getName() ); + } ); + } + + /** + * Tests that lazy loading without transaction nor open session is generally + * working. The magic is done by {@link AbstractLazyInitializer} who opens a + * temporary session. + */ + @Test + public void testProxyInitializationWithoutTX(SessionFactoryScope scope) { + final SimpleEntity parent = scope.fromTransaction( s -> { + final ChildEntity child = s.find( ChildEntity.class, 1L ); + return child.getParent(); + }); + + // assert we have an uninitialized proxy + assertTrue( parent instanceof HibernateProxy ); + assertFalse( Hibernate.isInitialized( parent ) ); + + assertEquals( "TheParent", parent.getName() ); + + // assert we have an initialized proxy now + assertTrue( Hibernate.isInitialized( parent ) ); + } + + /** + * Tests that lazy loading without transaction nor open session is generally + * working. The magic is done by {@link AbstractLazyInitializer} who opens a + * temporary session. + */ + @Test + @TestForIssue(jiraKey = "HHH-12720") + public void testProxyInitializationWithoutTXAfterDeserialization(SessionFactoryScope scope) { + final SimpleEntity deserializedParent = scope.fromTransaction( s -> { + final ChildEntity child = s.find( ChildEntity.class, 1L ); + final SimpleEntity parent = child.getParent(); + // destroy AbstractLazyInitializer internal state + return (SimpleEntity) SerializationHelper.clone( parent ); + }); + // assert we have an uninitialized proxy + assertTrue( deserializedParent instanceof HibernateProxy ); + assertFalse( Hibernate.isInitialized( deserializedParent ) ); + + assertEquals( "TheParent", deserializedParent.getName() ); + + // assert we have an initialized proxy now + assertTrue( Hibernate.isInitialized( deserializedParent ) ); + } + + @Entity(name = "SimpleEntity") + static class SimpleEntity implements Serializable { + + private Long id; + + private String name; + + Set children = new HashSet<>(); + + @Id + public Long getId() { + return id; + } + + public void setId(final Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(final String name) { + this.name = name; + } + + @OneToMany(targetEntity = ChildEntity.class, mappedBy = "parent") + @LazyCollection(LazyCollectionOption.EXTRA) + @Fetch(FetchMode.SELECT) + public Set getChildren() { + return children; + } + + public void setChildren(final Set children) { + this.children = children; + } + + } + + @Entity(name = "ChildEntity") + static class ChildEntity { + private Long id; + + private SimpleEntity parent; + + @Id + public Long getId() { + return id; + } + + public void setId(final Long id) { + this.id = id; + } + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn + @LazyToOne(LazyToOneOption.PROXY) + public SimpleEntity getParent() { + return parent; + } + + public void setParent(final SimpleEntity parent) { + this.parent = parent; + } + + } } \ No newline at end of file diff --git a/hibernate-core/src/test/java/org/hibernate/serialization/GetterSetterSerializationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/serialization/GetterSetterSerializationTest.java similarity index 96% rename from hibernate-core/src/test/java/org/hibernate/serialization/GetterSetterSerializationTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/serialization/GetterSetterSerializationTest.java index e437336fea..5d52d0bd18 100644 --- a/hibernate-core/src/test/java/org/hibernate/serialization/GetterSetterSerializationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/serialization/GetterSetterSerializationTest.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.serialization; +package org.hibernate.orm.test.serialization; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -14,14 +14,15 @@ import java.io.ObjectOutputStream; import org.junit.Test; import org.hibernate.internal.util.ReflectHelper; +import org.hibernate.orm.test.serialization.entity.AnEntity; +import org.hibernate.orm.test.serialization.entity.PK; import org.hibernate.property.access.spi.Getter; import org.hibernate.property.access.spi.GetterFieldImpl; import org.hibernate.property.access.spi.GetterMethodImpl; import org.hibernate.property.access.spi.Setter; import org.hibernate.property.access.spi.SetterFieldImpl; import org.hibernate.property.access.spi.SetterMethodImpl; -import org.hibernate.serialization.entity.AnEntity; -import org.hibernate.serialization.entity.PK; + import org.hibernate.testing.TestForIssue; import static org.junit.Assert.assertSame; diff --git a/hibernate-core/src/test/java/org/hibernate/serialization/MapProxySerializationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/serialization/MapProxySerializationTest.java similarity index 58% rename from hibernate-core/src/test/java/org/hibernate/serialization/MapProxySerializationTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/serialization/MapProxySerializationTest.java index 0b8eb3993c..b460deb766 100644 --- a/hibernate-core/src/test/java/org/hibernate/serialization/MapProxySerializationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/serialization/MapProxySerializationTest.java @@ -1,243 +1,183 @@ -/* - * 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 . - */ -package org.hibernate.serialization; - -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; - -import org.hibernate.EntityMode; -import org.hibernate.Hibernate; -import org.hibernate.Session; -import org.hibernate.Transaction; -import org.hibernate.cfg.AvailableSettings; -import org.hibernate.cfg.Configuration; -import org.hibernate.internal.util.SerializationHelper; -import org.hibernate.proxy.AbstractLazyInitializer; -import org.hibernate.proxy.HibernateProxy; -import org.hibernate.proxy.map.MapProxy; - -import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; -import org.junit.Before; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -/** - * @author Selaron - */ -public class MapProxySerializationTest extends BaseCoreFunctionalTestCase { - - @Override - protected String[] getMappings() { - return new String[] { "serialization/DynamicMapMappings.hbm.xml" }; - } - - @Override - protected void configure(final Configuration configuration) { - // enable LL without TX, which used to cause problems when serializing proxies (see HHH-12720) - configuration.setProperty( AvailableSettings.ENABLE_LAZY_LOAD_NO_TRANS, Boolean.TRUE.toString() ); - - // dynamic-map by default. - configuration.setProperty( AvailableSettings.DEFAULT_ENTITY_MODE, EntityMode.MAP.getExternalName() ); - } - - @Before - public void prepare() { - final Session s = openSession(); - - final Transaction t = s.beginTransaction(); - - try { - final Number count = (Number) s.createQuery("SELECT count(ID) FROM SimpleEntity").getSingleResult(); - if (count.longValue() > 0L) { - // entity already added previously - return; - } - - final Map entity = new HashMap<>(); - entity.put( "id", 1L ); - entity.put( "name", "TheParent" ); - - final Map c1 = new HashMap<>(); - c1.put( "id", 1L ); - c1.put( "parent", entity ); - - s.save( "SimpleEntity", entity ); - s.save( "ChildEntity", c1 ); - } - finally { - t.commit(); - s.close(); - } - } - - /** - * Tests that serializing an initialized proxy will serialize the target instead. - */ - @SuppressWarnings("unchecked") - @Test - @TestForIssue(jiraKey = "HHH-7686") - public void testInitializedProxySerializationIfTargetInPersistenceContext() { - final Session s = openSession(); - - final Transaction t = s.beginTransaction(); - try { - final Map child = (Map) s.load( "ChildEntity", 1L ); - - final Map parent = (Map) child.get( "parent" ); - - // assert we have an uninitialized proxy - assertTrue( parent instanceof MapProxy ); - assertFalse( Hibernate.isInitialized( parent ) ); - - // Initialize the proxy - parent.get( "name" ); - assertTrue( Hibernate.isInitialized( parent ) ); - - // serialize/deserialize the proxy - final Map deserializedParent = - (Map) SerializationHelper.clone( (Serializable) parent ); - - // assert the deserialized object is no longer a proxy, but the target of the proxy - assertFalse( deserializedParent instanceof HibernateProxy ); - assertEquals( "TheParent", deserializedParent.get( "name" ) ); - } - finally { - if ( t.isActive() ) { - t.rollback(); - } - s.close(); - } - } - - /** - * Tests that serializing a proxy which is not initialized - * but whose target has been (separately) added to the persistence context - * will serialized the target instead. - */ - @SuppressWarnings("unchecked") - @Test - @TestForIssue(jiraKey = "HHH-7686") - public void testUninitializedProxySerializationIfTargetInPersistenceContext() { - final Session s = openSession(); - - final Transaction t = s.beginTransaction(); - try { - final Map child = (Map) s.load( "ChildEntity", 1L ); - - final Map parent = (Map) child.get( "parent" ); - - // assert we have an uninitialized proxy - assertTrue( parent instanceof MapProxy ); - assertFalse( Hibernate.isInitialized( parent ) ); - - // Load the target of the proxy without the proxy being made aware of it - s.detach( parent ); - s.byId( "SimpleEntity" ).load( 1L ); - s.update( parent ); - - // assert we still have an uninitialized proxy - assertFalse( Hibernate.isInitialized( parent ) ); - - // serialize/deserialize the proxy - final Map deserializedParent = - (Map) SerializationHelper.clone( (Serializable) parent ); - - // assert the deserialized object is no longer a proxy, but the target of the proxy - assertFalse( deserializedParent instanceof HibernateProxy ); - assertEquals( "TheParent", deserializedParent.get( "name" ) ); - } - finally { - if ( t.isActive() ) { - t.rollback(); - } - s.close(); - } - } - - /** - * Tests that lazy loading without transaction nor open session is generally - * working. The magic is done by {@link AbstractLazyInitializer} who opens a - * temporary session. - */ - @SuppressWarnings("unchecked") - @Test - public void testProxyInitializationWithoutTX() { - final Session s = openSession(); - - final Transaction t = s.beginTransaction(); - try { - final Map child = (Map) s.load( "ChildEntity", 1L ); - - final Map parent = (Map) child.get( "parent" ); - - t.rollback(); - session.close(); - - // assert we have an uninitialized proxy - assertTrue( parent instanceof MapProxy ); - assertFalse( Hibernate.isInitialized( parent ) ); - - assertEquals( "TheParent", parent.get( "name" ) ); - - // assert we have an initialized proxy now - assertTrue( Hibernate.isInitialized( parent ) ); - } - finally { - if ( t.isActive() ) { - t.rollback(); - } - s.close(); - } - } - - /** - * Tests that lazy loading without transaction nor open session is generally - * working. The magic is done by {@link AbstractLazyInitializer} who opens a - * temporary session. - */ - @SuppressWarnings("unchecked") - @Test - @TestForIssue(jiraKey = "HHH-7686") - public void testProxyInitializationWithoutTXAfterDeserialization() { - final Session s = openSession(); - - final Transaction t = s.beginTransaction(); - try { - final Map child = (Map) s.load( "ChildEntity", 1L ); - - final Map parent = (Map) child.get( "parent" ); - - // destroy AbstractLazyInitializer internal state - final Map deserializedParent = - (Map) SerializationHelper.clone( (Serializable) parent ); - - t.rollback(); - session.close(); - - // assert we have an uninitialized proxy - assertTrue( deserializedParent instanceof MapProxy ); - assertFalse( Hibernate.isInitialized( deserializedParent ) ); - - assertEquals( "TheParent", deserializedParent.get( "name" ) ); - - // assert we have an initialized proxy now - assertTrue( Hibernate.isInitialized( deserializedParent ) ); - } - finally { - if ( t.isActive() ) { - t.rollback(); - } - s.close(); - } - } - +/* + * 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 . + */ +package org.hibernate.orm.test.serialization; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +import org.hibernate.Hibernate; +import org.hibernate.cfg.AvailableSettings; +import org.hibernate.internal.util.SerializationHelper; +import org.hibernate.proxy.AbstractLazyInitializer; +import org.hibernate.proxy.HibernateProxy; +import org.hibernate.proxy.map.MapProxy; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.ServiceRegistry; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.hibernate.testing.orm.junit.Setting; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * @author Selaron + */ +@DomainModel(xmlMappings = { + "org/hibernate/orm/test/serialization/DynamicMapMappings.hbm.xml" +}) +@SessionFactory +@ServiceRegistry(settings = { + @Setting( name = AvailableSettings.ENABLE_LAZY_LOAD_NO_TRANS, value = "true" ), + @Setting( name = AvailableSettings.DEFAULT_ENTITY_MODE, value = "dynamic-map" ) +}) +public class MapProxySerializationTest { + + @BeforeEach + public void prepare(SessionFactoryScope scope) { + scope.inTransaction( s -> { + final Number count = (Number) s.createQuery("SELECT count(ID) FROM SimpleEntity").getSingleResult(); + if (count.longValue() > 0L) { + // entity already added previously + return; + } + + final Map entity = new HashMap<>(); + entity.put( "id", 1L ); + entity.put( "name", "TheParent" ); + + final Map c1 = new HashMap<>(); + c1.put( "id", 1L ); + c1.put( "parent", entity ); + + s.save( "SimpleEntity", entity ); + s.save( "ChildEntity", c1 ); + } ); + } + + /** + * Tests that serializing an initialized proxy will serialize the target instead. + */ + @SuppressWarnings("unchecked") + @Test + @TestForIssue(jiraKey = "HHH-7686") + public void testInitializedProxySerializationIfTargetInPersistenceContext(SessionFactoryScope scope) { + scope.inTransaction( s -> { + final Map child = (Map) s.load( "ChildEntity", 1L ); + + final Map parent = (Map) child.get( "parent" ); + + // assert we have an uninitialized proxy + assertTrue( parent instanceof MapProxy ); + assertFalse( Hibernate.isInitialized( parent ) ); + + // Initialize the proxy + parent.get( "name" ); + assertTrue( Hibernate.isInitialized( parent ) ); + + // serialize/deserialize the proxy + final Map deserializedParent = + (Map) SerializationHelper.clone( (Serializable) parent ); + + // assert the deserialized object is no longer a proxy, but the target of the proxy + assertFalse( deserializedParent instanceof HibernateProxy ); + assertEquals( "TheParent", deserializedParent.get( "name" ) ); + } ); + } + + /** + * Tests that serializing a proxy which is not initialized + * but whose target has been (separately) added to the persistence context + * will serialized the target instead. + */ + @SuppressWarnings("unchecked") + @Test + @TestForIssue(jiraKey = "HHH-7686") + public void testUninitializedProxySerializationIfTargetInPersistenceContext(SessionFactoryScope scope) { + scope.inTransaction( s -> { + final Map child = (Map) s.load( "ChildEntity", 1L ); + + final Map parent = (Map) child.get( "parent" ); + + // assert we have an uninitialized proxy + assertTrue( parent instanceof MapProxy ); + assertFalse( Hibernate.isInitialized( parent ) ); + + // Load the target of the proxy without the proxy being made aware of it + s.detach( parent ); + s.byId( "SimpleEntity" ).load( 1L ); + s.update( parent ); + + // assert we still have an uninitialized proxy + assertFalse( Hibernate.isInitialized( parent ) ); + + // serialize/deserialize the proxy + final Map deserializedParent = + (Map) SerializationHelper.clone( (Serializable) parent ); + + // assert the deserialized object is no longer a proxy, but the target of the proxy + assertFalse( deserializedParent instanceof HibernateProxy ); + assertEquals( "TheParent", deserializedParent.get( "name" ) ); + } ); + } + + /** + * Tests that lazy loading without transaction nor open session is generally + * working. The magic is done by {@link AbstractLazyInitializer} who opens a + * temporary session. + */ + @SuppressWarnings("unchecked") + @Test + public void testProxyInitializationWithoutTX(SessionFactoryScope scope) { + final Map parent = scope.fromTransaction( s -> { + final Map child = (Map) s.load( "ChildEntity", 1L ); + return (Map) child.get( "parent" ); + }); + // assert we have an uninitialized proxy + assertTrue( parent instanceof MapProxy ); + assertFalse( Hibernate.isInitialized( parent ) ); + + assertEquals( "TheParent", parent.get( "name" ) ); + + // assert we have an initialized proxy now + assertTrue( Hibernate.isInitialized( parent ) ); + } + + /** + * Tests that lazy loading without transaction nor open session is generally + * working. The magic is done by {@link AbstractLazyInitializer} who opens a + * temporary session. + */ + @SuppressWarnings("unchecked") + @Test + @TestForIssue(jiraKey = "HHH-7686") + public void testProxyInitializationWithoutTXAfterDeserialization(SessionFactoryScope scope) { + final Map deserializedParent = scope.fromTransaction( s -> { + final Map child = (Map) s.load( "ChildEntity", 1L ); + final Map parent = (Map) child.get( "parent" ); + + // destroy AbstractLazyInitializer internal state + return (Map) SerializationHelper.clone( (Serializable) parent ); + }); + + // assert we have an uninitialized proxy + assertTrue( deserializedParent instanceof MapProxy ); + assertFalse( Hibernate.isInitialized( deserializedParent ) ); + + assertEquals( "TheParent", deserializedParent.get( "name" ) ); + + // assert we have an initialized proxy now + assertTrue( Hibernate.isInitialized( deserializedParent ) ); + } + } \ No newline at end of file diff --git a/hibernate-core/src/test/java/org/hibernate/serialization/SessionFactorySerializationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/serialization/SessionFactorySerializationTest.java similarity index 98% rename from hibernate-core/src/test/java/org/hibernate/serialization/SessionFactorySerializationTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/serialization/SessionFactorySerializationTest.java index 61d5f227da..75c9e21113 100644 --- a/hibernate-core/src/test/java/org/hibernate/serialization/SessionFactorySerializationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/serialization/SessionFactorySerializationTest.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.serialization; +package org.hibernate.orm.test.serialization; import javax.naming.Reference; diff --git a/hibernate-core/src/test/java/org/hibernate/serialization/entity/AnEntity.java b/hibernate-core/src/test/java/org/hibernate/orm/test/serialization/entity/AnEntity.java similarity index 92% rename from hibernate-core/src/test/java/org/hibernate/serialization/entity/AnEntity.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/serialization/entity/AnEntity.java index 89080e9761..53bd660edb 100644 --- a/hibernate-core/src/test/java/org/hibernate/serialization/entity/AnEntity.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/serialization/entity/AnEntity.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.serialization.entity; +package org.hibernate.orm.test.serialization.entity; /** * The class should be in a package that is different from the test diff --git a/hibernate-core/src/test/java/org/hibernate/serialization/entity/PK.java b/hibernate-core/src/test/java/org/hibernate/orm/test/serialization/entity/PK.java similarity index 93% rename from hibernate-core/src/test/java/org/hibernate/serialization/entity/PK.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/serialization/entity/PK.java index 3d8df2b127..f94d2c5815 100644 --- a/hibernate-core/src/test/java/org/hibernate/serialization/entity/PK.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/serialization/entity/PK.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.serialization.entity; +package org.hibernate.orm.test.serialization.entity; /** * This class should be in a package that is different from the test diff --git a/hibernate-core/src/test/java/org/hibernate/service/ServiceContributorTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/service/ServiceContributorTest.java similarity index 98% rename from hibernate-core/src/test/java/org/hibernate/service/ServiceContributorTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/service/ServiceContributorTest.java index 0429e67ff5..7c7ab1c6ca 100644 --- a/hibernate-core/src/test/java/org/hibernate/service/ServiceContributorTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/service/ServiceContributorTest.java @@ -4,7 +4,7 @@ * 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.service; +package org.hibernate.orm.test.service; import java.util.Map; diff --git a/hibernate-core/src/test/java/org/hibernate/service/ServiceRegistryTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/service/ServiceRegistryTest.java similarity index 97% rename from hibernate-core/src/test/java/org/hibernate/service/ServiceRegistryTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/service/ServiceRegistryTest.java index 710d3efd0f..dbc4656d7a 100644 --- a/hibernate-core/src/test/java/org/hibernate/service/ServiceRegistryTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/service/ServiceRegistryTest.java @@ -1,4 +1,4 @@ -package org.hibernate.service; +package org.hibernate.orm.test.service; import java.util.Map; import java.util.concurrent.Callable; @@ -10,6 +10,9 @@ import java.util.concurrent.FutureTask; import org.hibernate.boot.registry.StandardServiceInitiator; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.service.NullServiceException; +import org.hibernate.service.Service; +import org.hibernate.service.ServiceRegistry; import org.hibernate.service.spi.Configurable; import org.hibernate.service.spi.ServiceRegistryAwareService; import org.hibernate.service.spi.ServiceRegistryImplementor; diff --git a/hibernate-core/src/test/java/org/hibernate/service/internal/ServiceRegistryClosingCascadeTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/service/internal/ServiceRegistryClosingCascadeTest.java similarity index 96% rename from hibernate-core/src/test/java/org/hibernate/service/internal/ServiceRegistryClosingCascadeTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/service/internal/ServiceRegistryClosingCascadeTest.java index b39d43171c..b8456bd313 100644 --- a/hibernate-core/src/test/java/org/hibernate/service/internal/ServiceRegistryClosingCascadeTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/service/internal/ServiceRegistryClosingCascadeTest.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.service.internal; +package org.hibernate.orm.test.service.internal; import org.hibernate.SessionFactory; import org.hibernate.boot.registry.BootstrapServiceRegistry; diff --git a/hibernate-core/src/test/java/org/hibernate/session/AssociateEntityWithTwoSessionsTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/session/AssociateEntityWithTwoSessionsTest.java similarity index 78% rename from hibernate-core/src/test/java/org/hibernate/session/AssociateEntityWithTwoSessionsTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/session/AssociateEntityWithTwoSessionsTest.java index 4ce935e7cd..97e36a6d3c 100644 --- a/hibernate-core/src/test/java/org/hibernate/session/AssociateEntityWithTwoSessionsTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/session/AssociateEntityWithTwoSessionsTest.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.session; +package org.hibernate.orm.test.session; import javax.persistence.Entity; import javax.persistence.FetchType; @@ -14,33 +14,30 @@ import javax.persistence.ManyToOne; import org.hibernate.Session; import org.hibernate.internal.CoreMessageLogger; -import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; import org.hibernate.proxy.AbstractLazyInitializer; import org.hibernate.testing.TestForIssue; import org.hibernate.testing.logger.LoggerInspectionRule; import org.hibernate.testing.logger.Triggerable; +import org.hibernate.testing.orm.junit.EntityManagerFactoryScope; +import org.hibernate.testing.orm.junit.Jpa; + import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.jboss.logging.Logger; -import static org.hibernate.testing.transaction.TransactionUtil.doInJPA; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; /** * @author Vlad Mihalcea */ -public class AssociateEntityWithTwoSessionsTest extends BaseEntityManagerFunctionalTestCase { - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { - Location.class, - Event.class - }; - } +@Jpa(annotatedClasses = { + AssociateEntityWithTwoSessionsTest.Location.class, + AssociateEntityWithTwoSessionsTest.Event.class +}) +public class AssociateEntityWithTwoSessionsTest { @Rule public LoggerInspectionRule logInspection = new LoggerInspectionRule( @@ -48,7 +45,7 @@ public class AssociateEntityWithTwoSessionsTest extends BaseEntityManagerFunctio @Test @TestForIssue( jiraKey = "HHH-12216" ) - public void test() { + public void test(EntityManagerFactoryScope scope) { final Location location = new Location(); location.setCity( "Cluj" ); @@ -56,7 +53,7 @@ public class AssociateEntityWithTwoSessionsTest extends BaseEntityManagerFunctio final Event event = new Event(); event.setLocation( location ); - doInJPA( this::entityManagerFactory, entityManager -> { + scope.inTransaction( entityManager -> { entityManager.persist( location ); entityManager.persist( event ); } ); @@ -64,12 +61,12 @@ public class AssociateEntityWithTwoSessionsTest extends BaseEntityManagerFunctio final Triggerable triggerable = logInspection.watchForLogMessages( "HHH000485" ); triggerable.reset(); - doInJPA( this::entityManagerFactory, entityManager -> { + scope.inTransaction( entityManager -> { Event event1 = entityManager.find( Event.class, event.id ); Location location1 = event1.getLocation(); try { - doInJPA( this::entityManagerFactory, _entityManager -> { + scope.inTransaction( _entityManager -> { _entityManager.unwrap( Session.class ).update( location1 ); } ); @@ -80,7 +77,7 @@ public class AssociateEntityWithTwoSessionsTest extends BaseEntityManagerFunctio } ); assertEquals( - "HHH000485: Illegally attempted to associate a proxy for entity [org.hibernate.session.AssociateEntityWithTwoSessionsTest$Location] with id [1] with two open sessions.", + "HHH000485: Illegally attempted to associate a proxy for entity [org.hibernate.orm.test.session.AssociateEntityWithTwoSessionsTest$Location] with id [1] with two open sessions.", triggerable.triggerMessage() ); diff --git a/hibernate-core/src/test/java/org/hibernate/sharedSession/SessionWithSharedConnectionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/sharedSession/SessionWithSharedConnectionTest.java similarity index 71% rename from hibernate-core/src/test/java/org/hibernate/sharedSession/SessionWithSharedConnectionTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/sharedSession/SessionWithSharedConnectionTest.java index 079aea8e59..d4b44d5df7 100644 --- a/hibernate-core/src/test/java/org/hibernate/sharedSession/SessionWithSharedConnectionTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/sharedSession/SessionWithSharedConnectionTest.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.sharedSession; +package org.hibernate.orm.test.sharedSession; import org.hibernate.FlushMode; import org.hibernate.IrrelevantEntity; @@ -18,8 +18,9 @@ import org.hibernate.persister.entity.EntityPersister; import org.hibernate.resource.jdbc.spi.JdbcSessionOwner; import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; -import org.junit.Test; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; import java.lang.reflect.Field; import java.util.Collection; @@ -27,6 +28,8 @@ import java.util.Collection; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; +import org.junit.jupiter.api.Test; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -36,11 +39,13 @@ import static org.junit.Assert.assertTrue; /** * @author Steve Ebersole */ -public class SessionWithSharedConnectionTest extends BaseCoreFunctionalTestCase { +@DomainModel(annotatedClasses = IrrelevantEntity.class) +@SessionFactory +public class SessionWithSharedConnectionTest { @Test @TestForIssue( jiraKey = "HHH-7090" ) - public void testSharedTransactionContextSessionClosing() { - Session session = sessionFactory().openSession(); + public void testSharedTransactionContextSessionClosing(SessionFactoryScope scope) { + Session session = scope.getSessionFactory().openSession(); session.getTransaction().begin(); Session secondSession = session.sessionWithOptions() @@ -81,8 +86,8 @@ public class SessionWithSharedConnectionTest extends BaseCoreFunctionalTestCase @Test @TestForIssue( jiraKey = "HHH-7090" ) - public void testSharedTransactionContextAutoClosing() { - Session session = sessionFactory().openSession(); + public void testSharedTransactionContextAutoClosing(SessionFactoryScope scope) { + Session session = scope.getSessionFactory().openSession(); session.getTransaction().begin(); // COMMIT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -108,7 +113,7 @@ public class SessionWithSharedConnectionTest extends BaseCoreFunctionalTestCase // ROLLBACK ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - session = sessionFactory().openSession(); + session = scope.getSessionFactory().openSession(); session.getTransaction().begin(); secondSession = session.sessionWithOptions() @@ -134,7 +139,7 @@ public class SessionWithSharedConnectionTest extends BaseCoreFunctionalTestCase // @Test // @TestForIssue( jiraKey = "HHH-7090" ) // public void testSharedTransactionContextAutoJoining() { -// Session session = sessionFactory().openSession(); +// Session session = scope.getSessionFactory().openSession(); // session.getTransaction().begin(); // // Session secondSession = session.sessionWithOptions() @@ -151,8 +156,8 @@ public class SessionWithSharedConnectionTest extends BaseCoreFunctionalTestCase @Test @TestForIssue( jiraKey = "HHH-7090" ) - public void testSharedTransactionContextFlushBeforeCompletion() { - Session session = sessionFactory().openSession(); + public void testSharedTransactionContextFlushBeforeCompletion(SessionFactoryScope scope) { + Session session = scope.getSessionFactory().openSession(); session.getTransaction().begin(); Session secondSession = session.sessionWithOptions() @@ -174,7 +179,7 @@ public class SessionWithSharedConnectionTest extends BaseCoreFunctionalTestCase assertTrue( ((SessionImplementor) session).isClosed() ); assertTrue( ((SessionImplementor) secondSession).isClosed() ); - session = sessionFactory().openSession(); + session = scope.getSessionFactory().openSession(); session.getTransaction().begin(); IrrelevantEntity it = (IrrelevantEntity) session.byId( IrrelevantEntity.class ).load( id ); assertNotNull( it ); @@ -185,12 +190,12 @@ public class SessionWithSharedConnectionTest extends BaseCoreFunctionalTestCase @Test @TestForIssue( jiraKey = "HHH-7239" ) - public void testChildSessionCallsAfterTransactionAction() throws Exception { - Session session = openSession(); + public void testChildSessionCallsAfterTransactionAction(SessionFactoryScope scope) throws Exception { + Session session = scope.getSessionFactory().openSession(); final String postCommitMessage = "post commit was called"; - EventListenerRegistry eventListenerRegistry = sessionFactory().getServiceRegistry().getService(EventListenerRegistry.class); + EventListenerRegistry eventListenerRegistry = scope.getSessionFactory().getServiceRegistry().getService(EventListenerRegistry.class); //register a post commit listener eventListenerRegistry.appendListeners( EventType.POST_COMMIT_INSERT, @@ -206,13 +211,13 @@ public class SessionWithSharedConnectionTest extends BaseCoreFunctionalTestCase } } ); - + session.getTransaction().begin(); - + IrrelevantEntity irrelevantEntityMainSession = new IrrelevantEntity(); irrelevantEntityMainSession.setName( "main session" ); session.save( irrelevantEntityMainSession ); - + //open secondary session to also insert an entity Session secondSession = session.sessionWithOptions() .connection() @@ -233,8 +238,8 @@ public class SessionWithSharedConnectionTest extends BaseCoreFunctionalTestCase @Test @TestForIssue( jiraKey = "HHH-7239" ) - public void testChildSessionTwoTransactions() throws Exception { - Session session = openSession(); + public void testChildSessionTwoTransactions(SessionFactoryScope scope) throws Exception { + Session session = scope.getSessionFactory().openSession(); session.getTransaction().begin(); @@ -257,52 +262,58 @@ public class SessionWithSharedConnectionTest extends BaseCoreFunctionalTestCase @Test @TestForIssue(jiraKey = "HHH-11830") - public void testSharedSessionTransactionObserver() throws Exception { - Session session = openSession(); - - session.getTransaction().begin(); - - Field field = null; - Class clazz = ((JdbcSessionOwner) session).getTransactionCoordinator().getClass(); - while (clazz != null) { - try { - field = clazz.getDeclaredField("observers"); - field.setAccessible(true); - break; - } catch (NoSuchFieldException e) { - clazz = clazz.getSuperclass(); - } catch (Exception e) { - throw new IllegalStateException(e); + public void testSharedSessionTransactionObserver(SessionFactoryScope scope) throws Exception { + scope.inTransaction( session -> { + Field field = null; + Class clazz = ( (JdbcSessionOwner) session ).getTransactionCoordinator().getClass(); + while ( clazz != null ) { + try { + field = clazz.getDeclaredField( "observers" ); + field.setAccessible( true ); + break; + } + catch (NoSuchFieldException e) { + clazz = clazz.getSuperclass(); + } + catch (Exception e) { + throw new IllegalStateException( e ); + } } - } - assertNotNull("Observers field was not found", field); + assertNotNull( "Observers field was not found", field ); - //Some of these collections could be lazily initialize: check for null before invoking size() - final Collection collection = (Collection) field.get( ( (SessionImplementor) session ).getTransactionCoordinator() ); - assertTrue(collection == null || collection.size() == 0 ); + try { + //Some of these collections could be lazily initialize: check for null before invoking size() + final Collection collection = (Collection) field.get( session.getTransactionCoordinator() ); + assertTrue( collection == null || collection.size() == 0 ); - //open secondary sessions with managed options and immediately close - Session secondarySession; - for (int i = 0; i < 10; i++){ - secondarySession = session.sessionWithOptions() - .connection() - .flushMode( FlushMode.COMMIT ) - .autoClose( true ) - .openSession(); + //open secondary sessions with managed options and immediately close + Session secondarySession; + for ( int i = 0; i < 10; i++ ) { + secondarySession = session.sessionWithOptions() + .connection() + .flushMode( FlushMode.COMMIT ) + .autoClose( true ) + .openSession(); - //when the shared session is opened it should register an observer - assertEquals(1, ((Collection) field.get(((JdbcSessionOwner) session).getTransactionCoordinator())).size()); + //when the shared session is opened it should register an observer + assertEquals( + 1, + ( (Collection) field.get( session.getTransactionCoordinator() ) ).size() + ); - //observer should be released - secondarySession.close(); + //observer should be released + secondarySession.close(); - assertEquals(0, ((Collection) field.get(((JdbcSessionOwner) session).getTransactionCoordinator())).size()); - } + assertEquals( + 0, + ( (Collection) field.get( session.getTransactionCoordinator() ) ).size() + ); + } + } + catch (Exception e) { + throw new IllegalStateException( e ); + } + } ); } - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { IrrelevantEntity.class }; - } } diff --git a/hibernate-core/src/test/java/org/hibernate/stat/internal/ConcurrentQueryStatisticsTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/stat/internal/ConcurrentQueryStatisticsTest.java similarity index 92% rename from hibernate-core/src/test/java/org/hibernate/stat/internal/ConcurrentQueryStatisticsTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/stat/internal/ConcurrentQueryStatisticsTest.java index 78e1173e6a..c526b3fdfa 100644 --- a/hibernate-core/src/test/java/org/hibernate/stat/internal/ConcurrentQueryStatisticsTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/stat/internal/ConcurrentQueryStatisticsTest.java @@ -4,7 +4,9 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.stat.internal; +package org.hibernate.orm.test.stat.internal; + +import org.hibernate.stat.internal.QueryStatisticsImpl; import org.hibernate.testing.junit4.BaseUnitTestCase; import org.junit.Test; diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/stat/internal/ConcurrentStatisticsTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/stat/internal/ConcurrentStatisticsTest.java new file mode 100644 index 0000000000..2c4476adf5 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/stat/internal/ConcurrentStatisticsTest.java @@ -0,0 +1,45 @@ +/* + * 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 . + */ +package org.hibernate.orm.test.stat.internal; + +import org.hibernate.cfg.Environment; +import org.hibernate.internal.util.StringHelper; +import org.hibernate.stat.SecondLevelCacheStatistics; +import org.hibernate.stat.internal.StatisticsImpl; + +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.ServiceRegistry; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.hibernate.testing.orm.junit.Setting; + +import org.junit.jupiter.api.Test; + +import static org.hamcrest.core.Is.is; +import static org.hamcrest.core.IsNull.nullValue; +import static org.junit.Assert.assertThat; + +/** + * @author Andrea Boriero + */ +@DomainModel +@ServiceRegistry(settings = { + @Setting( name = Environment.CACHE_REGION_PREFIX, value = ConcurrentStatisticsTest.REGION_PREFIX), + @Setting( name = Environment.USE_SECOND_LEVEL_CACHE, value = "false") +}) +@SessionFactory +public class ConcurrentStatisticsTest { + static final String REGION_PREFIX = "my-app"; + static final String TRIVIAL_REGION_NAME = "noname"; + + @Test + public void testThatGetSecondLevelCacheStatisticsWhenSecondLevelCacheIsNotEnabledReturnsNull(SessionFactoryScope scope) { + final SecondLevelCacheStatistics secondLevelCacheStatistics = new StatisticsImpl( scope.getSessionFactory() ) + .getSecondLevelCacheStatistics( StringHelper.qualify( REGION_PREFIX, TRIVIAL_REGION_NAME ) ); + assertThat( secondLevelCacheStatistics, is( nullValue() ) ); + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/stat/internal/QueryPlanCacheStatisticsTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/stat/internal/QueryPlanCacheStatisticsTest.java similarity index 81% rename from hibernate-core/src/test/java/org/hibernate/stat/internal/QueryPlanCacheStatisticsTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/stat/internal/QueryPlanCacheStatisticsTest.java index 5974b976b0..efef340396 100644 --- a/hibernate-core/src/test/java/org/hibernate/stat/internal/QueryPlanCacheStatisticsTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/stat/internal/QueryPlanCacheStatisticsTest.java @@ -4,11 +4,9 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.stat.internal; +package org.hibernate.orm.test.stat.internal; import java.util.List; -import java.util.Map; - import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @@ -17,15 +15,20 @@ import javax.persistence.NamedQuery; import javax.persistence.Tuple; import javax.persistence.TypedQuery; -import org.hibernate.SessionFactory; import org.hibernate.cfg.Environment; -import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; import org.hibernate.stat.QueryStatistics; import org.hibernate.stat.Statistics; -import org.hibernate.testing.TestForIssue; -import org.junit.Test; -import static org.hibernate.testing.transaction.TransactionUtil.doInJPA; +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.ServiceRegistry; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.hibernate.testing.orm.junit.Setting; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -33,33 +36,24 @@ import static org.junit.Assert.assertTrue; /** * @author Gail Badner */ +@DomainModel(annotatedClasses = { + QueryPlanCacheStatisticsTest.Employee.class +}) +@ServiceRegistry(settings = { + @Setting( name = Environment.GENERATE_STATISTICS, value = "true") +}) +@SessionFactory @TestForIssue(jiraKey = "HHH-12855") -public class QueryPlanCacheStatisticsTest extends BaseEntityManagerFunctionalTestCase { +public class QueryPlanCacheStatisticsTest { private Statistics statistics; - @Override - public Class[] getAnnotatedClasses() { - return new Class[] { - Employee.class - }; - } + @BeforeAll + protected void afterEntityManagerFactoryBuilt(SessionFactoryScope scope) { + statistics = scope.getSessionFactory().getStatistics(); - @Override - protected void addConfigOptions(Map options) { - options.put( Environment.GENERATE_STATISTICS, "true" ); - } - - @Override - protected void afterEntityManagerFactoryBuilt() { - SessionFactory sessionFactory = entityManagerFactory().unwrap( SessionFactory.class ); - statistics = sessionFactory.getStatistics(); - - doInJPA( this::entityManagerFactory, entityManager -> { + scope.inTransaction( entityManager -> { for ( long i = 1; i <= 5; i++ ) { - if ( i % 3 == 0 ) { - entityManager.flush(); - } Employee employee = new Employee(); employee.setName( String.format( "Employee: %d", i ) ); entityManager.persist( employee ); @@ -67,14 +61,18 @@ public class QueryPlanCacheStatisticsTest extends BaseEntityManagerFunctionalTes } ); } - @Test - public void test() { - + @BeforeEach + protected void cleanup(SessionFactoryScope scope) { + scope.getSessionFactory().getQueryEngine().getInterpretationCache().close(); statistics.clear(); + } + + @Test + public void test(SessionFactoryScope scope) { assertEquals( 0, statistics.getQueryPlanCacheHitCount() ); assertEquals( 0, statistics.getQueryPlanCacheMissCount() ); - doInJPA( this::entityManagerFactory, entityManager -> { + scope.inTransaction( entityManager -> { final String FIRST_QUERY = "select e from Employee e"; entityManager.createQuery( FIRST_QUERY ); @@ -125,10 +123,8 @@ public class QueryPlanCacheStatisticsTest extends BaseEntityManagerFunctionalTes @Test @TestForIssue( jiraKey = "HHH-13077" ) - public void testCreateQueryHitCount() { - statistics.clear(); - - doInJPA( this::entityManagerFactory, entityManager -> { + public void testCreateQueryHitCount(SessionFactoryScope scope) { + scope.inTransaction( entityManager -> { List employees = entityManager.createQuery( "select e from Employee e", Employee.class ) @@ -142,7 +138,7 @@ public class QueryPlanCacheStatisticsTest extends BaseEntityManagerFunctionalTes assertEquals( 0, statistics.getQueryPlanCacheHitCount() ); } ); - doInJPA( this::entityManagerFactory, entityManager -> { + scope.inTransaction( entityManager -> { List employees = entityManager.createQuery( "select e from Employee e", Employee.class ) @@ -156,7 +152,7 @@ public class QueryPlanCacheStatisticsTest extends BaseEntityManagerFunctionalTes assertEquals( 1, statistics.getQueryPlanCacheHitCount() ); } ); - doInJPA( this::entityManagerFactory, entityManager -> { + scope.inTransaction( entityManager -> { List employees = entityManager.createQuery( "select e from Employee e", Employee.class ) @@ -173,12 +169,11 @@ public class QueryPlanCacheStatisticsTest extends BaseEntityManagerFunctionalTes @Test @TestForIssue( jiraKey = "HHH-13077" ) - public void testCreateNamedQueryHitCount() { - //This is for the NamedQuery that gets compiled - assertEquals( 1, statistics.getQueryPlanCacheMissCount() ); + public void testCreateNamedQueryHitCount(SessionFactoryScope scope) { + // Compile the named queries + scope.getSessionFactory().getQueryEngine().getNamedObjectRepository().checkNamedQueries( scope.getSessionFactory().getQueryEngine() ); statistics.clear(); - - doInJPA( this::entityManagerFactory, entityManager -> { + scope.inTransaction( entityManager -> { Employee employees = entityManager.createNamedQuery( "find_employee_by_name", Employee.class ) @@ -191,7 +186,7 @@ public class QueryPlanCacheStatisticsTest extends BaseEntityManagerFunctionalTes assertEquals( 1, statistics.getQueryPlanCacheHitCount() ); } ); - doInJPA( this::entityManagerFactory, entityManager -> { + scope.inTransaction( entityManager -> { Employee employees = entityManager.createNamedQuery( "find_employee_by_name", Employee.class ) @@ -207,10 +202,8 @@ public class QueryPlanCacheStatisticsTest extends BaseEntityManagerFunctionalTes @Test @TestForIssue( jiraKey = "HHH-13077" ) - public void testCreateQueryTupleHitCount() { - statistics.clear(); - - doInJPA( this::entityManagerFactory, entityManager -> { + public void testCreateQueryTupleHitCount(SessionFactoryScope scope) { + scope.inTransaction( entityManager -> { List employees = entityManager.createQuery( "select e.id, e.name from Employee e", Tuple.class ) @@ -224,7 +217,7 @@ public class QueryPlanCacheStatisticsTest extends BaseEntityManagerFunctionalTes assertEquals( 0, statistics.getQueryPlanCacheHitCount() ); } ); - doInJPA( this::entityManagerFactory, entityManager -> { + scope.inTransaction( entityManager -> { List employees = entityManager.createQuery( "select e.id, e.name from Employee e", Tuple.class ) @@ -238,7 +231,7 @@ public class QueryPlanCacheStatisticsTest extends BaseEntityManagerFunctionalTes assertEquals( 1, statistics.getQueryPlanCacheHitCount() ); } ); - doInJPA( this::entityManagerFactory, entityManager -> { + scope.inTransaction( entityManager -> { List employees = entityManager.createQuery( "select e.id, e.name from Employee e", Tuple.class ) @@ -255,10 +248,8 @@ public class QueryPlanCacheStatisticsTest extends BaseEntityManagerFunctionalTes @Test @TestForIssue(jiraKey = "HHH-13077") - public void testLockModeHitCount() { - statistics.clear(); - - doInJPA( this::entityManagerFactory, entityManager -> { + public void testLockModeHitCount(SessionFactoryScope scope) { + scope.inTransaction( entityManager -> { TypedQuery typedQuery = entityManager.createQuery( "select e from Employee e", Employee.class ); List employees = typedQuery.getResultList(); diff --git a/hibernate-core/src/test/java/org/hibernate/stat/internal/StatsNamedContainerNullComputedValueTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/stat/internal/StatsNamedContainerNullComputedValueTest.java similarity index 87% rename from hibernate-core/src/test/java/org/hibernate/stat/internal/StatsNamedContainerNullComputedValueTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/stat/internal/StatsNamedContainerNullComputedValueTest.java index afd5b1088d..08da2701b1 100644 --- a/hibernate-core/src/test/java/org/hibernate/stat/internal/StatsNamedContainerNullComputedValueTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/stat/internal/StatsNamedContainerNullComputedValueTest.java @@ -4,7 +4,9 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.stat.internal; +package org.hibernate.orm.test.stat.internal; + +import org.hibernate.stat.internal.StatsNamedContainer; import org.hibernate.testing.TestForIssue; import org.junit.Test; diff --git a/hibernate-core/src/test/java/org/hibernate/persister/entity/FormulaTemplateSchemaSubstitutionTest.java b/hibernate-core/src/test/java/org/hibernate/persister/entity/FormulaTemplateSchemaSubstitutionTest.java deleted file mode 100644 index 967f0de7f5..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/persister/entity/FormulaTemplateSchemaSubstitutionTest.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 . - */ -package org.hibernate.persister.entity; - -import java.util.Properties; - -import org.hibernate.cfg.Configuration; -import org.hibernate.dialect.H2Dialect; - -import org.hibernate.testing.RequiresDialect; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; -import org.junit.Test; - -import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -@RequiresDialect(H2Dialect.class) -public class FormulaTemplateSchemaSubstitutionTest extends AbstractSchemaSubstitutionFormulaTest { - - private static final String CUSTOM_SCHEMA = "CUSTOM_SCHEMA"; - - @Override - protected void configure(Configuration configuration) { - final Properties properties = new Properties(); - properties.put( "hibernate.default_schema", CUSTOM_SCHEMA ); - configuration.addProperties( properties ); - } - - @Override - protected String createSecondSchema() { - return CUSTOM_SCHEMA; - } - - @Override - void validate(String formula) { - assertEquals( "Formula should not contain {} characters", - 4, formula.split( CUSTOM_SCHEMA + ".", -1 ).length - 1 - ); - } -} diff --git a/hibernate-core/src/test/java/org/hibernate/procedure/internal/ProcedureCallImplTest.java b/hibernate-core/src/test/java/org/hibernate/procedure/internal/ProcedureCallImplTest.java deleted file mode 100644 index 0b89867ee2..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/procedure/internal/ProcedureCallImplTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.hibernate.procedure.internal; - -import java.util.stream.Stream; -import javax.persistence.EntityManager; -import javax.persistence.Query; -import org.hibernate.dialect.H2Dialect; -import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; -import org.hibernate.testing.RequiresDialect; -import org.hibernate.testing.TestForIssue; -import org.junit.Assert; -import org.junit.Test; - -/** - * @author Nathan Xu - */ -public class ProcedureCallImplTest extends BaseEntityManagerFunctionalTestCase { - - @Test - @TestForIssue( jiraKey = "HHH-13644" ) - @RequiresDialect( H2Dialect.class ) - public void testNoNullPointerExceptionThrown() { - - EntityManager em = getOrCreateEntityManager(); - - em.getTransaction().begin(); - - em.createNativeQuery("CREATE ALIAS GET_RANDOM_VALUE FOR \"java.lang.Math.random\";").executeUpdate(); - - Query query = em.createStoredProcedureQuery("GET_RANDOM_VALUE"); - - Stream stream = query.getResultStream(); - - Assert.assertEquals(1, stream.count()); - - em.getTransaction().commit(); - - em.close(); - } -} diff --git a/hibernate-core/src/test/java/org/hibernate/property/DirectPropertyAccessorTest.java b/hibernate-core/src/test/java/org/hibernate/property/DirectPropertyAccessorTest.java deleted file mode 100644 index 8fb4c74b73..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/property/DirectPropertyAccessorTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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 . - */ -package org.hibernate.property; - -import org.junit.Test; - -import org.hibernate.Hibernate; -import org.hibernate.Session; -import org.hibernate.Transaction; -import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -/** - * @author Michael Rudolf - */ -public class DirectPropertyAccessorTest extends BaseCoreFunctionalTestCase { - @Test - @TestForIssue( jiraKey="HHH-3718" ) - public void testDirectIdPropertyAccess() throws Exception { - Session s = openSession(); - final Transaction transaction = s.beginTransaction(); - Item i = new Item(); - s.persist( i ); - Order o = new Order(); - o.setOrderNumber( 1 ); - o.getItems().add( i ); - s.persist( o ); - transaction.commit(); - s.clear(); - - o = ( Order ) s.load( Order.class, 1 ); - assertFalse( Hibernate.isInitialized( o ) ); - o.getOrderNumber(); - // If you mapped with field access, any method, except id, call initializes the proxy - assertFalse( Hibernate.isInitialized( o ) ); - o.getName(); - assertTrue( Hibernate.isInitialized( o ) ); - s.close(); - } - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { - Order.class, - Item.class, - }; - } -} diff --git a/hibernate-core/src/test/java/org/hibernate/stat/internal/ConcurrentStatisticsTest.java b/hibernate-core/src/test/java/org/hibernate/stat/internal/ConcurrentStatisticsTest.java deleted file mode 100644 index e843504cfa..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/stat/internal/ConcurrentStatisticsTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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 . - */ -package org.hibernate.stat.internal; - -import org.hibernate.SessionFactory; -import org.hibernate.cfg.AvailableSettings; -import org.hibernate.cfg.Configuration; -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.internal.util.StringHelper; -import org.hibernate.stat.SecondLevelCacheStatistics; - -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import static org.hamcrest.core.Is.is; -import static org.hamcrest.core.IsNull.nullValue; -import static org.junit.Assert.assertThat; - -/** - * @author Andrea Boriero - */ -public class ConcurrentStatisticsTest extends BaseCoreFunctionalTestCase { - private static final String REGION_PREFIX = "my-app"; - private static final String TRIVIAL_REGION_NAME = "noname"; - - private StatisticsImpl statistics; - private SessionFactory sessionFactory; - - @Before - public void setUp() { - sessionFactory = sessionFactory(); - statistics = new StatisticsImpl( (SessionFactoryImplementor) sessionFactory ); - } - - @Override - protected void configure(Configuration configuration) { - super.configure( configuration ); - configuration.setProperty( AvailableSettings.CACHE_REGION_PREFIX, REGION_PREFIX ); - configuration.setProperty( AvailableSettings.USE_SECOND_LEVEL_CACHE, "false" ); - } - - @After - public void tearDown() { - sessionFactory.close(); - } - - @Test - public void testThatGetSecondLevelCacheStatisticsWhenSecondLevelCacheIsNotEnabledReturnsNull() { - final SecondLevelCacheStatistics secondLevelCacheStatistics = statistics - .getSecondLevelCacheStatistics( StringHelper.qualify( REGION_PREFIX, TRIVIAL_REGION_NAME ) ); - assertThat( secondLevelCacheStatistics, is( nullValue() ) ); - } -} diff --git a/hibernate-core/src/test/resources/org/hibernate/test/serialization/DynamicMapMappings.hbm.xml b/hibernate-core/src/test/resources/org/hibernate/orm/test/serialization/DynamicMapMappings.hbm.xml similarity index 96% rename from hibernate-core/src/test/resources/org/hibernate/test/serialization/DynamicMapMappings.hbm.xml rename to hibernate-core/src/test/resources/org/hibernate/orm/test/serialization/DynamicMapMappings.hbm.xml index dff71b2c79..6dd508df3a 100644 --- a/hibernate-core/src/test/resources/org/hibernate/test/serialization/DynamicMapMappings.hbm.xml +++ b/hibernate-core/src/test/resources/org/hibernate/orm/test/serialization/DynamicMapMappings.hbm.xml @@ -1,33 +1,33 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hibernate-core/src/test/resources/org/hibernate/property/TheEntity.hbm.xml b/hibernate-core/src/test/resources/org/hibernate/property/TheEntity.hbm.xml index 84ae7abf0f..ff100dd647 100644 --- a/hibernate-core/src/test/resources/org/hibernate/property/TheEntity.hbm.xml +++ b/hibernate-core/src/test/resources/org/hibernate/property/TheEntity.hbm.xml @@ -6,7 +6,7 @@ ~ See the lgpl.txt file in the root directory or . --> - + \ No newline at end of file diff --git a/hibernate-testing/hibernate-testing.gradle b/hibernate-testing/hibernate-testing.gradle index bc69724dba..3c7f7aa023 100644 --- a/hibernate-testing/hibernate-testing.gradle +++ b/hibernate-testing/hibernate-testing.gradle @@ -35,11 +35,6 @@ dependencies { testRuntime( libraries.log4j ) } -// resources inherently exclude sources -sourceSets.test.resources { - setSrcDirs( ['src/test/java'] ) -} - // todo : Fold into hibernate-core and publish in separate publications // once http://issues.gradle.org/browse/GRADLE-2966 is resolved; // that will allow us to keep the same artifactId and publish the pom diff --git a/hibernate-testing/src/test/java/org/hibernate/testing/annotations/BasicEntityManagerFactoryScopeTests.java b/hibernate-testing/src/test/java/org/hibernate/testing/annotations/BasicEntityManagerFactoryScopeTests.java index 21d0b5f768..bf9d6f750c 100644 --- a/hibernate-testing/src/test/java/org/hibernate/testing/annotations/BasicEntityManagerFactoryScopeTests.java +++ b/hibernate-testing/src/test/java/org/hibernate/testing/annotations/BasicEntityManagerFactoryScopeTests.java @@ -6,11 +6,8 @@ */ package org.hibernate.testing.annotations; -import org.hibernate.cfg.AvailableSettings; - -import org.hibernate.testing.orm.junit.Jpa; import org.hibernate.testing.orm.junit.EntityManagerFactoryScope; -import org.hibernate.testing.orm.junit.Setting; +import org.hibernate.testing.orm.junit.Jpa; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; @@ -19,16 +16,7 @@ import static org.hamcrest.Matchers.notNullValue; @Jpa( annotatedClasses = { AnEntity.class - }, - properties = { - @Setting( name = AvailableSettings.JPA_JDBC_URL, value = "jdbc:h2:mem:test_db" ), - @Setting( name = AvailableSettings.JPA_JDBC_USER, value = "tester" ) } -// works with either -// integrationSettings = { -// @Setting( name = AvailableSettings.JPA_JDBC_URL, value = "jdbc:h2:mem:test_db" ), -// @Setting( name = AvailableSettings.JPA_JDBC_USER, value = "tester" ) -// } ) public class BasicEntityManagerFactoryScopeTests { @Test diff --git a/hibernate-testing/src/test/java/org/hibernate/testing/annotations/BasicSessionFactoryScopeTests.java b/hibernate-testing/src/test/java/org/hibernate/testing/annotations/BasicSessionFactoryScopeTests.java index 74638a337f..77851c72f0 100644 --- a/hibernate-testing/src/test/java/org/hibernate/testing/annotations/BasicSessionFactoryScopeTests.java +++ b/hibernate-testing/src/test/java/org/hibernate/testing/annotations/BasicSessionFactoryScopeTests.java @@ -6,19 +6,18 @@ */ package org.hibernate.testing.annotations; -import org.hibernate.cfg.AvailableSettings; +import org.hibernate.dialect.H2Dialect; import org.hibernate.testing.orm.junit.DomainModel; -import org.hibernate.testing.orm.junit.ServiceRegistry; +import org.hibernate.testing.orm.junit.RequiresDialect; import org.hibernate.testing.orm.junit.SessionFactory; import org.hibernate.testing.orm.junit.SessionFactoryScope; -import org.hibernate.testing.orm.junit.Setting; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.notNullValue; -@ServiceRegistry( settings = @Setting( name = AvailableSettings.URL, value = "jdbc:h2:mem:test_db" ) ) +@RequiresDialect(H2Dialect.class) @DomainModel( annotatedClasses = AnEntity.class ) @SessionFactory public class BasicSessionFactoryScopeTests { diff --git a/hibernate-testing/src/test/resources/hibernate.properties b/hibernate-testing/src/test/resources/hibernate.properties new file mode 100644 index 0000000000..df1e7e1fb6 --- /dev/null +++ b/hibernate-testing/src/test/resources/hibernate.properties @@ -0,0 +1,27 @@ +# +# 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 . +# + +hibernate.dialect @db.dialect@ +hibernate.connection.driver_class @jdbc.driver@ +hibernate.connection.url @jdbc.url@ +hibernate.connection.username @jdbc.user@ +hibernate.connection.password @jdbc.pass@ + +hibernate.connection.pool_size 5 + +hibernate.show_sql false +hibernate.format_sql true + +hibernate.max_fetch_depth 5 + +hibernate.cache.region_prefix hibernate.test +hibernate.cache.region.factory_class org.hibernate.testing.cache.CachingRegionFactory + +javax.persistence.validation.mode=NONE +hibernate.service.allow_crawling=false +hibernate.session.events.log=true +hibernate.hql.bulk_id_strategy.global_temporary.drop_tables=true