Skip to content

Commit e3245cb

Browse files
committed
HHH-16383 - NaturalIdClass
# Conflicts: # hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/CompoundNaturalIdMapping.java
1 parent 8140c65 commit e3245cb

File tree

6 files changed

+264
-39
lines changed

6 files changed

+264
-39
lines changed

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

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,40 @@
2929
import org.hibernate.AnnotationException;
3030
import org.hibernate.AssertionFailure;
3131
import org.hibernate.MappingException;
32-
import org.hibernate.annotations.*;
32+
import org.hibernate.annotations.Cache;
33+
import org.hibernate.annotations.CacheConcurrencyStrategy;
34+
import org.hibernate.annotations.CacheLayout;
35+
import org.hibernate.annotations.Check;
36+
import org.hibernate.annotations.Checks;
37+
import org.hibernate.annotations.ConcreteProxy;
38+
import org.hibernate.annotations.DiscriminatorFormula;
39+
import org.hibernate.annotations.DynamicInsert;
40+
import org.hibernate.annotations.DynamicUpdate;
41+
import org.hibernate.annotations.Filter;
42+
import org.hibernate.annotations.Filters;
43+
import org.hibernate.annotations.HQLSelect;
44+
import org.hibernate.annotations.Immutable;
45+
import org.hibernate.annotations.Mutability;
46+
import org.hibernate.annotations.NaturalIdCache;
47+
import org.hibernate.annotations.NaturalIdClass;
48+
import org.hibernate.annotations.OnDelete;
49+
import org.hibernate.annotations.OptimisticLockType;
50+
import org.hibernate.annotations.OptimisticLocking;
51+
import org.hibernate.annotations.QueryCacheLayout;
52+
import org.hibernate.annotations.RowId;
53+
import org.hibernate.annotations.SQLDelete;
54+
import org.hibernate.annotations.SQLDeleteAll;
55+
import org.hibernate.annotations.SQLInsert;
56+
import org.hibernate.annotations.SQLRestriction;
57+
import org.hibernate.annotations.SQLSelect;
58+
import org.hibernate.annotations.SQLUpdate;
59+
import org.hibernate.annotations.SecondaryRow;
60+
import org.hibernate.annotations.SecondaryRows;
61+
import org.hibernate.annotations.SoftDelete;
62+
import org.hibernate.annotations.Subselect;
63+
import org.hibernate.annotations.Synchronize;
64+
import org.hibernate.annotations.TypeBinderType;
65+
import org.hibernate.annotations.View;
3366
import org.hibernate.binder.TypeBinder;
3467
import org.hibernate.boot.model.NamedEntityGraphDefinition;
3568
import org.hibernate.boot.model.internal.InheritanceState.ElementsToProcess;
@@ -86,6 +119,7 @@
86119

