Skip to content

Commit 6913234

Browse files
committed
HHH-18131 Composite identifiers with associations stopped working with @IdClass
1 parent 1e50105 commit 6913234

14 files changed

+108
-19
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 );
166166
if ( originalId != null ) {
167167
final EntityKey entityKey;
168168
if ( persister.getIdentifierType() instanceof ComponentType ) {

hibernate-core/src/main/java/org/hibernate/event/spi/MergeContext.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,4 +364,8 @@ private String printEntity(Object entity) {
364364
// Entity was not found in current persistence context. Use Object#toString() method.
365365
return "[" + entity + "]";
366366
}
367+
368+
public EventSource getEventSource() {
369+
return session;
370+
}
367371
}

hibernate-core/src/main/java/org/hibernate/internal/util/EntityPrinter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public String toString(String entityName, Object entity) throws HibernateExcepti
5151
result.put(
5252
entityPersister.getIdentifierPropertyName(),
5353
entityPersister.getIdentifierType().toLoggableString(
54-
entityPersister.getIdentifier( entity, null ),
54+
entityPersister.getIdentifier( entity ),
5555
factory
5656
)
5757
);

hibernate-core/src/main/java/org/hibernate/jpa/internal/PersistenceUnitUtilImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ private Object getIdentifierFromPersister(Object entity) {
159159
catch (MappingException ex) {
160160
throw new IllegalArgumentException( entityClass.getName() + " is not an entity", ex );
161161
}
162-
return persister.getIdentifier( entity, null );
162+
return persister.getIdentifier( entity );
163163
}
164164

165165
private Object getVersionFromPersister(Object entity) {

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 & 5 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,18 +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, mergeContext );
225232
}
226233
else {
227-
propertyValues[i] = o;
228-
assert false;
234+
propertyValues[i] = toOne;
229235
}
230236
}
231237
else {
@@ -240,6 +246,16 @@ else if ( attributeMapping instanceof ToOneAttributeMapping
240246
}
241247
}
242248

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

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

Lines changed: 20 additions & 5 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,18 +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, mergeContext );
266272
}
267273
else {
268-
propertyValues[i] = o;
269-
assert false;
274+
propertyValues[i] = toOne;
270275
}
271276
}
272277
else {
@@ -283,6 +288,16 @@ else if ( attributeMapping instanceof ToOneAttributeMapping
283288
}
284289
}
285290

291+
private static Object getIfMerged(Object o, MergeContext mergeContext) {
292+
if ( mergeContext != null ) {
293+
final Object merged = mergeContext.get( o );
294+
if ( merged != null ) {
295+
return merged;
296+
}
297+
}
298+
return o;
299+
}
300+
286301
@Override
287302
public void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session) {
288303
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;
@@ -4297,6 +4298,11 @@ public Object getIdentifier(Object entity, SharedSessionContractImplementor sess
42974298
return identifierMapping.getIdentifier( entity );
42984299
}
42994300

4301+
@Override
4302+
public Object getIdentifier(Object entity, MergeContext mergeContext) {
4303+
return identifierMapping.getIdentifier( entity, mergeContext );
4304+
}
4305+
43004306
@Override
43014307
public void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session) {
43024308
identifierMapping.setIdentifier( entity, id, session );

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

Lines changed: 19 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,24 @@ 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) {
1140+
return getIdentifier( entity, mergeContext.getEventSource() );
1141+
}
1142+
1143+
/**
1144+
* Get the identifier of an instance from the object's identifier property.
1145+
* Throw an exception if it has no identifier property.
1146+
*/
1147+
default Object getIdentifier(Object entity) {
1148+
return getIdentifier( entity, (SharedSessionContractImplementor) null );
1149+
}
1150+
11321151
/**
11331152
* Inject the identifier value into the given entity.
11341153
*/

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 );

0 commit comments

Comments
 (0)