From f5bdf08d257e451b312eec07768f01559b22003a Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Tue, 26 Sep 2023 08:54:36 -0500 Subject: [PATCH] natural-id + not-found https://hibernate.atlassian.net/browse/HHH-17197 - Add check for illegal combo of to-one + natural-id + not-found https://hibernate.atlassian.net/browse/HHH-17196 - Documentation for @NaturalId should be more explicit about non-nullability (cherry picked from commit 6c2e04381da4fdf26999fb3a31ca9514955da33b) --- gradle/java-module.gradle | 1 + gradle/libraries.gradle | 2 + .../tuple/entity/EntityMetamodel.java | 17 +++------ .../test/naturalid/ValidationTests.java | 37 ++++++++----------- 4 files changed, 25 insertions(+), 32 deletions(-) diff --git a/gradle/java-module.gradle b/gradle/java-module.gradle index 4d5aa37bed..5647421056 100644 --- a/gradle/java-module.gradle +++ b/gradle/java-module.gradle @@ -67,6 +67,7 @@ dependencies { annotationProcessor( libraries.logging_annotations ) testCompile( libraries.junit ) + testCompile( libraries.assertj ) testCompile( libraries.byteman ) testCompile( libraries.byteman_install ) testCompile( libraries.byteman_bmunit ) diff --git a/gradle/libraries.gradle b/gradle/libraries.gradle index 6a365959ff..04c1275b8e 100644 --- a/gradle/libraries.gradle +++ b/gradle/libraries.gradle @@ -13,6 +13,7 @@ ext { h2Version = '1.4.196' bytemanVersion = '4.0.16' //Compatible with JDK 17 jnpVersion = '5.0.6.CR1' + assertjVersion = "3.22.0" hibernateValidatorVersion = '6.0.22.Final' hibernateCommonsVersion = '5.0.5.Final' @@ -103,6 +104,7 @@ ext { log4j2: "org.apache.logging.log4j:log4j-core:2.17.1", junit: "junit:junit:${junitVersion}", + assertj: "org.assertj:assertj-core:${assertjVersion}", byteman: "org.jboss.byteman:byteman:${bytemanVersion}", byteman_install: "org.jboss.byteman:byteman-install:${bytemanVersion}", byteman_bmunit: "org.jboss.byteman:byteman-bmunit:${bytemanVersion}", diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java index 40274ebb19..2054723538 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java @@ -19,8 +19,6 @@ import java.util.Set; import org.hibernate.EntityMode; import org.hibernate.HibernateException; import org.hibernate.MappingException; -import org.hibernate.annotations.NotFoundAction; -import org.hibernate.boot.spi.MetadataImplementor; import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementHelper; import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata; import org.hibernate.cfg.NotYetImplementedException; @@ -32,15 +30,10 @@ import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.mapping.Component; -import org.hibernate.mapping.GeneratorCreator; import org.hibernate.mapping.ManyToOne; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; -import org.hibernate.mapping.Subclass; -import org.hibernate.mapping.ToOne; import org.hibernate.mapping.Value; -import org.hibernate.metamodel.mapping.EntityMappingType; -import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.tuple.GenerationTiming; import org.hibernate.tuple.IdentifierProperty; @@ -240,7 +233,7 @@ public class EntityMetamodel implements Serializable { } if ( prop.isNaturalIdentifier() ) { - verifyNaturalIdProperty( property ); + verifyNaturalIdProperty( prop ); naturalIdNumbers.add( i ); if ( prop.isUpdateable() ) { foundUpdateableNaturalIdProperty = true; @@ -672,7 +665,7 @@ public class EntityMetamodel implements Serializable { final Value value = property.getValue(); if ( value instanceof ManyToOne ) { final ManyToOne toOne = (ManyToOne) value; - if ( toOne.getNotFoundAction() == NotFoundAction.IGNORE ) { + if ( toOne.isIgnoreNotFound() ) { throw new MappingException( "Attribute marked as natural-id can not also be a not-found association - " + propertyName( property ) @@ -681,8 +674,10 @@ public class EntityMetamodel implements Serializable { } else if ( value instanceof Component ) { final Component component = (Component) value; - for ( Property componentProperty : component.getProperties() ) { - verifyNaturalIdProperty( componentProperty ); + //noinspection unchecked + final Iterator properties = component.getPropertyIterator(); + while ( properties.hasNext() ) { + verifyNaturalIdProperty( properties.next() ); } } } diff --git a/hibernate-core/src/test/java/org/hibernate/test/naturalid/ValidationTests.java b/hibernate-core/src/test/java/org/hibernate/test/naturalid/ValidationTests.java index 54cea3fdbb..e6561bd4c5 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/naturalid/ValidationTests.java +++ b/hibernate-core/src/test/java/org/hibernate/test/naturalid/ValidationTests.java @@ -4,7 +4,14 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. */ -package org.hibernate.orm.test.mapping.naturalid; +package org.hibernate.test.naturalid; + +import javax.persistence.Embeddable; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import javax.persistence.Table; import org.hibernate.MappingException; import org.hibernate.SessionFactory; @@ -12,31 +19,20 @@ import org.hibernate.annotations.NaturalId; import org.hibernate.annotations.NotFound; import org.hibernate.annotations.NotFoundAction; import org.hibernate.boot.MetadataSources; -import org.hibernate.boot.registry.StandardServiceRegistry; -import org.hibernate.testing.orm.junit.ServiceRegistry; -import org.hibernate.testing.orm.junit.ServiceRegistryScope; -import org.junit.jupiter.api.Test; - -import jakarta.persistence.Embeddable; -import jakarta.persistence.Embedded; -import jakarta.persistence.Entity; -import jakarta.persistence.Id; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.Table; +import org.hibernate.testing.junit4.BaseUnitTestCase; +import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.Assert.fail; /** * @author Steve Ebersole */ -@ServiceRegistry -public class ValidationTests { +public class ValidationTests extends BaseUnitTestCase { @Test - void checkManyToOne(ServiceRegistryScope registryScope) { - final StandardServiceRegistry registry = registryScope.getRegistry(); - final MetadataSources metadataSources = new MetadataSources( registry ) + public void checkManyToOne() { + final MetadataSources metadataSources = new MetadataSources() .addAnnotatedClass( Thing1.class ) .addAnnotatedClass( Thing2.class ); try (final SessionFactory sessionFactory = metadataSources.buildMetadata().buildSessionFactory(); ) { @@ -49,9 +45,8 @@ public class ValidationTests { } @Test - void checkEmbeddable(ServiceRegistryScope registryScope) { - final StandardServiceRegistry registry = registryScope.getRegistry(); - final MetadataSources metadataSources = new MetadataSources( registry ) + public void checkEmbeddable() { + final MetadataSources metadataSources = new MetadataSources() .addAnnotatedClass( Thing1.class ) .addAnnotatedClass( Thing3.class ) .addAnnotatedClass( Container.class );