diff --git a/gradle/libraries.gradle b/gradle/libraries.gradle index 8baca56d6f..cb77eaa309 100644 --- a/gradle/libraries.gradle +++ b/gradle/libraries.gradle @@ -27,7 +27,7 @@ ext { weldVersion = '3.1.5.Final' jakartaWeldVersion = '4.0.1.SP1' - byteBuddyVersion = '1.11.16' + byteBuddyVersion = '1.11.20' agroalVersion = '1.9' diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/CollectionType.java b/hibernate-core/src/main/java/org/hibernate/annotations/CollectionType.java index 0bd221dbf9..3a2706f369 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/CollectionType.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/CollectionType.java @@ -20,9 +20,12 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; * @see org.hibernate.usertype.UserCollectionType * * @author Steve Ebersole + * + * @deprecated Custom handling for "collection types" will be handled differently in 6.0 */ @java.lang.annotation.Target({FIELD, METHOD}) @Retention(RUNTIME) +@Deprecated public @interface CollectionType { /** * Names the type. 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 6efe2a6913..269764c397 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 @@ -65,7 +65,6 @@ import org.hibernate.cfg.CreateKeySecondPass; import org.hibernate.cfg.FkSecondPass; import org.hibernate.cfg.IdGeneratorResolverSecondPass; import org.hibernate.cfg.JPAIndexHolder; -import org.hibernate.cfg.PkDrivenByDefaultMapsIdSecondPass; import org.hibernate.cfg.PropertyData; import org.hibernate.cfg.QuerySecondPass; import org.hibernate.cfg.RecoverableException; @@ -1520,7 +1519,6 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector } private ArrayList idGeneratorResolverSecondPassList; - private ArrayList pkDrivenByDefaultMapsIdSecondPassList; private ArrayList setBasicValueTypeSecondPassList; private ArrayList copyIdentifierComponentSecondPasList; private ArrayList fkSecondPassList; @@ -1541,9 +1539,6 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector if ( secondPass instanceof IdGeneratorResolverSecondPass ) { addIdGeneratorResolverSecondPass( (IdGeneratorResolverSecondPass) secondPass, onTopOfTheQueue ); } - else if ( secondPass instanceof PkDrivenByDefaultMapsIdSecondPass ) { - addPkDrivenByDefaultMapsIdSecondPass( (PkDrivenByDefaultMapsIdSecondPass) secondPass, onTopOfTheQueue ); - } else if ( secondPass instanceof SetBasicValueTypeSecondPass ) { addSetBasicValueTypeSecondPass( (SetBasicValueTypeSecondPass) secondPass, onTopOfTheQueue ); } @@ -1574,15 +1569,6 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector } } - private void addPkDrivenByDefaultMapsIdSecondPass( - PkDrivenByDefaultMapsIdSecondPass secondPass, - boolean onTopOfTheQueue) { - if ( pkDrivenByDefaultMapsIdSecondPassList == null ) { - pkDrivenByDefaultMapsIdSecondPassList = new ArrayList<>(); - } - addSecondPass( secondPass, pkDrivenByDefaultMapsIdSecondPassList, onTopOfTheQueue ); - } - private void addSecondPass(T secondPass, ArrayList secondPassList, boolean onTopOfTheQueue) { if ( onTopOfTheQueue ) { secondPassList.add( 0, secondPass ); @@ -1663,7 +1649,6 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector try { processSecondPasses( idGeneratorResolverSecondPassList ); processSecondPasses( implicitColumnNamingSecondPassList ); - processSecondPasses( pkDrivenByDefaultMapsIdSecondPassList ); processSecondPasses( setBasicValueTypeSecondPassList ); composites.forEach( Component::sortProperties ); 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 c838f1ad01..3ffaeb4e96 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 @@ -409,7 +409,7 @@ public class MetadataImpl implements MetadataImplementor, Serializable { final ConfigurationService cfgService = sessionFactoryServiceRegistry.getService( ConfigurationService.class ); final ClassLoaderService classLoaderService = sessionFactoryServiceRegistry.getService( ClassLoaderService.class ); - for ( Map.Entry entry : ( (Map) cfgService.getSettings() ).entrySet() ) { + for ( Map.Entry entry : ( (Map) cfgService.getSettings() ).entrySet() ) { if ( !String.class.isInstance( entry.getKey() ) ) { continue; } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryOptionsBuilder.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryOptionsBuilder.java index e0a40fce03..44d30b066b 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryOptionsBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryOptionsBuilder.java @@ -528,6 +528,7 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions { configurationSettings, false ); + Object jdbcTimeZoneValue = configurationSettings.get( JDBC_TIME_ZONE ); diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/PkDrivenByDefaultMapsIdSecondPass.java b/hibernate-core/src/main/java/org/hibernate/cfg/PkDrivenByDefaultMapsIdSecondPass.java index ca4ac36e28..07f69c89d2 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/PkDrivenByDefaultMapsIdSecondPass.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/PkDrivenByDefaultMapsIdSecondPass.java @@ -16,17 +16,31 @@ import org.hibernate.mapping.SimpleValue; /** * @author Emmanuel Bernard */ -public class PkDrivenByDefaultMapsIdSecondPass implements SecondPass { +public class PkDrivenByDefaultMapsIdSecondPass extends FkSecondPass { private final String referencedEntityName; private final Ejb3JoinColumn[] columns; private final SimpleValue value; public PkDrivenByDefaultMapsIdSecondPass(String referencedEntityName, Ejb3JoinColumn[] columns, SimpleValue value) { + super( value, columns ); this.referencedEntityName = referencedEntityName; this.columns = columns; this.value = value; } + @Override + public String getReferencedEntityName() { + return referencedEntityName; + } + + @Override + public boolean isInPrimaryKey() { + // @MapsId is not itself in the primary key, + // so it's safe to simply process it after all the primary keys have been processed. + return true; + } + + @Override public void doSecondPass(Map persistentClasses) throws MappingException { PersistentClass referencedEntity = (PersistentClass) persistentClasses.get( referencedEntityName ); if ( referencedEntity == null ) { diff --git a/hibernate-core/src/main/java/org/hibernate/jpa/boot/internal/EntityManagerFactoryBuilderImpl.java b/hibernate-core/src/main/java/org/hibernate/jpa/boot/internal/EntityManagerFactoryBuilderImpl.java index 2e0238050a..03e6549477 100644 --- a/hibernate-core/src/main/java/org/hibernate/jpa/boot/internal/EntityManagerFactoryBuilderImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/jpa/boot/internal/EntityManagerFactoryBuilderImpl.java @@ -550,9 +550,9 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil // 2) additional cache region declarations // // we will also clean up any references with null entries - Iterator itr = mergedSettings.configurationValues.entrySet().iterator(); + Iterator itr = mergedSettings.configurationValues.entrySet().iterator(); while ( itr.hasNext() ) { - final Map.Entry entry = (Map.Entry) itr.next(); + final Map.Entry entry = itr.next(); if ( entry.getValue() == null ) { // remove entries with null values itr.remove(); @@ -1228,8 +1228,10 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil // apply id generators final Object idGeneratorStrategyProviderSetting = configurationValues.remove( AvailableSettings.IDENTIFIER_GENERATOR_STRATEGY_PROVIDER ); if ( idGeneratorStrategyProviderSetting != null ) { - final IdentifierGeneratorStrategyProvider idGeneratorStrategyProvider = - strategySelector.resolveStrategy( IdentifierGeneratorStrategyProvider.class, idGeneratorStrategyProviderSetting ); + final IdentifierGeneratorStrategyProvider idGeneratorStrategyProvider = strategySelector.resolveStrategy( + IdentifierGeneratorStrategyProvider.class, + idGeneratorStrategyProviderSetting + ); final MutableIdentifierGeneratorFactory identifierGeneratorFactory = ssr.getService( MutableIdentifierGeneratorFactory.class ); if ( identifierGeneratorFactory == null ) { throw persistenceException( @@ -1500,8 +1502,10 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil // Locate and apply any requested SessionFactoryObserver final Object sessionFactoryObserverSetting = configurationValues.remove( AvailableSettings.SESSION_FACTORY_OBSERVER ); if ( sessionFactoryObserverSetting != null ) { - final SessionFactoryObserver suppliedSessionFactoryObserver = - strategySelector.resolveStrategy( SessionFactoryObserver.class, sessionFactoryObserverSetting ); + final SessionFactoryObserver suppliedSessionFactoryObserver = strategySelector.resolveStrategy( + SessionFactoryObserver.class, + sessionFactoryObserverSetting + ); sfBuilder.addSessionFactoryObservers( suppliedSessionFactoryObserver ); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/exceptionhandling/BaseJpaOrNativeBootstrapFunctionalTestCase.java b/hibernate-core/src/test/java/org/hibernate/orm/test/exceptionhandling/BaseJpaOrNativeBootstrapFunctionalTestCase.java index f559d876b9..8444ab1c30 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/exceptionhandling/BaseJpaOrNativeBootstrapFunctionalTestCase.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/exceptionhandling/BaseJpaOrNativeBootstrapFunctionalTestCase.java @@ -275,7 +275,7 @@ public abstract class BaseJpaOrNativeBootstrapFunctionalTestCase extends BaseUni private Properties buildProperties() { Properties properties = Environment.getProperties(); - properties.put( org.hibernate.cfg.AvailableSettings.CACHE_REGION_FACTORY, CachingRegionFactory.class.getName() ); + properties.put( AvailableSettings.CACHE_REGION_FACTORY, CachingRegionFactory.class.getName() ); for ( Map.Entry entry : getCachedClasses().entrySet() ) { properties.put( AvailableSettings.CLASS_CACHE_PREFIX + "." + entry.getKey().getName(), entry.getValue() ); } @@ -286,10 +286,10 @@ public abstract class BaseJpaOrNativeBootstrapFunctionalTestCase extends BaseUni configure( properties ); if ( createSchema() ) { - properties.put( org.hibernate.cfg.AvailableSettings.HBM2DDL_AUTO, "create-drop" ); + properties.put( AvailableSettings.HBM2DDL_AUTO, "create-drop" ); } - properties.put( org.hibernate.cfg.AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS, "true" ); - properties.put( org.hibernate.cfg.AvailableSettings.DIALECT, getDialect().getClass().getName() ); + properties.put( AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS, "true" ); + properties.put( AvailableSettings.DIALECT, getDialect().getClass().getName() ); return properties; } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/BaseEntityManagerFunctionalTestCase.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/BaseEntityManagerFunctionalTestCase.java index ef62755402..eaf59629e0 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/BaseEntityManagerFunctionalTestCase.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/BaseEntityManagerFunctionalTestCase.java @@ -223,7 +223,7 @@ public abstract class BaseEntityManagerFunctionalTestCase extends BaseUnitTestCa config.put( AvailableSettings.COLLECTION_CACHE_PREFIX + "." + entry.getKey(), entry.getValue() ); } if ( getEjb3DD().length > 0 ) { - ArrayList dds = new ArrayList(); + ArrayList dds = new ArrayList<>(); dds.addAll( Arrays.asList( getEjb3DD() ) ); config.put( AvailableSettings.ORM_XML_FILES, dds ); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/EntityManagerFactoryClosedTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/EntityManagerFactoryClosedTest.java index b313d73c68..123d6bc312 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/EntityManagerFactoryClosedTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/EntityManagerFactoryClosedTest.java @@ -35,7 +35,7 @@ public class EntityManagerFactoryClosedTest extends BaseEntityManagerFunctionalT protected void addConfigOptions(Map options) { super.addConfigOptions( options ); TestingJtaBootstrap.prepare(options); - options.put( AvailableSettings.JPA_TRANSACTION_TYPE, "JTA" ); + options.put( AvailableSettings.JAKARTA_TRANSACTION_TYPE, "JTA" ); } /** diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/cacheable/annotation/ConfigurationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/cacheable/annotation/ConfigurationTest.java index f94428278b..cbb84de9d7 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/cacheable/annotation/ConfigurationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/cacheable/annotation/ConfigurationTest.java @@ -114,11 +114,11 @@ public class ConfigurationTest { assertTrue( pc.isCached() ); } - @SuppressWarnings("unchecked") + @SuppressWarnings({ "unchecked", "rawtypes" }) private MetadataImplementor buildMetadata(SharedCacheMode mode) { Map settings = new HashMap(); settings.put( AvailableSettings.JPA_SHARED_CACHE_MODE, mode ); - settings.put( Environment.CACHE_REGION_FACTORY, CustomRegionFactory.class.getName() ); + settings.put( AvailableSettings.CACHE_REGION_FACTORY, CustomRegionFactory.class.getName() ); settings.put( AvailableSettings.LOADED_CLASSES, Arrays.asList( diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/ejb3configuration/InterceptorTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/ejb3configuration/InterceptorTest.java index 61f1000857..eec14e859c 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/ejb3configuration/InterceptorTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/ejb3configuration/InterceptorTest.java @@ -273,9 +273,9 @@ public class InterceptorTest { protected Map basicSettings() { return SettingsGenerator.generateSettings( - Environment.HBM2DDL_AUTO, "create-drop", - Environment.USE_NEW_ID_GENERATOR_MAPPINGS, "true", - Environment.DIALECT, DialectContext.getDialect().getClass().getName(), + AvailableSettings.HBM2DDL_AUTO, "create-drop", + AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS, "true", + AvailableSettings.DIALECT, DialectContext.getDialect().getClass().getName(), AvailableSettings.LOADED_CLASSES, Arrays.asList( getAnnotatedClasses() ) ); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/lock/LockTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/lock/LockTest.java index 457b664916..83fcf41847 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/lock/LockTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/lock/LockTest.java @@ -63,7 +63,7 @@ public class LockTest extends BaseEntityManagerFunctionalTestCase { protected void addConfigOptions(Map options) { super.addConfigOptions( options ); // We can't use a shared connection provider if we use TransactionUtil.setJdbcTimeout because that is set on the connection level - options.remove( org.hibernate.cfg.AvailableSettings.CONNECTION_PROVIDER ); + options.remove( AvailableSettings.CONNECTION_PROVIDER ); } @Test @@ -285,7 +285,7 @@ public class LockTest extends BaseEntityManagerFunctionalTestCase { doInJPA( this::entityManagerFactory, _entityManagaer -> { Map properties = new HashMap<>(); - properties.put( org.hibernate.cfg.AvailableSettings.JPA_LOCK_TIMEOUT, LockOptions.SKIP_LOCKED ); + properties.put( AvailableSettings.JPA_LOCK_TIMEOUT, LockOptions.SKIP_LOCKED ); _entityManagaer.find( Lock.class, lock.getId(), LockModeType.PESSIMISTIC_READ, properties ); try { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/query/CachedQueryTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/query/CachedQueryTest.java index 1ee68a9489..55fef84902 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/query/CachedQueryTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/query/CachedQueryTest.java @@ -45,7 +45,7 @@ public class CachedQueryTest extends BaseEntityManagerFunctionalTestCase { em.getTransaction().commit(); em.close(); - HibernateEntityManagerFactory hemf = (HibernateEntityManagerFactory) entityManagerFactory(); + HibernateEntityManagerFactory hemf = entityManagerFactory(); Statistics stats = hemf.getSessionFactory().getStatistics(); assertEquals( 0, stats.getQueryCacheHitCount() ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/schemagen/SchemaCreateDropUtf8WithoutHbm2DdlCharsetNameTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/schemagen/SchemaCreateDropUtf8WithoutHbm2DdlCharsetNameTest.java index 547a28b918..7b9449822d 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/schemagen/SchemaCreateDropUtf8WithoutHbm2DdlCharsetNameTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/schemagen/SchemaCreateDropUtf8WithoutHbm2DdlCharsetNameTest.java @@ -28,6 +28,9 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import static org.hibernate.cfg.AvailableSettings.HBM2DDL_SCRIPTS_ACTION; +import static org.hibernate.cfg.AvailableSettings.HBM2DDL_SCRIPTS_CREATE_TARGET; +import static org.hibernate.cfg.AvailableSettings.HBM2DDL_SCRIPTS_DROP_TARGET; import static org.junit.jupiter.api.Assertions.assertTrue; /** @@ -42,9 +45,9 @@ public class SchemaCreateDropUtf8WithoutHbm2DdlCharsetNameTest { protected Map getConfig() { final Map config = Environment.getProperties(); - config.put( org.hibernate.cfg.AvailableSettings.HBM2DDL_SCRIPTS_CREATE_TARGET, createSchema.toPath() ); - config.put( org.hibernate.cfg.AvailableSettings.HBM2DDL_SCRIPTS_DROP_TARGET, dropSchema.toPath() ); - config.put( org.hibernate.cfg.AvailableSettings.HBM2DDL_SCRIPTS_ACTION, "drop-and-create" ); + config.put( HBM2DDL_SCRIPTS_CREATE_TARGET, createSchema.toPath() ); + config.put( HBM2DDL_SCRIPTS_DROP_TARGET, dropSchema.toPath() ); + config.put( HBM2DDL_SCRIPTS_ACTION, "drop-and-create" ); ArrayList classes = new ArrayList(); classes.addAll( Arrays.asList( new Class[] {TestEntity.class} ) ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/schemagen/SchemaScriptFileGenerationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/schemagen/SchemaScriptFileGenerationTest.java index 912721253a..e2e6212f61 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/schemagen/SchemaScriptFileGenerationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/schemagen/SchemaScriptFileGenerationTest.java @@ -108,9 +108,9 @@ public class SchemaScriptFileGenerationTest { private Map getConfig() { final Map config = Environment.getProperties(); - config.put( org.hibernate.cfg.AvailableSettings.HBM2DDL_SCRIPTS_CREATE_TARGET, createSchema.toPath() ); - config.put( org.hibernate.cfg.AvailableSettings.HBM2DDL_SCRIPTS_DROP_TARGET, dropSchema.toPath() ); - config.put( org.hibernate.cfg.AvailableSettings.HBM2DDL_SCRIPTS_ACTION, "drop-and-create" ); + config.put( AvailableSettings.HBM2DDL_SCRIPTS_CREATE_TARGET, createSchema.toPath() ); + config.put( AvailableSettings.HBM2DDL_SCRIPTS_DROP_TARGET, dropSchema.toPath() ); + config.put( AvailableSettings.HBM2DDL_SCRIPTS_ACTION, "drop-and-create" ); ArrayList classes = new ArrayList(); classes.addAll( Arrays.asList( new Class[] {TestEntity.class} ) ); diff --git a/hibernate-core/src/test/java/org/hibernate/test/ecid/EmbeddedIdWithMapsIdTargetingDerivedEntityTest.java b/hibernate-core/src/test/java/org/hibernate/test/ecid/EmbeddedIdWithMapsIdTargetingDerivedEntityTest.java new file mode 100644 index 0000000000..4b0507a4e6 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/ecid/EmbeddedIdWithMapsIdTargetingDerivedEntityTest.java @@ -0,0 +1,227 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html + */ +package org.hibernate.test.ecid; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.hibernate.test.util.SchemaUtil.getColumnNames; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import javax.persistence.Column; +import javax.persistence.Embeddable; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.ManyToOne; +import javax.persistence.MapsId; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; +import org.junit.Test; + +/** + * Test that bootstrap doesn't throw an exception + * when an entity has an {@link EmbeddedId} and a {@link MapsId} that references a derived identity. + *

+ * This test used to fail on bootstrap with the following error: + *

+ * java.util.NoSuchElementException + * at java.base/java.util.ArrayList$Itr.next(ArrayList.java:1000) + * at org.hibernate.cfg.annotations.TableBinder.linkJoinColumnWithValueOverridingNameIfImplicit(TableBinder.java:714) + * at org.hibernate.cfg.PkDrivenByDefaultMapsIdSecondPass.doSecondPass(PkDrivenByDefaultMapsIdSecondPass.java:37) + * at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1693) + * at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1650) + * at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:295) + * at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:86) + * at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:479) + * at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:85) + * at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:709) + * at org.hibernate.testing.junit4.BaseCoreFunctionalTestCase.buildSessionFactory(BaseCoreFunctionalTestCase.java:125) + * at org.hibernate.testing.junit4.BaseCoreFunctionalTestCase.buildSessionFactory(BaseCoreFunctionalTestCase.java:110) + * at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + * at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + * at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + * at java.base/java.lang.reflect.Method.invoke(Method.java:566) + * at org.hibernate.testing.junit4.TestClassMetadata.performCallbackInvocation(TestClassMetadata.java:205) + */ +@TestForIssue(jiraKey = "HHH-13295") +public class EmbeddedIdWithMapsIdTargetingDerivedEntityTest extends BaseNonConfigCoreFunctionalTestCase { + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { Attendance.class, AttendanceId.class, Lecture.class, Student.class, User.class }; + } + + @Test + public void metadataTest() { + assertThat( getColumnNames( "attendance", metadata() ) ) + // Just check we're using @MapsId; otherwise the test wouldn't be able to reproduce HHH-13295. + .containsExactlyInAnyOrder( "student_id", "lecture_id" ); + } + + // The main goal of the test is to check that bootstrap doesn't throw an exception, + // but it feels wrong to have a test class with just an empty test method, + // so just check that persisting/loading works correctly. + @Test + public void smokeTest() { + inTransaction( s -> { + Lecture lecture = new Lecture( 1L ); + s.persist( lecture ); + Student student = new Student( 2L ); + s.persist( student ); + Attendance attendance = new Attendance( lecture, student ); + student.getAttendances().add( attendance ); + lecture.getAttendances().add( attendance ); + s.persist( attendance ); + } ); + + inTransaction( s -> { + Attendance attendance = s.get( Attendance.class, new AttendanceId( 1L, 2L ) ); + assertThat( attendance.getId() ) + .extracting( AttendanceId::getLectureId ) + .isEqualTo( 1L ); + assertThat( attendance.getId() ) + .extracting( AttendanceId::getStudentId ) + .isEqualTo( 2L ); + assertThat( attendance.getLecture() ) + .extracting( Lecture::getId ) + .isEqualTo( 1L ); + assertThat( attendance.getStudent() ) + .extracting( Student::getId ) + .isEqualTo( 2L ); + } ); + } + + @Entity + @Table(name = "attendance") + public static class Attendance { + @EmbeddedId + private AttendanceId id; + + @ManyToOne(fetch = FetchType.LAZY) + @MapsId("lectureId") + private Lecture lecture; + + @ManyToOne(fetch = FetchType.LAZY) + @MapsId("studentId") + private Student student; + + Attendance() { + } + + public Attendance(Lecture lecture, Student student) { + this.id = new AttendanceId( lecture.getId(), student.getId() ); + this.lecture = lecture; + this.student = student; + } + + public AttendanceId getId() { + return id; + } + + public Lecture getLecture() { + return lecture; + } + + public Student getStudent() { + return student; + } + } + + @Embeddable + public static class AttendanceId implements Serializable { + @Column + private Long lectureId; + + @Column + private Long studentId; + + AttendanceId() { + } + + public AttendanceId(Long lectureId, Long studentId) { + this.lectureId = lectureId; + this.studentId = studentId; + } + + public Long getLectureId() { + return lectureId; + } + + public Long getStudentId() { + return studentId; + } + } + + @Entity + @Table(name = "users") + @Inheritance(strategy = InheritanceType.JOINED) + public static abstract class User { + @Id + private Long id; + + User() { + } + + public User(Long id) { + this.id = id; + } + + public Long getId() { + return id; + } + } + + @Entity + @Table(name = "student") + public static class Student extends User { + @OneToMany(mappedBy = "student", fetch = FetchType.LAZY) + private List attendances = new ArrayList<>(); + + Student() { + } + + public Student(Long id) { + super( id ); + } + + public List getAttendances() { + return attendances; + } + } + + @Entity + @Table(name = "lecture") + public static class Lecture { + @Id + private Long id; + + @OneToMany(mappedBy = "lecture", fetch = FetchType.LAZY) + private List attendances = new ArrayList<>(); + + Lecture() { + } + + public Lecture(Long id) { + this.id = id; + } + + public Long getId() { + return id; + } + + public List getAttendances() { + return attendances; + } + } +} diff --git a/hibernate-core/src/test_legacy/org/hibernate/jpa/test/procedure/DateTimeParameterTest.java b/hibernate-core/src/test_legacy/org/hibernate/jpa/test/procedure/DateTimeParameterTest.java index c8ac98cccd..3b53dcc4d5 100644 --- a/hibernate-core/src/test_legacy/org/hibernate/jpa/test/procedure/DateTimeParameterTest.java +++ b/hibernate-core/src/test_legacy/org/hibernate/jpa/test/procedure/DateTimeParameterTest.java @@ -30,11 +30,11 @@ import jakarta.persistence.Table; import jakarta.persistence.Temporal; import jakarta.persistence.TemporalType; +import org.hibernate.cfg.AvailableSettings; import org.hibernate.dialect.DerbyTenSevenDialect; import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess; import org.hibernate.engine.jdbc.spi.JdbcServices; import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.jpa.AvailableSettings; import org.hibernate.jpa.HibernateEntityManagerFactory; import org.hibernate.jpa.boot.spi.Bootstrap; import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor; diff --git a/hibernate-core/src/test_legacy/org/hibernate/jpa/test/procedure/JpaTckUsageTest.java b/hibernate-core/src/test_legacy/org/hibernate/jpa/test/procedure/JpaTckUsageTest.java index 24b2ebe685..1c2722e134 100644 --- a/hibernate-core/src/test_legacy/org/hibernate/jpa/test/procedure/JpaTckUsageTest.java +++ b/hibernate-core/src/test_legacy/org/hibernate/jpa/test/procedure/JpaTckUsageTest.java @@ -19,11 +19,11 @@ import java.util.Map; import jakarta.persistence.EntityManager; import jakarta.persistence.StoredProcedureQuery; +import org.hibernate.cfg.AvailableSettings; import org.hibernate.dialect.DerbyTenSevenDialect; import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess; import org.hibernate.engine.jdbc.spi.JdbcServices; import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.jpa.AvailableSettings; import org.hibernate.jpa.HibernateEntityManagerFactory; import org.hibernate.jpa.boot.spi.Bootstrap; import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor; diff --git a/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/BaseEnversJPAFunctionalTestCase.java b/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/BaseEnversJPAFunctionalTestCase.java index be6a978af9..b49470cec7 100644 --- a/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/BaseEnversJPAFunctionalTestCase.java +++ b/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/BaseEnversJPAFunctionalTestCase.java @@ -139,7 +139,7 @@ public abstract class BaseEnversJPAFunctionalTestCase extends AbstractEnversTest } if ( getEjb3DD().length > 0 ) { - ArrayList dds = new ArrayList(); + ArrayList dds = new ArrayList<>(); dds.addAll( Arrays.asList( getEjb3DD() ) ); config.put( AvailableSettings.ORM_XML_FILES, dds ); } diff --git a/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/performance/AbstractEntityManagerTest.java b/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/performance/AbstractEntityManagerTest.java index a85b6c4f4f..e7d16c790c 100644 --- a/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/performance/AbstractEntityManagerTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/performance/AbstractEntityManagerTest.java @@ -84,8 +84,8 @@ public abstract class AbstractEntityManagerTest extends AbstractEnversTest { configurationProperties.setProperty( EnversIntegrator.AUTO_REGISTER, "false" ); } if ( createSchema() ) { - configurationProperties.setProperty( Environment.HBM2DDL_AUTO, "create-drop" ); - configurationProperties.setProperty( Environment.USE_NEW_ID_GENERATOR_MAPPINGS, "true" ); + configurationProperties.setProperty( AvailableSettings.HBM2DDL_AUTO, "create-drop" ); + configurationProperties.setProperty( AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS, "true" ); configurationProperties.setProperty( EnversSettings.USE_REVISION_ENTITY_WITH_NATIVE_ID, "false" ); } if ( auditStrategy != null && !"".equals( auditStrategy ) ) {