87120
import static jakarta.persistence.InheritanceType.SINGLE_TABLE;
88121
import static java.util.Collections.addAll;
122+
import static org.hibernate.boot.BootLogging.BOOT_LOGGER;
89123
import static org.hibernate.boot.model.internal.AnnotatedClassType.MAPPED_SUPERCLASS;
90124
import static org.hibernate.boot.model.internal.AnnotatedDiscriminatorColumn.DEFAULT_DISCRIMINATOR_COLUMN_NAME;
91125
import static org.hibernate.boot.model.internal.AnnotatedDiscriminatorColumn.buildDiscriminatorColumn;
@@ -112,7 +146,6 @@
112146
import static org.hibernate.boot.spi.AccessType.getAccessStrategy;
113147
import static org.hibernate.engine.OptimisticLockStyle.fromLockType;
114148
import static org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle.fromResultCheckStyle;
115-
import static org.hibernate.boot.BootLogging.BOOT_LOGGER;
116149
import static org.hibernate.internal.util.ReflectHelper.getDefaultSupplier;
117150
import static org.hibernate.internal.util.StringHelper.isBlank;
118151
import static org.hibernate.internal.util.StringHelper.isNotBlank;
@@ -159,7 +192,7 @@ public class EntityBinder {
159192
private String cacheRegion;
160193
private boolean cacheLazyProperty;
161194
private String naturalIdCacheRegion;
162-
private Class<?> naturalIdClass;
195+
private ClassDetails naturalIdClass;
163196
private CacheLayout queryCacheLayout;
164197

165198
private ModelsContext modelsContext() {
@@ -1340,7 +1373,7 @@ private void bindRootEntity() {
13401373
rootClass.setLazyPropertiesCacheable( cacheLazyProperty );
13411374
}
13421375
rootClass.setNaturalIdCacheRegionName( naturalIdCacheRegion );
1343-
rootClass.setNaturalIdClass( naturalIdClass );
1376+
rootClass.setNaturalIdClass( naturalIdClass );
13441377
}
13451378

13461379
private void bindCustomSql() {
@@ -1618,7 +1651,16 @@ private SQLRestriction extractSQLRestriction(ClassDetails classDetails) {
16181651

16191652
private void bindNaturalIdClass() {
16201653
final var ann = annotatedClass.getAnnotationUsage( NaturalIdClass.class, modelsContext() );
1621-
naturalIdClass = ann != null ? ann.value() : null;
1654+
if ( ann != null ) {
1655+
if ( ann.value() == void.class ) {
1656+
throw new IllegalStateException( "NaturalIdClass#value must not be void.class" );
1657+
}
1658+
naturalIdClass = context
1659+
.getBootstrapContext()
1660+
.getModelsContext()
1661+
.getClassDetailsRegistry()
1662+
.resolveClassDetails( ann.value().getName() );
1663+
}
16221664
}
16231665

16241666
private void bindNaturalIdCache() {

hibernate-core/src/main/java/org/hibernate/internal/NaturalIdMultiLoadAccessStandard.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,11 @@ public List<T> multiLoad(Object... ids) {
151151
}
152152

153153
try {
154+
// normalize the incoming natural-id values
155+
for ( int i = 0; i < ids.length; i++ ) {
156+
ids[i] = entityDescriptor.getNaturalIdMapping().normalizeInput( ids[ i ] );
157+
}
158+
154159
return (List<T>)
155160
entityDescriptor.getMultiNaturalIdLoader()
156161
.multiLoad( ids, this, session );

hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractMultiNaturalIdLoader.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,8 @@ private <K> Object[] checkPersistenceContextForCachedResults(
144144
Consumer<E> results ) {
145145
final List<K> unresolvedIds = arrayList( naturalIds.length );
146146
final var context = session.getPersistenceContextInternal();
147-
final var naturalIdMapping = getEntityDescriptor().getNaturalIdMapping();
148147
for ( K naturalId : naturalIds ) {
149-
final Object entity = entityForNaturalId( context, naturalIdMapping.normalizeInput( naturalId ) );
148+
final Object entity = entityForNaturalId( context, naturalId );
150149
if ( entity != null ) {
151150
// Entity is already in the persistence context
152151
final var entry = context.getEntry( entity );

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.hibernate.annotations.SoftDeleteType;
1313
import org.hibernate.boot.Metadata;
1414
import org.hibernate.boot.spi.MetadataBuildingContext;
15+
import org.hibernate.models.spi.ClassDetails;
1516

1617
import static org.hibernate.internal.CoreMessageLogger.CORE_LOGGER;
1718
import static org.hibernate.internal.util.ReflectHelper.overridesEquals;
@@ -34,7 +35,7 @@ public final class RootClass extends PersistentClass implements TableOwner, Soft
3435
private String cacheConcurrencyStrategy;
3536
private String cacheRegionName;
3637
private boolean lazyPropertiesCacheable = true;
37-
private Class<?> naturalIdClass;
38+
private ClassDetails naturalIdClass;
3839
private String naturalIdCacheRegionName;
3940

4041
private Value discriminator;
@@ -366,11 +367,11 @@ public void setLazyPropertiesCacheable(boolean lazyPropertiesCacheable) {
366367
this.lazyPropertiesCacheable = lazyPropertiesCacheable;
367368
}
368369

369-
public Class<?> getNaturalIdClass() {
370+
public ClassDetails getNaturalIdClass() {
370371
return naturalIdClass;
371372
}
372373

373-
public void setNaturalIdClass(Class<?> naturalIdClass) {
374+
public void setNaturalIdClass(ClassDetails naturalIdClass) {
374375
this.naturalIdClass = naturalIdClass;
375376
}
376377

0 commit comments

Comments
 (0)