diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java index c9980b003d8f..1977334a4d38 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java @@ -309,7 +309,7 @@ public AbstractCollectionPersister( final BasicValue discriminatorDescriptor = any.getDiscriminatorDescriptor(); final AnyType anyType = any.getType(); final MetaType metaType = (MetaType) anyType.getDiscriminatorType(); - final Object discriminatorValue = metaType.getEntityNameToDiscriminatorValueMap().get( ownerPersister.getEntityName() ); + final Object discriminatorValue = metaType.resolveDiscriminatorValue( ownerPersister ); final BasicType discriminatorBaseType = (BasicType) metaType.getBaseType(); final String discriminatorLiteral = discriminatorBaseType.getJdbcLiteralFormatter().toJdbcLiteral( discriminatorValue, diff --git a/hibernate-core/src/main/java/org/hibernate/type/MetaType.java b/hibernate-core/src/main/java/org/hibernate/type/MetaType.java index c7d2ebfc197d..0d14702d70f6 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/MetaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/MetaType.java @@ -8,6 +8,7 @@ import java.sql.SQLException; import java.util.HashMap; import java.util.Map; +import java.util.Optional; import org.hibernate.HibernateException; import org.hibernate.MappingException; @@ -19,6 +20,7 @@ import org.hibernate.metamodel.mapping.DiscriminatorConverter; import org.hibernate.persister.entity.DiscriminatorMetadata; import org.hibernate.persister.entity.DiscriminatorType; +import org.hibernate.persister.entity.EntityPersister; /** * @author Gavin King @@ -59,6 +61,17 @@ public Map getEntityNameToDiscriminatorValueMap(){ return entityNameToDiscriminatorValueMap; } + public Object resolveDiscriminatorValue(EntityPersister ownerPersister) { + String entityName = ownerPersister.getEntityName(); + return Optional.ofNullable( + getEntityNameToDiscriminatorValueMap().get( entityName ) ).orElse( entityName ); + } + + public String resolveEntityName(String discriminatorValue) { + return Optional.ofNullable( + getDiscriminatorValuesToEntityNameMap().get( discriminatorValue ) ).orElse( discriminatorValue ); + } + public int[] getSqlTypeCodes(MappingContext mappingContext) throws MappingException { return baseType.getSqlTypeCodes( mappingContext ); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/manytoone/ManyToOneWithAnyTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/manytoone/ManyToOneWithAnyTest.java index 9fb6fe36d055..4dcc54de4459 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/manytoone/ManyToOneWithAnyTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/manytoone/ManyToOneWithAnyTest.java @@ -8,7 +8,6 @@ import org.hibernate.Session; import org.hibernate.annotations.Any; -import org.hibernate.annotations.AnyDiscriminatorValue; import org.hibernate.annotations.AnyKeyJavaClass; import org.hibernate.cfg.JdbcSettings; @@ -45,6 +44,7 @@ integrationSettings = @Setting(name = JdbcSettings.SHOW_SQL, value = "true") ) @JiraKey("HHH-15722") +@JiraKey("HHH-18684") class ManyToOneWithAnyTest { @Test @@ -117,8 +117,6 @@ public static class Book { @Any @AnyKeyJavaClass(Long.class) - @AnyDiscriminatorValue(entity = Shop.class, discriminator = "S") - @AnyDiscriminatorValue(entity = Library.class, discriminator = "L") @Column(name = "STORE_ROLE") @JoinColumn(name = "STORE_ID") private Store store; diff --git a/hibernate-core/src/test/java/org/hibernate/type/MetaTypeResolveTest.java b/hibernate-core/src/test/java/org/hibernate/type/MetaTypeResolveTest.java new file mode 100644 index 000000000000..1e559d991321 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/type/MetaTypeResolveTest.java @@ -0,0 +1,102 @@ +/* + * SPDX-License-Identifier: LGPL-2.1-or-later + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.type; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.JiraKey; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test {@link MetaType#resolveDiscriminatorValue(EntityPersister)} and {@link MetaType#resolveEntityName(String)} + * + * @author Vincent Bouthinon + */ +@DomainModel( + annotatedClasses = { + MetaTypeResolveTest.Dog.class + } +) +@SessionFactory +@JiraKey("HHH-18684") +class MetaTypeResolveTest { + + @Test + void resolveDiscriminatorValue_must_return_the_discriminator_value_when_the_entity_name_exist(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + // Given + EntityPersister dogPersister = session.getSessionFactory() + .getRuntimeMetamodels() + .getMappingMetamodel() + .getEntityDescriptor( MetaTypeResolveTest.Dog.class ); + Map discriminatorValuesToEntityNameMap = new HashMap<>(); + discriminatorValuesToEntityNameMap.put( "dog", dogPersister.getEntityName() ); + MetaType metaType = new MetaType( discriminatorValuesToEntityNameMap, null ); + // When + Object discriminatorValue = metaType.resolveDiscriminatorValue( dogPersister ); + // Then + assertThat( discriminatorValue ).isEqualTo( "dog" ); + } ); + } + + @Test + void resolveDiscriminatorValue_must_return_the_entity_name_when_the_entity_name_dont_exist(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + // Given + EntityPersister dogPersister = session.getSessionFactory() + .getRuntimeMetamodels() + .getMappingMetamodel() + .getEntityDescriptor( MetaTypeResolveTest.Dog.class ); + Map discriminatorValuesToEntityNameMap = new HashMap<>(); + discriminatorValuesToEntityNameMap.put( "anotherClass", + MetaTypeResolveTest.class.getCanonicalName() ); + MetaType metaType = new MetaType( discriminatorValuesToEntityNameMap, null ); + // When + Object discriminatorValue = metaType.resolveDiscriminatorValue( dogPersister ); + // Then + assertThat( discriminatorValue ).isEqualTo( dogPersister.getEntityName() ); + } ); + } + + @Test + void resolveEntityName_must_return_the_entity_name_when_the_discriminator_value_exist() { + // Given + Map discriminatorValuesToEntityNameMap = new HashMap<>(); + discriminatorValuesToEntityNameMap.put( "dog", Dog.class.getCanonicalName() ); + MetaType metaType = new MetaType( discriminatorValuesToEntityNameMap, null ); + // When + Object resolveEntityName = metaType.resolveEntityName( "dog" ); + // Then + assertThat( resolveEntityName ).isEqualTo( Dog.class.getCanonicalName() ); + } + + @Test + void resolveEntityName_must_return_discriminator_value_when_the_entity_name_dont_exist() { + // Given + Map discriminatorValuesToEntityNameMap = new HashMap<>(); + MetaType metaType = new MetaType( discriminatorValuesToEntityNameMap, null ); + // When + Object resolveEntityName = metaType.resolveEntityName( Dog.class.getCanonicalName() ); + // Then + assertThat( resolveEntityName ).isEqualTo( Dog.class.getCanonicalName() ); + } + + @Entity + public static class Dog { + @Id + public int id; + } +}