Skip to content

Commit 5e91b1e

Browse files
committed
HHH-18131 Composite identifiers with associations stopped working with @IdClass
1 parent d10d3f9 commit 5e91b1e

9 files changed

+88
-9
lines changed

hibernate-core/src/main/java/org/hibernate/event/internal/DefaultMergeEventListener.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ private void merge(MergeEvent event, MergeContext copiedAlready, Object entity)
162162
final Object originalId;
163163
if ( entry == null ) {
164164
final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
165-
originalId = persister.getIdentifier( entity, source );
165+
originalId = persister.getIdentifier( entity, copiedAlready, source );
166166
if ( originalId != null ) {
167167
final EntityKey entityKey;
168168
if ( persister.getIdentifierType() instanceof ComponentType ) {

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import org.hibernate.engine.internal.ForeignKeys;
99
import org.hibernate.engine.spi.IdentifierValue;
1010
import org.hibernate.engine.spi.SharedSessionContractImplementor;
11+
import org.hibernate.event.spi.MergeContext;
1112

1213
import jakarta.persistence.EmbeddedId;
1314
import jakarta.persistence.Id;
@@ -66,6 +67,15 @@ default String getPartName() {
6667
*/
6768
Object getIdentifier(Object entity);
6869

70+
/**
71+
* Extract the identifier from an instance of the entity
72+
*
73+
* It's supposed to be use during the merging process
74+
*/
75+
default Object getIdentifier(Object entity, MergeContext mergeContext){
76+
return getIdentifier( entity );
77+
}
78+
6979
/**
7080
* Return the identifier of the persistent or transient object, or throw
7181
* an exception if the instance is "unsaved"

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

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.hibernate.engine.spi.EntityKey;
1313
import org.hibernate.engine.spi.PersistenceContext;
1414
import org.hibernate.engine.spi.SharedSessionContractImplementor;
15+
import org.hibernate.event.spi.MergeContext;
1516
import org.hibernate.internal.util.collections.CollectionHelper;
1617
import org.hibernate.metamodel.mapping.AttributeMapping;
1718
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
@@ -194,6 +195,11 @@ public SqlTuple toSqlExpression(
194195

195196
@Override
196197
public Object getIdentifier(Object entity) {
198+
return getIdentifier( entity, null );
199+
}
200+
201+
@Override
202+
public Object getIdentifier(Object entity, MergeContext mergeContext) {
197203
if ( hasContainingClass() ) {
198204
final Object id = identifierValueMapper.getRepresentationStrategy().getInstantiator().instantiate(
199205
null,
@@ -214,17 +220,18 @@ public Object getIdentifier(Object entity) {
214220
}
215221
}
216222
//JPA 2 @MapsId + @IdClass points to the pk of the entity
217-
else if ( attributeMapping instanceof ToOneAttributeMapping
223+
else if ( attributeMapping instanceof ToOneAttributeMapping toOneAttributeMapping
218224
&& !( identifierValueMapper.getAttributeMapping( i ) instanceof ToOneAttributeMapping ) ) {
219-
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) attributeMapping;
225+
final Object toOne = getIfMerged( o, mergeContext );
220226
final ModelPart targetPart = toOneAttributeMapping.getForeignKeyDescriptor().getPart(
221227
toOneAttributeMapping.getSideNature().inverse()
222228
);
223229
if ( targetPart.isEntityIdentifierMapping() ) {
224-
propertyValues[i] = ( (EntityIdentifierMapping) targetPart ).getIdentifier( o );
230+
propertyValues[i] = ( (EntityIdentifierMapping) targetPart )
231+
.getIdentifier( toOne );
225232
}
226233
else {
227-
propertyValues[i] = o;
234+
propertyValues[i] = toOne;
228235
assert false;
229236
}
230237
}
@@ -240,6 +247,16 @@ else if ( attributeMapping instanceof ToOneAttributeMapping
240247
}
241248
}
242249

250+
private static Object getIfMerged(Object o, MergeContext mergeContext) {
251+
if ( mergeContext != null ) {
252+
final Object merged = mergeContext.get( o );
253+
if ( merged != null ) {
254+
return merged;
255+
}
256+
}
257+
return o;
258+
}
259+
243260
@Override
244261
public void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session) {
245262
final Object[] propertyValues = new Object[identifierValueMapper.getNumberOfAttributeMappings()];

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

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import org.hibernate.engine.spi.EntityKey;
1414
import org.hibernate.engine.spi.PersistenceContext;
1515
import org.hibernate.engine.spi.SharedSessionContractImplementor;
16+
import org.hibernate.event.spi.MergeContext;
1617
import org.hibernate.internal.util.collections.CollectionHelper;
1718
import org.hibernate.mapping.Component;
1819
import org.hibernate.mapping.RootClass;
@@ -235,6 +236,11 @@ public String getAttributeName() {
235236

236237
@Override
237238
public Object getIdentifier(Object entity) {
239+
return getIdentifier( entity, null );
240+
}
241+
242+
@Override
243+
public Object getIdentifier(Object entity, MergeContext mergeContext) {
238244
if ( hasContainingClass() ) {
239245
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( entity );
240246
if ( lazyInitializer != null ) {
@@ -255,17 +261,17 @@ public Object getIdentifier(Object entity) {
255261
}
256262
}
257263
//JPA 2 @MapsId + @IdClass points to the pk of the entity
258-
else if ( attributeMapping instanceof ToOneAttributeMapping
264+
else if ( attributeMapping instanceof ToOneAttributeMapping toOneAttributeMapping
259265
&& !( identifierValueMapper.getAttributeMapping( i ) instanceof ToOneAttributeMapping ) ) {
260-
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) attributeMapping;
266+
final Object toOne = getIfMerged( o, mergeContext );
261267
final ModelPart targetPart = toOneAttributeMapping.getForeignKeyDescriptor().getPart(
262268
toOneAttributeMapping.getSideNature().inverse()
263269
);
264270
if ( targetPart.isEntityIdentifierMapping() ) {
265-
propertyValues[i] = ( (EntityIdentifierMapping) targetPart ).getIdentifier( o );
271+
propertyValues[i] = ( (EntityIdentifierMapping) targetPart ).getIdentifier( toOne );
266272
}
267273
else {
268-
propertyValues[i] = o;
274+
propertyValues[i] = toOne;
269275
assert false;
270276
}
271277
}
@@ -283,6 +289,16 @@ else if ( attributeMapping instanceof ToOneAttributeMapping
283289
}
284290
}
285291

292+
private static Object getIfMerged(Object o, MergeContext mergeContext) {
293+
if ( mergeContext != null ) {
294+
final Object merged = mergeContext.get( o );
295+
if ( merged != null ) {
296+
return merged;
297+
}
298+
}
299+
return o;
300+
}
301+
286302
@Override
287303
public void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session) {
288304
final Object[] propertyValues = new Object[identifierValueMapper.getNumberOfAttributeMappings()];

hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@
9494
import org.hibernate.engine.spi.SharedSessionContractImplementor;
9595
import org.hibernate.event.spi.EventSource;
9696
import org.hibernate.event.spi.LoadEvent;
97+
import org.hibernate.event.spi.MergeContext;
9798
import org.hibernate.generator.BeforeExecutionGenerator;
9899
import org.hibernate.generator.EventType;
99100
import org.hibernate.generator.Generator;
@@ -4287,6 +4288,11 @@ public Object getIdentifier(Object entity, SharedSessionContractImplementor sess
42874288
return identifierMapping.getIdentifier( entity );
42884289
}
42894290

4291+
@Override
4292+
public Object getIdentifier(Object entity, MergeContext mergeContext, SharedSessionContractImplementor session) {
4293+
return identifierMapping.getIdentifier( entity, mergeContext );
4294+
}
4295+
42904296
@Override
42914297
public void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session) {
42924298
identifierMapping.setIdentifier( entity, id, session );

hibernate-core/src/main/java/org/hibernate/persister/entity/EntityPersister.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.hibernate.engine.spi.SessionImplementor;
2929
import org.hibernate.engine.spi.SharedSessionContractImplementor;
3030
import org.hibernate.event.spi.EventSource;
31+
import org.hibernate.event.spi.MergeContext;
3132
import org.hibernate.generator.BeforeExecutionGenerator;
3233
import org.hibernate.generator.EventType;
3334
import org.hibernate.generator.Generator;
@@ -1129,6 +1130,16 @@ default Object getValue(Object object, int i) {
11291130
*/
11301131
Object getIdentifier(Object entity, SharedSessionContractImplementor session);
11311132

1133+
/**
1134+
* Get the identifier of an instance from the object's identifier property.
1135+
* Throw an exception if it has no identifier property.
1136+
*
1137+
* It's supposed to be use during the merging process
1138+
*/
1139+
default Object getIdentifier(Object entity, MergeContext mergeContext, SharedSessionContractImplementor session) {
1140+
return getIdentifier( entity, session );
1141+
}
1142+
11321143
/**
11331144
* Inject the identifier value into the given entity.
11341145
*/

hibernate-core/src/main/java/org/hibernate/query/derived/AnonymousTupleBasicEntityIdentifierMapping.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import org.hibernate.Incubating;
88
import org.hibernate.engine.spi.IdentifierValue;
99
import org.hibernate.engine.spi.SharedSessionContractImplementor;
10+
import org.hibernate.event.spi.MergeContext;
1011
import org.hibernate.metamodel.mapping.BasicEntityIdentifierMapping;
1112
import org.hibernate.metamodel.mapping.JdbcMapping;
1213
import org.hibernate.metamodel.mapping.ManagedMappingType;
@@ -49,6 +50,11 @@ public Object getIdentifier(Object entity) {
4950
return delegate.getIdentifier( entity );
5051
}
5152

53+
@Override
54+
public Object getIdentifier(Object entity, MergeContext mergeContext) {
55+
return delegate.getIdentifier( entity, mergeContext );
56+
}
57+
5258
@Override
5359
public void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session) {
5460
delegate.setIdentifier( entity, id, session );

hibernate-core/src/main/java/org/hibernate/query/derived/AnonymousTupleEmbeddedEntityIdentifierMapping.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.hibernate.Incubating;
1111
import org.hibernate.engine.spi.IdentifierValue;
1212
import org.hibernate.engine.spi.SharedSessionContractImplementor;
13+
import org.hibernate.event.spi.MergeContext;
1314
import org.hibernate.metamodel.mapping.CompositeIdentifierMapping;
1415
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
1516
import org.hibernate.metamodel.mapping.internal.SingleAttributeIdentifierMapping;
@@ -68,6 +69,11 @@ public Object getIdentifier(Object entity) {
6869
return delegate.getIdentifier( entity );
6970
}
7071

72+
@Override
73+
public Object getIdentifier(Object entity, MergeContext mergeContext) {
74+
return delegate.getIdentifier( entity, mergeContext );
75+
}
76+
7177
@Override
7278
public void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session) {
7379
delegate.setIdentifier( entity, id, session );

hibernate-core/src/main/java/org/hibernate/query/derived/AnonymousTupleNonAggregatedEntityIdentifierMapping.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.hibernate.engine.FetchTiming;
1313
import org.hibernate.engine.spi.IdentifierValue;
1414
import org.hibernate.engine.spi.SharedSessionContractImplementor;
15+
import org.hibernate.event.spi.MergeContext;
1516
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
1617
import org.hibernate.metamodel.mapping.NonAggregatedIdentifierMapping;
1718
import org.hibernate.metamodel.mapping.internal.IdClassEmbeddable;
@@ -77,6 +78,12 @@ public Object getIdentifier(Object entity) {
7778
return delegate.getIdentifier( entity );
7879
}
7980

81+
82+
@Override
83+
public Object getIdentifier(Object entity, MergeContext mergeContext) {
84+
return delegate.getIdentifier( entity, mergeContext );
85+
}
86+
8087
@Override
8188
public void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session) {
8289
delegate.setIdentifier( entity, id, session );

0 commit comments

Comments
 (0)