Skip to content

Commit 24a1b2c

Browse files
committed
HHH-18729 - Allow custom strategy for implicit discriminator-value determination for ANY
- allow opting into use of short-name - potentially look at allowing an "implicit value mapper" later
1 parent 7bf6004 commit 24a1b2c

File tree

16 files changed

+249
-62
lines changed

16 files changed

+249
-62
lines changed

hibernate-core/src/main/java/org/hibernate/annotations/AnyDiscriminator.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,10 @@
5454
* @since 7.0
5555
*/
5656
AnyDiscriminatorValueStrategy valueStrategy() default AUTO;
57+
58+
/**
59+
* Whether the entity's short-name should be used as the discriminator value
60+
* (as opposed to its full-name) in the case of implicit value mapping.
61+
*/
62+
boolean implicitEntityShortName() default false;
5763
}

hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnyBinder.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ private static void bindAny(
111111
final AnyDiscriminator anyDiscriminator = property.getDirectAnnotationUsage( AnyDiscriminator.class );
112112
if ( anyDiscriminator != null ) {
113113
value.setDiscriminatorValueStrategy( anyDiscriminator.valueStrategy() );
114+
value.setImplicitEntityShortName( anyDiscriminator.implicitEntityShortName() );
114115
}
115116

116117
final PropertyBinder binder = new PropertyBinder();

hibernate-core/src/main/java/org/hibernate/boot/models/annotations/internal/AnyDiscriminatorAnnotation.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@
1616
public class AnyDiscriminatorAnnotation implements AnyDiscriminator {
1717
private jakarta.persistence.DiscriminatorType value;
1818
private AnyDiscriminatorValueStrategy valueStrategy;
19+
private boolean implicitEntityShortName;
1920

2021
/**
2122
* Used in creating dynamic annotation instances (e.g. from XML)
2223
*/
2324
public AnyDiscriminatorAnnotation(SourceModelBuildingContext modelContext) {
2425
this.value = jakarta.persistence.DiscriminatorType.STRING;
2526
this.valueStrategy = AnyDiscriminatorValueStrategy.AUTO;
27+
this.implicitEntityShortName = false;
2628
}
2729

2830
/**
@@ -31,13 +33,16 @@ public AnyDiscriminatorAnnotation(SourceModelBuildingContext modelContext) {
3133
public AnyDiscriminatorAnnotation(AnyDiscriminator annotation, SourceModelBuildingContext modelContext) {
3234
this.value = annotation.value();
3335
this.valueStrategy = annotation.valueStrategy();
36+
this.implicitEntityShortName = annotation.implicitEntityShortName();
3437
}
3538

3639
/**
3740
* Used in creating annotation instances from Jandex variant
3841
*/
3942
public AnyDiscriminatorAnnotation(Map<String, Object> attributeValues, SourceModelBuildingContext modelContext) {
4043
this.value = (jakarta.persistence.DiscriminatorType) attributeValues.get( "value" );
44+
this.valueStrategy = (AnyDiscriminatorValueStrategy) attributeValues.get( "valueStrategy" );
45+
this.implicitEntityShortName = (boolean) attributeValues.get( "implicitEntityShortName" );
4146
}
4247

4348
@Override
@@ -63,5 +68,12 @@ public void valueStrategy(AnyDiscriminatorValueStrategy valueStrategy) {
6368
this.valueStrategy = valueStrategy;
6469
}
6570

71+
@Override
72+
public boolean implicitEntityShortName() {
73+
return implicitEntityShortName;
74+
}
6675

76+
public void implicitEntityShortName(boolean implicitEntityShortName) {
77+
this.implicitEntityShortName = implicitEntityShortName;
78+
}
6779
}

hibernate-core/src/main/java/org/hibernate/mapping/Any.java

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,19 @@
44
*/
55
package org.hibernate.mapping;
66

7-
import java.util.HashMap;
8-
import java.util.Map;
9-
import java.util.Objects;
10-
import java.util.function.Consumer;
11-
127
import org.hibernate.Incubating;
138
import org.hibernate.MappingException;
149
import org.hibernate.boot.spi.MetadataBuildingContext;
1510
import org.hibernate.engine.jdbc.spi.JdbcServices;
1611
import org.hibernate.type.AnyDiscriminatorValueStrategy;
1712
import org.hibernate.type.AnyType;
18-
import org.hibernate.type.Type;
1913
import org.hibernate.type.MappingContext;
14+
import org.hibernate.type.Type;
15+
16+
import java.util.HashMap;
17+
import java.util.Map;
18+
import java.util.Objects;
19+
import java.util.function.Consumer;
2020

2121
/**
2222
* A mapping model object representing a {@linkplain org.hibernate.annotations.Any polymorphic association}
@@ -36,6 +36,7 @@ public class Any extends SimpleValue {
3636
// common
3737
private Map<Object,String> metaValueToEntityNameMap;
3838
private AnyDiscriminatorValueStrategy discriminatorValueStrategy = AnyDiscriminatorValueStrategy.AUTO;
39+
private boolean implicitEntityShortName = false;
3940
private boolean lazy = true;
4041

4142
private AnyType resolvedType;
@@ -132,25 +133,24 @@ public void setIdentifierType(String identifierType) {
132133
}
133134

134135
/**
135-
* Current strategy for interpreting {@linkplain org.hibernate.annotations.AnyDiscriminatorValue} definitions,
136-
* especially in terms of implicit, explicit and potentially missing values.
136+
* Set the strategy for interpreting {@linkplain org.hibernate.annotations.AnyDiscriminatorValue}
137+
* definitions in terms of implicit, explicit and potentially missing values.
137138
*
138139
* @since 7.0
139140
*/
140141
@Incubating
141-
public AnyDiscriminatorValueStrategy getDiscriminatorValueStrategy() {
142-
return discriminatorValueStrategy;
142+
public void setDiscriminatorValueStrategy(AnyDiscriminatorValueStrategy discriminatorValueStrategy) {
143+
this.discriminatorValueStrategy = discriminatorValueStrategy;
143144
}
144145

145146
/**
146-
* Set the strategy
147+
* Set whether to use the entity's short-name for implicit discriminator value mappings
147148
*
148-
* @see #getDiscriminatorValueStrategy
149149
* @since 7.0
150150
*/
151151
@Incubating
152-
public void setDiscriminatorValueStrategy(AnyDiscriminatorValueStrategy discriminatorValueStrategy) {
153-
this.discriminatorValueStrategy = discriminatorValueStrategy;
152+
public void setImplicitEntityShortName(boolean implicitEntityShortName) {
153+
this.implicitEntityShortName = implicitEntityShortName;
154154
}
155155

156156
@Override
@@ -176,6 +176,7 @@ public AnyType getType() throws MappingException {
176176
discriminatorType,
177177
identifierType,
178178
discriminatorValueStrategy,
179+
implicitEntityShortName,
179180
metaValueToEntityNameMap,
180181
isLazy(),
181182
getBuildingContext()

hibernate-core/src/main/java/org/hibernate/mapping/MappingHelper.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,17 +129,26 @@ public static AnyType anyMapping(
129129
Map<Object, String> explicitValeMappings,
130130
boolean lazy,
131131
MetadataBuildingContext buildingContext) {
132-
return anyMapping( discriminatorType, identifierType, AnyDiscriminatorValueStrategy.AUTO, explicitValeMappings, lazy, buildingContext );
132+
return anyMapping(
133+
discriminatorType,
134+
identifierType,
135+
AnyDiscriminatorValueStrategy.AUTO,
136+
false,
137+
explicitValeMappings,
138+
lazy,
139+
buildingContext
140+
);
133141
}
134142

135143
public static AnyType anyMapping(
136144
Type discriminatorType,
137145
Type identifierType,
138146
AnyDiscriminatorValueStrategy discriminatorValueStrategy,
147+
boolean implicitEntityShortName,
139148
Map<Object, String> explicitValeMappings,
140149
boolean lazy,
141150
MetadataBuildingContext buildingContext) {
142-
final MetaType metaType = new MetaType( discriminatorType, discriminatorValueStrategy, explicitValeMappings );
151+
final MetaType metaType = new MetaType( discriminatorType, discriminatorValueStrategy, implicitEntityShortName, explicitValeMappings );
143152
return new AnyType( buildingContext.getBootstrapContext().getTypeConfiguration(), metaType, identifierType, lazy );
144153
}
145154

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/DiscriminatorConverter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public R toRelationalValue(O domainForm) {
9090
return (R) discriminatorValueDetails.getValue();
9191
}
9292

93-
public abstract DiscriminatorValueDetails getDetailsForDiscriminatorValue(Object relationalForm);
93+
public abstract DiscriminatorValueDetails getDetailsForDiscriminatorValue(Object relationalValue);
9494

9595
public abstract DiscriminatorValueDetails getDetailsForEntityName(String entityName);
9696

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EmbeddableDiscriminatorConverter.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,13 @@ public O toDomainValue(R relationalForm) {
8686
}
8787

8888
@Override
89-
public EmbeddableDiscriminatorValueDetailsImpl getDetailsForDiscriminatorValue(Object value) {
90-
final EmbeddableDiscriminatorValueDetailsImpl valueMatch = discriminatorValueToDetailsMap.get( value );
89+
public EmbeddableDiscriminatorValueDetailsImpl getDetailsForDiscriminatorValue(Object relationalValue) {
90+
final EmbeddableDiscriminatorValueDetailsImpl valueMatch = discriminatorValueToDetailsMap.get( relationalValue );
9191
if ( valueMatch != null ) {
9292
return valueMatch;
9393
}
9494

95-
throw new HibernateException( "Unrecognized discriminator value: " + value );
95+
throw new HibernateException( "Unrecognized discriminator value: " + relationalValue );
9696
}
9797

9898
@Override

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AnyDiscriminatorPart.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ public AnyDiscriminatorPart(
8585
BasicType<?> underlyingJdbcMapping,
8686
Map<Object,String> valueToEntityNameMap,
8787
AnyDiscriminatorValueStrategy valueStrategy,
88+
boolean implicitEntityShortName,
8889
MappingMetamodelImplementor mappingMetamodel) {
8990
this.navigableRole = partRole;
9091
this.declaringType = declaringType;
@@ -106,6 +107,7 @@ public AnyDiscriminatorPart(
106107
underlyingJdbcMapping,
107108
valueToEntityNameMap,
108109
valueStrategy,
110+
implicitEntityShortName,
109111
mappingMetamodel
110112
);
111113
}
@@ -115,6 +117,7 @@ public AnyDiscriminatorPart(
115117
BasicType<?> underlyingJdbcMapping,
116118
Map<Object, String> valueToEntityNameMap,
117119
AnyDiscriminatorValueStrategy valueStrategy,
120+
boolean implicitEntityShortName,
118121
MappingMetamodelImplementor mappingMetamodel) {
119122
if ( valueStrategy == AnyDiscriminatorValueStrategy.AUTO ) {
120123
if ( valueToEntityNameMap == null || valueToEntityNameMap.isEmpty() ) {
@@ -132,6 +135,7 @@ public AnyDiscriminatorPart(
132135
ClassJavaType.INSTANCE,
133136
underlyingJdbcMapping.getJavaTypeDescriptor(),
134137
valueToEntityNameMap,
138+
implicitEntityShortName,
135139
mappingMetamodel
136140
);
137141
case EXPLICIT -> new ExplicitDiscriminatorConverter<>(
@@ -146,6 +150,7 @@ public AnyDiscriminatorPart(
146150
ClassJavaType.INSTANCE,
147151
underlyingJdbcMapping.getJavaTypeDescriptor(),
148152
valueToEntityNameMap,
153+
implicitEntityShortName,
149154
mappingMetamodel
150155
);
151156
};

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/DiscriminatedAssociationMapping.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ public static DiscriminatedAssociationMapping from(
9090
(BasicType<?>) metaType.getBaseType(),
9191
metaType.getDiscriminatorValuesToEntityNameMap(),
9292
metaType.getValueStrategy(),
93+
metaType.isImplicitEntityShortName(),
9394
creationProcess.getCreationContext().getSessionFactory().getMappingMetamodel()
9495
);
9596

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ExplicitDiscriminatorConverter.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ public ExplicitDiscriminatorConverter(
5454
this.detailsByEntityName = CollectionHelper.concurrentMap( explicitValueMappings.size() );
5555

5656
explicitValueMappings.forEach( (value, entityName) -> {
57-
final EntityPersister entityDescriptor = mappingMetamodel.getEntityDescriptor( entityName );
57+
final String importedEntityName = mappingMetamodel.getImportedName( entityName );
58+
final EntityPersister entityDescriptor = mappingMetamodel.getEntityDescriptor( importedEntityName );
5859
final DiscriminatorValueDetails details = new DiscriminatorValueDetailsImpl( value, entityDescriptor );
5960
detailsByValue.put( value, details );
6061
detailsByEntityName.put( entityDescriptor.getEntityName(), details );
@@ -75,12 +76,12 @@ public Map<String, DiscriminatorValueDetails> getDetailsByEntityName() {
7576
}
7677

7778
@Override
78-
public DiscriminatorValueDetails getDetailsForDiscriminatorValue(Object relationalForm) {
79-
if ( relationalForm == null ) {
79+
public DiscriminatorValueDetails getDetailsForDiscriminatorValue(Object relationalValue) {
80+
if ( relationalValue == null ) {
8081
return detailsByValue.get( NULL_DISCRIMINATOR );
8182
}
8283

83-
final DiscriminatorValueDetails existing = detailsByValue.get( relationalForm );
84+
final DiscriminatorValueDetails existing = detailsByValue.get( relationalValue );
8485
if ( existing != null ) {
8586
// an explicit or previously-resolved mapping
8687
return existing;
@@ -91,16 +92,16 @@ public DiscriminatorValueDetails getDetailsForDiscriminatorValue(Object relation
9192
return notNullMatch;
9293
}
9394

94-
if ( relationalForm.getClass().isEnum() ) {
95+
if ( relationalValue.getClass().isEnum() ) {
9596
final Object enumValue;
9697
if ( getRelationalJavaType() instanceof StringJavaType ) {
97-
enumValue = ( (Enum<?>) relationalForm ).name();
98+
enumValue = ( (Enum<?>) relationalValue).name();
9899
}
99100
else if ( getRelationalJavaType() instanceof CharacterJavaType ) {
100-
enumValue = ( (Enum<?>) relationalForm ).name().charAt( 0 );
101+
enumValue = ( (Enum<?>) relationalValue).name().charAt( 0 );
101102
}
102103
else {
103-
enumValue = ( (Enum<?>) relationalForm ).ordinal();
104+
enumValue = ( (Enum<?>) relationalValue).ordinal();
104105
}
105106
final DiscriminatorValueDetails enumMatch = detailsByValue.get( enumValue );
106107
if ( enumMatch != null ) {
@@ -112,7 +113,7 @@ else if ( getRelationalJavaType() instanceof CharacterJavaType ) {
112113
ROOT,
113114
"Unknown discriminator value (%s) : %s",
114115
discriminatorRole,
115-
relationalForm
116+
relationalValue
116117
) );
117118
}
118119

0 commit comments

Comments
 (0)