Skip to content

Commit 923d572

Browse files
committed
HHH-19861 Fix 'EntityNotFoundException when using @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED) on FK fields'
1 parent 33429e9 commit 923d572

File tree

9 files changed

+266
-27
lines changed

9 files changed

+266
-27
lines changed

hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/IdMetadataGenerator.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ else if ( hasNotAuditedEntityConfiguration( referencedEntityName ) ) {
178178
referencedEntityName,
179179
prefixedMapper,
180180
true,
181+
false,
181182
false
182183
);
183184
}

hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/ToOneRelationMetadataGenerator.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55
package org.hibernate.envers.configuration.internal.metadata;
66

7+
import org.hibernate.envers.RelationTargetAuditMode;
78
import org.hibernate.envers.boot.EnversMappingException;
89
import org.hibernate.envers.boot.model.AttributeContainer;
910
import org.hibernate.envers.boot.spi.EnversMetadataBuildingContext;
@@ -62,7 +63,8 @@ public void addToOne(
6263
referencedEntityName,
6364
relMapper,
6465
insertable,
65-
shouldIgnoreNotFoundRelation( propertyAuditingData, value )
66+
shouldIgnoreNotFoundRelation( propertyAuditingData, value ),
67+
propertyAuditingData.getRelationTargetAuditMode() == RelationTargetAuditMode.NOT_AUDITED
6668
);
6769

6870
// If the property isn't insertable, checking if this is not a "fake" bidirectional many-to-one relationship,
@@ -127,7 +129,8 @@ public void addOneToOneNotOwning(
127129
owningReferencePropertyName,
128130
referencedEntityName,
129131
ownedIdMapper,
130-
MappingTools.ignoreNotFound( value )
132+
MappingTools.ignoreNotFound( value ),
133+
propertyAuditingData.getRelationTargetAuditMode() == RelationTargetAuditMode.NOT_AUDITED
131134
);
132135

133136
// Adding mapper for the id
@@ -170,7 +173,8 @@ void addOneToOnePrimaryKeyJoinColumn(
170173
referencedEntityName,
171174
relMapper,
172175
insertable,
173-
MappingTools.ignoreNotFound( value )
176+
MappingTools.ignoreNotFound( value ),
177+
propertyAuditingData.getRelationTargetAuditMode() == RelationTargetAuditMode.NOT_AUDITED
174178
);
175179

176180
// Adding mapper for the id

hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/EntityConfiguration.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ public void addToOneRelation(
5454
String toEntityName,
5555
IdMapper idMapper,
5656
boolean insertable,
57-
boolean ignoreNotFound) {
57+
boolean ignoreNotFound,
58+
boolean targetNotAudited) {
5859
relations.put(
5960
fromPropertyName,
6061
RelationDescription.toOne(
@@ -66,7 +67,8 @@ public void addToOneRelation(
6667
null,
6768
null,
6869
insertable,
69-
ignoreNotFound
70+
ignoreNotFound,
71+
targetNotAudited
7072
)
7173
);
7274
}
@@ -76,7 +78,8 @@ public void addToOneNotOwningRelation(
7678
String mappedByPropertyName,
7779
String toEntityName,
7880
IdMapper idMapper,
79-
boolean ignoreNotFound) {
81+
boolean ignoreNotFound,
82+
boolean targetNotAudited) {
8083
relations.put(
8184
fromPropertyName,
8285
RelationDescription.toOne(
@@ -88,7 +91,8 @@ public void addToOneNotOwningRelation(
8891
null,
8992
null,
9093
true,
91-
ignoreNotFound
94+
ignoreNotFound,
95+
targetNotAudited
9296
)
9397
);
9498
}

hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/EntityInstantiator.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ private void replaceNonAuditIdProxies(Map versionsEntity, Number revision) {
124124
enversService.getConfig().getRevisionTypePropertyName()
125125
)
126126
),
127-
enversService
127+
enversService,
128+
false
128129
);
129130
originalId.put(
130131
key,

hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/RelationDescription.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public class RelationDescription {
1818
private final String toEntityName;
1919
private final String mappedByPropertyName;
2020
private final boolean ignoreNotFound;
21+
private final boolean targetNotAudited;
2122
private final IdMapper idMapper;
2223
private final PropertyMapper fakeBidirectionalRelationMapper;
2324
private final PropertyMapper fakeBidirectionalRelationIndexMapper;
@@ -37,10 +38,11 @@ public static RelationDescription toOne(
3738
PropertyMapper fakeBidirectionalRelationMapper,
3839
PropertyMapper fakeBidirectionalRelationIndexMapper,
3940
boolean insertable,
40-
boolean ignoreNotFound) {
41+
boolean ignoreNotFound,
42+
boolean targetNotAudited) {
4143
return new RelationDescription(
4244
fromPropertyName, relationType, toEntityName, mappedByPropertyName, idMapper,
43-
fakeBidirectionalRelationMapper, fakeBidirectionalRelationIndexMapper, null, null, null, insertable, ignoreNotFound, false
45+
fakeBidirectionalRelationMapper, fakeBidirectionalRelationIndexMapper, null, null, null, insertable, ignoreNotFound, targetNotAudited, false
4446
);
4547
}
4648

@@ -60,10 +62,10 @@ public static RelationDescription toMany(
6062
// Envers populates collections by executing dedicated queries. Special handling of
6163
// @NotFound(action = NotFoundAction.IGNORE) can be omitted in such case as exceptions
6264
// (e.g. EntityNotFoundException, ObjectNotFoundException) are never thrown.
63-
// Therefore assigning false to ignoreNotFound.
65+
// Therefore assigning false to ignoreNotFound and targetNotAudited.
6466
return new RelationDescription(
6567
fromPropertyName, relationType, toEntityName, mappedByPropertyName, idMapper, fakeBidirectionalRelationMapper,
66-
fakeBidirectionalRelationIndexMapper, referencingIdData, referencedIdData, auditMiddleEntityName, insertable, false, indexed
68+
fakeBidirectionalRelationIndexMapper, referencingIdData, referencedIdData, auditMiddleEntityName, insertable, false, false, indexed
6769
);
6870
}
6971

@@ -80,12 +82,14 @@ private RelationDescription(
8082
String auditMiddleEntityName,
8183
boolean insertable,
8284
boolean ignoreNotFound,
85+
boolean targetNotAudited,
8386
boolean indexed) {
8487
this.fromPropertyName = fromPropertyName;
8588
this.relationType = relationType;
8689
this.toEntityName = toEntityName;
8790
this.mappedByPropertyName = mappedByPropertyName;
8891
this.ignoreNotFound = ignoreNotFound;
92+
this.targetNotAudited = targetNotAudited;
8993
this.idMapper = idMapper;
9094
this.fakeBidirectionalRelationMapper = fakeBidirectionalRelationMapper;
9195
this.fakeBidirectionalRelationIndexMapper = fakeBidirectionalRelationIndexMapper;
@@ -117,6 +121,10 @@ public boolean isIgnoreNotFound() {
117121
return ignoreNotFound;
118122
}
119123

124+
public boolean isTargetNotAudited() {
125+
return targetNotAudited;
126+
}
127+
120128
public IdMapper getIdMapper() {
121129
return idMapper;
122130
}

hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/ToOneEntityLoader.java

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,19 @@ public static Object loadImmediate(
2828
Object entityId,
2929
Number revision,
3030
boolean removed,
31-
EnversService enversService) {
32-
if ( enversService.getEntitiesConfigurations().getNotVersionEntityConfiguration( entityName ) == null ) {
31+
EnversService enversService,
32+
boolean isTargetNotAudited) {
33+
34+
if ( isTargetNotAudited || enversService.getEntitiesConfigurations().getNotVersionEntityConfiguration( entityName ) != null ) {
35+
// Not audited relation, look up entity with Hibernate.
36+
return versionsReader.getSessionImplementor().immediateLoad( entityName, entityId );
37+
}
38+
else {
3339
// Audited relation, look up entity with Envers.
3440
// When user traverses removed entities graph, do not restrict revision type of referencing objects
3541
// to ADD or MOD (DEL possible). See HHH-5845.
3642
return versionsReader.find( entityClass, entityName, entityId, revision, removed );
3743
}
38-
else {
39-
// Not audited relation, look up entity with Hibernate.
40-
return versionsReader.getSessionImplementor().immediateLoad( entityName, entityId );
41-
}
4244
}
4345

4446
/**
@@ -51,14 +53,15 @@ public static Object createProxy(
5153
Object entityId,
5254
Number revision,
5355
boolean removed,
54-
EnversService enversService) {
56+
EnversService enversService,
57+
boolean isTargetNotAudited) {
5558
final EntityPersister persister = versionsReader.getSessionImplementor()
5659
.getFactory()
5760
.getMappingMetamodel()
5861
.getEntityDescriptor( entityName );
5962
return persister.createProxy(
6063
entityId,
61-
new ToOneDelegateSessionImplementor( versionsReader, entityClass, entityId, revision, removed, enversService )
64+
new ToOneDelegateSessionImplementor( versionsReader, entityClass, entityId, revision, removed, enversService, isTargetNotAudited )
6265
);
6366
}
6467

@@ -73,14 +76,15 @@ public static Object createProxyOrLoadImmediate(
7376
Object entityId,
7477
Number revision,
7578
boolean removed,
76-
EnversService enversService) {
79+
EnversService enversService,
80+
boolean isTargetNotAudited) {
7781
final EntityPersister persister = versionsReader.getSessionImplementor()
7882
.getFactory()
7983
.getMappingMetamodel()
8084
.getEntityDescriptor( entityName );
8185
if ( persister.hasProxy() ) {
82-
return createProxy( versionsReader, entityClass, entityName, entityId, revision, removed, enversService );
86+
return createProxy( versionsReader, entityClass, entityName, entityId, revision, removed, enversService, isTargetNotAudited );
8387
}
84-
return loadImmediate( versionsReader, entityClass, entityName, entityId, revision, removed, enversService );
88+
return loadImmediate( versionsReader, entityClass, entityName, entityId, revision, removed, enversService, isTargetNotAudited );
8589
}
8690
}

hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/ToOneIdMapper.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,15 @@ public Object nullSafeMapToEntityFromMap(
150150
}
151151
else {
152152
final EntityInfo referencedEntity = getEntityInfo( enversService, referencedEntityName );
153+
154+
// Check if the relation is marked as NOT_AUDITED
155+
final String referencingEntityName = enversService.getEntitiesConfigurations()
156+
.getEntityNameForVersionsEntityName( (String) data.get( "$type$" ) );
157+
final boolean isTargetNotAudited = referencingEntityName != null &&
158+
enversService.getEntitiesConfigurations()
159+
.getRelationDescription( referencingEntityName, getPropertyData().getName() )
160+
.isTargetNotAudited();
161+
153162
if ( isIgnoreNotFound( enversService, referencedEntity, data, primaryKey ) ) {
154163
// Eagerly loading referenced entity to silence potential (in case of proxy)
155164
// EntityNotFoundException or ObjectNotFoundException. Assigning null reference.
@@ -160,7 +169,8 @@ public Object nullSafeMapToEntityFromMap(
160169
entityId,
161170
revision,
162171
RevisionType.DEL.equals( data.get( enversService.getConfig().getRevisionTypePropertyName() ) ),
163-
enversService
172+
enversService,
173+
isTargetNotAudited
164174
);
165175
}
166176
else {
@@ -171,7 +181,8 @@ public Object nullSafeMapToEntityFromMap(
171181
entityId,
172182
revision,
173183
RevisionType.DEL.equals( data.get( enversService.getConfig().getRevisionTypePropertyName() ) ),
174-
enversService
184+
enversService,
185+
isTargetNotAudited
175186
);
176187
}
177188
}

hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/ToOneDelegateSessionImplementor.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,24 @@ public class ToOneDelegateSessionImplementor extends AbstractDelegateSessionImpl
2323
private final Number revision;
2424
private final boolean removed;
2525
private final EnversService enversService;
26+
private final boolean isTargetNotAudited;
2627

2728
public ToOneDelegateSessionImplementor(
2829
AuditReaderImplementor versionsReader,
2930
Class<?> entityClass,
3031
Object entityId,
3132
Number revision,
3233
boolean removed,
33-
EnversService enversService) {
34+
EnversService enversService,
35+
boolean isTargetNotAudited) {
3436
super( versionsReader.getSessionImplementor() );
3537
this.versionsReader = versionsReader;
3638
this.entityClass = entityClass;
3739
this.entityId = entityId;
3840
this.revision = revision;
3941
this.removed = removed;
4042
this.enversService = enversService;
43+
this.isTargetNotAudited = isTargetNotAudited;
4144
}
4245

4346
@Override
@@ -49,7 +52,8 @@ public Object doImmediateLoad(String entityName) throws HibernateException {
4952
entityId,
5053
revision,
5154
removed,
52-
enversService
55+
enversService,
56+
isTargetNotAudited
5357
);
5458
}
5559
}

0 commit comments

Comments
 (0)