Skip to content

Commit 28a653c

Browse files
committed
HHH-17612 HHH-18762 Separate envers default revision entity types from mapped-superclasses
Also, ensure they're query-able through Criteria and HQL queries
1 parent 009905c commit 28a653c

File tree

18 files changed

+365
-303
lines changed

18 files changed

+365
-303
lines changed

hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/ModelBinder.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,10 @@ private void bindBasicEntityValues(
364364
entityDescriptor.setEntityName( entitySource.getEntityNamingSource().getEntityName() );
365365
entityDescriptor.setJpaEntityName( entitySource.getEntityNamingSource().getJpaEntityName() );
366366
entityDescriptor.setClassName( entitySource.getEntityNamingSource().getClassName() );
367+
if ( entityDescriptor.getJpaEntityName() != null && entityDescriptor.getClassName() != null ) {
368+
metadataBuildingContext.getMetadataCollector()
369+
.addImport( entityDescriptor.getJpaEntityName(), entityDescriptor.getClassName() );
370+
}
367371

368372
entityDescriptor.setDiscriminatorValue(
369373
entitySource.getDiscriminatorMatchValue() != null

hibernate-envers/src/main/java/org/hibernate/envers/DefaultRevisionEntity.java

Lines changed: 3 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -4,76 +4,12 @@
44
*/
55
package org.hibernate.envers;
66

7-
import java.io.Serializable;
8-
import java.util.Date;
9-
10-
import jakarta.persistence.GeneratedValue;
11-
import jakarta.persistence.Id;
12-
import jakarta.persistence.MappedSuperclass;
13-
import jakarta.persistence.Transient;
7+
import jakarta.persistence.Entity;
148

159
/**
1610
* @author Adam Warski (adam at warski dot org)
1711
* @author Chris Cranford
1812
*/
19-
@MappedSuperclass
20-
public class DefaultRevisionEntity implements Serializable {
21-
private static final long serialVersionUID = 8530213963961662300L;
22-
23-
@Id
24-
@GeneratedValue
25-
@RevisionNumber
26-
private int id;
27-
28-
@RevisionTimestamp
29-
private long timestamp;
30-
31-
public int getId() {
32-
return id;
33-
}
34-
35-
public void setId(int id) {
36-
this.id = id;
37-
}
38-
39-
@Transient
40-
public Date getRevisionDate() {
41-
return new Date( timestamp );
42-
}
43-
44-
public long getTimestamp() {
45-
return timestamp;
46-
}
47-
48-
public void setTimestamp(long timestamp) {
49-
this.timestamp = timestamp;
50-
}
51-
52-
@Override
53-
public boolean equals(Object o) {
54-
if ( this == o ) {
55-
return true;
56-
}
57-
if ( !(o instanceof DefaultRevisionEntity) ) {
58-
return false;
59-
}
60-
61-
final DefaultRevisionEntity that = (DefaultRevisionEntity) o;
62-
return id == that.id
63-
&& timestamp == that.timestamp;
64-
}
65-
66-
@Override
67-
public int hashCode() {
68-
int result;
69-
result = id;
70-
result = 31 * result + (int) (timestamp ^ (timestamp >>> 32));
71-
return result;
72-
}
73-
74-
@Override
75-
public String toString() {
76-
return "DefaultRevisionEntity(id = " + id
77-
+ ", revisionDate = " + DateTimeFormatter.INSTANCE.format(getRevisionDate() ) + ")";
78-
}
13+
@Entity
14+
public final class DefaultRevisionEntity extends RevisionMapping {
7915
}

hibernate-envers/src/main/java/org/hibernate/envers/DefaultTrackingModifiedEntitiesRevisionEntity.java

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

7-
import java.util.HashSet;
8-
import java.util.Set;
9-
import jakarta.persistence.Column;
10-
import jakarta.persistence.ElementCollection;
11-
import jakarta.persistence.FetchType;
12-
import jakarta.persistence.JoinColumn;
13-
import jakarta.persistence.JoinTable;
14-
import jakarta.persistence.MappedSuperclass;
15-
16-
import org.hibernate.annotations.Fetch;
17-
import org.hibernate.annotations.FetchMode;
7+
import jakarta.persistence.Entity;
188

199
/**
2010
* Extension of standard {@link DefaultRevisionEntity} that allows tracking entity names changed in each revision.
@@ -23,54 +13,6 @@
2313
*
2414
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
2515
*/
26-
@MappedSuperclass
27-
public class DefaultTrackingModifiedEntitiesRevisionEntity extends DefaultRevisionEntity {
28-
@ElementCollection(fetch = FetchType.EAGER)
29-
@JoinTable(name = "REVCHANGES", joinColumns = @JoinColumn(name = "REV"))
30-
@Column(name = "ENTITYNAME")
31-
@Fetch(FetchMode.JOIN)
32-
@ModifiedEntityNames
33-
private Set<String> modifiedEntityNames = new HashSet<>();
34-
35-
public Set<String> getModifiedEntityNames() {
36-
return modifiedEntityNames;
37-
}
38-
39-
public void setModifiedEntityNames(Set<String> modifiedEntityNames) {
40-
this.modifiedEntityNames = modifiedEntityNames;
41-
}
42-
43-
@Override
44-
public boolean equals(Object o) {
45-
if ( this == o ) {
46-
return true;
47-
}
48-
if ( !(o instanceof DefaultTrackingModifiedEntitiesRevisionEntity) ) {
49-
return false;
50-
}
51-
if ( !super.equals( o ) ) {
52-
return false;
53-
}
54-
55-
final DefaultTrackingModifiedEntitiesRevisionEntity that = (DefaultTrackingModifiedEntitiesRevisionEntity) o;
56-
57-
if ( modifiedEntityNames != null ? !modifiedEntityNames.equals( that.modifiedEntityNames )
58-
: that.modifiedEntityNames != null ) {
59-
return false;
60-
}
61-
62-
return true;
63-
}
64-
65-
@Override
66-
public int hashCode() {
67-
int result = super.hashCode();
68-
result = 31 * result + (modifiedEntityNames != null ? modifiedEntityNames.hashCode() : 0);
69-
return result;
70-
}
71-
72-
@Override
73-
public String toString() {
74-
return "DefaultTrackingModifiedEntitiesRevisionEntity(" + super.toString() + ", modifiedEntityNames = " + modifiedEntityNames + ")";
75-
}
16+
@Entity
17+
public final class DefaultTrackingModifiedEntitiesRevisionEntity extends TrackingModifiedEntitiesRevisionMapping {
7618
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* SPDX-License-Identifier: LGPL-2.1-or-later
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.envers;
6+
7+
import jakarta.persistence.GeneratedValue;
8+
import jakarta.persistence.Id;
9+
import jakarta.persistence.MappedSuperclass;
10+
import jakarta.persistence.Transient;
11+
12+
import java.io.Serializable;
13+
import java.util.Date;
14+
15+
/**
16+
* @author Adam Warski (adam at warski dot org)
17+
* @author Chris Cranford
18+
*/
19+
@MappedSuperclass
20+
public class RevisionMapping implements Serializable {
21+
private static final long serialVersionUID = 8530213963961662300L;
22+
23+
@Id
24+
@GeneratedValue
25+
@RevisionNumber
26+
private int id;
27+
28+
@RevisionTimestamp
29+
private long timestamp;
30+
31+
public int getId() {
32+
return id;
33+
}
34+
35+
public void setId(int id) {
36+
this.id = id;
37+
}
38+
39+
@Transient
40+
public Date getRevisionDate() {
41+
return new Date( timestamp );
42+
}
43+
44+
public long getTimestamp() {
45+
return timestamp;
46+
}
47+
48+
public void setTimestamp(long timestamp) {
49+
this.timestamp = timestamp;
50+
}
51+
52+
@Override
53+
public boolean equals(Object o) {
54+
if ( this == o ) {
55+
return true;
56+
}
57+
if ( !(o instanceof RevisionMapping) ) {
58+
return false;
59+
}
60+
61+
final RevisionMapping that = (RevisionMapping) o;
62+
return id == that.id
63+
&& timestamp == that.timestamp;
64+
}
65+
66+
@Override
67+
public int hashCode() {
68+
int result;
69+
result = id;
70+
result = 31 * result + (int) (timestamp ^ (timestamp >>> 32));
71+
return result;
72+
}
73+
74+
@Override
75+
public String toString() {
76+
return "DefaultRevisionEntity(id = " + id
77+
+ ", revisionDate = " + DateTimeFormatter.INSTANCE.format(getRevisionDate() ) + ")";
78+
}
79+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* SPDX-License-Identifier: LGPL-2.1-or-later
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.envers;
6+
7+
import jakarta.persistence.Column;
8+
import jakarta.persistence.ElementCollection;
9+
import jakarta.persistence.FetchType;
10+
import jakarta.persistence.JoinColumn;
11+
import jakarta.persistence.JoinTable;
12+
import jakarta.persistence.MappedSuperclass;
13+
import org.hibernate.annotations.Fetch;
14+
import org.hibernate.annotations.FetchMode;
15+
16+
import java.util.HashSet;
17+
import java.util.Set;
18+
19+
/**
20+
* Extension of standard {@link RevisionMapping} that allows tracking entity names changed in each revision.
21+
* This revision entity is implicitly used when {@code org.hibernate.envers.track_entities_changed_in_revision}
22+
* parameter is set to {@code true}.
23+
*
24+
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
25+
*/
26+
@MappedSuperclass
27+
public class TrackingModifiedEntitiesRevisionMapping extends RevisionMapping {
28+
@ElementCollection(fetch = FetchType.EAGER)
29+
@JoinTable(name = "REVCHANGES", joinColumns = @JoinColumn(name = "REV"))
30+
@Column(name = "ENTITYNAME")
31+
@Fetch(FetchMode.JOIN)
32+
@ModifiedEntityNames
33+
private Set<String> modifiedEntityNames = new HashSet<>();
34+
35+
public Set<String> getModifiedEntityNames() {
36+
return modifiedEntityNames;
37+
}
38+
39+
public void setModifiedEntityNames(Set<String> modifiedEntityNames) {
40+
this.modifiedEntityNames = modifiedEntityNames;
41+
}
42+
43+
@Override
44+
public boolean equals(Object o) {
45+
if ( this == o ) {
46+
return true;
47+
}
48+
if ( !(o instanceof TrackingModifiedEntitiesRevisionMapping) ) {
49+
return false;
50+
}
51+
if ( !super.equals( o ) ) {
52+
return false;
53+
}
54+
55+
final TrackingModifiedEntitiesRevisionMapping that = (TrackingModifiedEntitiesRevisionMapping) o;
56+
57+
if ( modifiedEntityNames != null ? !modifiedEntityNames.equals( that.modifiedEntityNames )
58+
: that.modifiedEntityNames != null ) {
59+
return false;
60+
}
61+
62+
return true;
63+
}
64+
65+
@Override
66+
public int hashCode() {
67+
int result = super.hashCode();
68+
result = 31 * result + (modifiedEntityNames != null ? modifiedEntityNames.hashCode() : 0);
69+
return result;
70+
}
71+
72+
@Override
73+
public String toString() {
74+
return "DefaultTrackingModifiedEntitiesRevisionEntity(" + super.toString() + ", modifiedEntityNames = " + modifiedEntityNames + ")";
75+
}
76+
}

hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/RevisionInfoConfiguration.java

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ public Attribute getRevisionInfoRelationMapping() {
166166
true,
167167
false,
168168
true,
169-
revisionInfoEntityName
169+
revisionInfoClass.getName()
170170
);
171171

172172
attribute.setOnDelete( configuration.isCascadeDeleteRevision() ? "cascade" : null );
@@ -190,7 +190,7 @@ private RootPersistentEntity generateDefaultRevisionInfoMapping(String revisionI
190190
RootPersistentEntity mapping = new RootPersistentEntity(
191191
new AuditTableData( null, null, configuration.getDefaultSchemaName(), configuration.getDefaultCatalogName() ),
192192
revisionInfoClass,
193-
revisionInfoEntityName,
193+
useDefaultRevisionInfoMapping ? null : revisionInfoEntityName,
194194
DEFAULT_REVISION_ENTITY_TABLE_NAME
195195
);
196196

@@ -283,7 +283,6 @@ private class RevisionEntityResolver {
283283

284284
public RevisionEntityResolver(InFlightMetadataCollector metadata) {
285285
this.metadata = metadata;
286-
this.revisionInfoEntityName = getDefaultEntityName();
287286
this.revisionInfoIdData = createPropertyData( "id", "field" );
288287
this.revisionInfoTimestampData = createPropertyData( "timestamp", "field" );
289288
this.modifiedEntityNamesData = createPropertyData( "modifiedEntityNames", "field" );
@@ -294,15 +293,6 @@ public RevisionEntityResolver(InFlightMetadataCollector metadata) {
294293
locateRevisionEntityMapping();
295294
}
296295

297-
private String getDefaultEntityName() {
298-
if ( configuration.isNativeIdEnabled() ) {
299-
return DefaultRevisionEntity.class.getName();
300-
}
301-
else {
302-
return SequenceIdRevisionEntity.class.getName();
303-
}
304-
}
305-
306296
private void locateRevisionEntityMapping() {
307297
for ( PersistentClass persistentClass : metadata.getEntityBindings() ) {
308298
// Only process POJO models, not dynamic models
@@ -390,14 +380,16 @@ private void locateRevisionEntityMapping() {
390380
revisionInfoClass = configuration.isNativeIdEnabled()
391381
? DefaultTrackingModifiedEntitiesRevisionEntity.class
392382
: SequenceIdTrackingModifiedEntitiesRevisionEntity.class;
393-
revisionInfoEntityName = revisionInfoClass.getName();
394383
}
395384
else {
396385
revisionInfoClass = configuration.isNativeIdEnabled()
397386
? DefaultRevisionEntity.class
398387
: SequenceIdRevisionEntity.class;
399388
}
400389

390+
// Use the simple name of default revision entities as entity name
391+
revisionInfoEntityName = revisionInfoClass.getSimpleName();
392+
401393
timestampValueResolver = createRevisionTimestampResolver(
402394
revisionInfoClass,
403395
revisionInfoTimestampData,

0 commit comments

Comments
 (0)