HHH-17612 HHH-18762 Separate envers default revision entity types from mapped-superclasses
Also, ensure they're query-able through Criteria and HQL queries
This commit is contained in:
parent
528129b69a
commit
e06da88b42
|
@ -364,6 +364,10 @@ public class ModelBinder {
|
||||||
entityDescriptor.setEntityName( entitySource.getEntityNamingSource().getEntityName() );
|
entityDescriptor.setEntityName( entitySource.getEntityNamingSource().getEntityName() );
|
||||||
entityDescriptor.setJpaEntityName( entitySource.getEntityNamingSource().getJpaEntityName() );
|
entityDescriptor.setJpaEntityName( entitySource.getEntityNamingSource().getJpaEntityName() );
|
||||||
entityDescriptor.setClassName( entitySource.getEntityNamingSource().getClassName() );
|
entityDescriptor.setClassName( entitySource.getEntityNamingSource().getClassName() );
|
||||||
|
if ( entityDescriptor.getJpaEntityName() != null && entityDescriptor.getClassName() != null ) {
|
||||||
|
metadataBuildingContext.getMetadataCollector()
|
||||||
|
.addImport( entityDescriptor.getJpaEntityName(), entityDescriptor.getClassName() );
|
||||||
|
}
|
||||||
|
|
||||||
entityDescriptor.setDiscriminatorValue(
|
entityDescriptor.setDiscriminatorValue(
|
||||||
entitySource.getDiscriminatorMatchValue() != null
|
entitySource.getDiscriminatorMatchValue() != null
|
||||||
|
|
|
@ -4,76 +4,12 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.envers;
|
package org.hibernate.envers;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import jakarta.persistence.Entity;
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import jakarta.persistence.GeneratedValue;
|
|
||||||
import jakarta.persistence.Id;
|
|
||||||
import jakarta.persistence.MappedSuperclass;
|
|
||||||
import jakarta.persistence.Transient;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adam Warski (adam at warski dot org)
|
* @author Adam Warski (adam at warski dot org)
|
||||||
* @author Chris Cranford
|
* @author Chris Cranford
|
||||||
*/
|
*/
|
||||||
@MappedSuperclass
|
@Entity
|
||||||
public class DefaultRevisionEntity implements Serializable {
|
public final class DefaultRevisionEntity extends RevisionMapping {
|
||||||
private static final long serialVersionUID = 8530213963961662300L;
|
|
||||||
|
|
||||||
@Id
|
|
||||||
@GeneratedValue
|
|
||||||
@RevisionNumber
|
|
||||||
private int id;
|
|
||||||
|
|
||||||
@RevisionTimestamp
|
|
||||||
private long timestamp;
|
|
||||||
|
|
||||||
public int getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(int id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transient
|
|
||||||
public Date getRevisionDate() {
|
|
||||||
return new Date( timestamp );
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getTimestamp() {
|
|
||||||
return timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTimestamp(long timestamp) {
|
|
||||||
this.timestamp = timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if ( this == o ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if ( !(o instanceof DefaultRevisionEntity) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final DefaultRevisionEntity that = (DefaultRevisionEntity) o;
|
|
||||||
return id == that.id
|
|
||||||
&& timestamp == that.timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int result;
|
|
||||||
result = id;
|
|
||||||
result = 31 * result + (int) (timestamp ^ (timestamp >>> 32));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "DefaultRevisionEntity(id = " + id
|
|
||||||
+ ", revisionDate = " + DateTimeFormatter.INSTANCE.format(getRevisionDate() ) + ")";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,17 +4,7 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.envers;
|
package org.hibernate.envers;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import jakarta.persistence.Entity;
|
||||||
import java.util.Set;
|
|
||||||
import jakarta.persistence.Column;
|
|
||||||
import jakarta.persistence.ElementCollection;
|
|
||||||
import jakarta.persistence.FetchType;
|
|
||||||
import jakarta.persistence.JoinColumn;
|
|
||||||
import jakarta.persistence.JoinTable;
|
|
||||||
import jakarta.persistence.MappedSuperclass;
|
|
||||||
|
|
||||||
import org.hibernate.annotations.Fetch;
|
|
||||||
import org.hibernate.annotations.FetchMode;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extension of standard {@link DefaultRevisionEntity} that allows tracking entity names changed in each revision.
|
* Extension of standard {@link DefaultRevisionEntity} that allows tracking entity names changed in each revision.
|
||||||
|
@ -23,54 +13,6 @@ import org.hibernate.annotations.FetchMode;
|
||||||
*
|
*
|
||||||
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
||||||
*/
|
*/
|
||||||
@MappedSuperclass
|
@Entity
|
||||||
public class DefaultTrackingModifiedEntitiesRevisionEntity extends DefaultRevisionEntity {
|
public final class DefaultTrackingModifiedEntitiesRevisionEntity extends TrackingModifiedEntitiesRevisionMapping {
|
||||||
@ElementCollection(fetch = FetchType.EAGER)
|
|
||||||
@JoinTable(name = "REVCHANGES", joinColumns = @JoinColumn(name = "REV"))
|
|
||||||
@Column(name = "ENTITYNAME")
|
|
||||||
@Fetch(FetchMode.JOIN)
|
|
||||||
@ModifiedEntityNames
|
|
||||||
private Set<String> modifiedEntityNames = new HashSet<>();
|
|
||||||
|
|
||||||
public Set<String> getModifiedEntityNames() {
|
|
||||||
return modifiedEntityNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setModifiedEntityNames(Set<String> modifiedEntityNames) {
|
|
||||||
this.modifiedEntityNames = modifiedEntityNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if ( this == o ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if ( !(o instanceof DefaultTrackingModifiedEntitiesRevisionEntity) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if ( !super.equals( o ) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final DefaultTrackingModifiedEntitiesRevisionEntity that = (DefaultTrackingModifiedEntitiesRevisionEntity) o;
|
|
||||||
|
|
||||||
if ( modifiedEntityNames != null ? !modifiedEntityNames.equals( that.modifiedEntityNames )
|
|
||||||
: that.modifiedEntityNames != null ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int result = super.hashCode();
|
|
||||||
result = 31 * result + (modifiedEntityNames != null ? modifiedEntityNames.hashCode() : 0);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "DefaultTrackingModifiedEntitiesRevisionEntity(" + super.toString() + ", modifiedEntityNames = " + modifiedEntityNames + ")";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
* Copyright Red Hat Inc. and Hibernate Authors
|
||||||
|
*/
|
||||||
|
package org.hibernate.envers;
|
||||||
|
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.MappedSuperclass;
|
||||||
|
import jakarta.persistence.Transient;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adam Warski (adam at warski dot org)
|
||||||
|
* @author Chris Cranford
|
||||||
|
*/
|
||||||
|
@MappedSuperclass
|
||||||
|
public class RevisionMapping implements Serializable {
|
||||||
|
private static final long serialVersionUID = 8530213963961662300L;
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
@RevisionNumber
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
@RevisionTimestamp
|
||||||
|
private long timestamp;
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
public Date getRevisionDate() {
|
||||||
|
return new Date( timestamp );
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTimestamp() {
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimestamp(long timestamp) {
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if ( this == o ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ( !(o instanceof RevisionMapping) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final RevisionMapping that = (RevisionMapping) o;
|
||||||
|
return id == that.id
|
||||||
|
&& timestamp == that.timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result;
|
||||||
|
result = id;
|
||||||
|
result = 31 * result + (int) (timestamp ^ (timestamp >>> 32));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "DefaultRevisionEntity(id = " + id
|
||||||
|
+ ", revisionDate = " + DateTimeFormatter.INSTANCE.format(getRevisionDate() ) + ")";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
* Copyright Red Hat Inc. and Hibernate Authors
|
||||||
|
*/
|
||||||
|
package org.hibernate.envers;
|
||||||
|
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.ElementCollection;
|
||||||
|
import jakarta.persistence.FetchType;
|
||||||
|
import jakarta.persistence.JoinColumn;
|
||||||
|
import jakarta.persistence.JoinTable;
|
||||||
|
import jakarta.persistence.MappedSuperclass;
|
||||||
|
import org.hibernate.annotations.Fetch;
|
||||||
|
import org.hibernate.annotations.FetchMode;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extension of standard {@link RevisionMapping} that allows tracking entity names changed in each revision.
|
||||||
|
* This revision entity is implicitly used when {@code org.hibernate.envers.track_entities_changed_in_revision}
|
||||||
|
* parameter is set to {@code true}.
|
||||||
|
*
|
||||||
|
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
||||||
|
*/
|
||||||
|
@MappedSuperclass
|
||||||
|
public class TrackingModifiedEntitiesRevisionMapping extends RevisionMapping {
|
||||||
|
@ElementCollection(fetch = FetchType.EAGER)
|
||||||
|
@JoinTable(name = "REVCHANGES", joinColumns = @JoinColumn(name = "REV"))
|
||||||
|
@Column(name = "ENTITYNAME")
|
||||||
|
@Fetch(FetchMode.JOIN)
|
||||||
|
@ModifiedEntityNames
|
||||||
|
private Set<String> modifiedEntityNames = new HashSet<>();
|
||||||
|
|
||||||
|
public Set<String> getModifiedEntityNames() {
|
||||||
|
return modifiedEntityNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModifiedEntityNames(Set<String> modifiedEntityNames) {
|
||||||
|
this.modifiedEntityNames = modifiedEntityNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if ( this == o ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ( !(o instanceof TrackingModifiedEntitiesRevisionMapping) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( !super.equals( o ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final TrackingModifiedEntitiesRevisionMapping that = (TrackingModifiedEntitiesRevisionMapping) o;
|
||||||
|
|
||||||
|
if ( modifiedEntityNames != null ? !modifiedEntityNames.equals( that.modifiedEntityNames )
|
||||||
|
: that.modifiedEntityNames != null ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = super.hashCode();
|
||||||
|
result = 31 * result + (modifiedEntityNames != null ? modifiedEntityNames.hashCode() : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "DefaultTrackingModifiedEntitiesRevisionEntity(" + super.toString() + ", modifiedEntityNames = " + modifiedEntityNames + ")";
|
||||||
|
}
|
||||||
|
}
|
|
@ -166,7 +166,7 @@ public class RevisionInfoConfiguration {
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
revisionInfoEntityName
|
revisionInfoClass.getName()
|
||||||
);
|
);
|
||||||
|
|
||||||
attribute.setOnDelete( configuration.isCascadeDeleteRevision() ? "cascade" : null );
|
attribute.setOnDelete( configuration.isCascadeDeleteRevision() ? "cascade" : null );
|
||||||
|
@ -190,7 +190,7 @@ public class RevisionInfoConfiguration {
|
||||||
RootPersistentEntity mapping = new RootPersistentEntity(
|
RootPersistentEntity mapping = new RootPersistentEntity(
|
||||||
new AuditTableData( null, null, configuration.getDefaultSchemaName(), configuration.getDefaultCatalogName() ),
|
new AuditTableData( null, null, configuration.getDefaultSchemaName(), configuration.getDefaultCatalogName() ),
|
||||||
revisionInfoClass,
|
revisionInfoClass,
|
||||||
revisionInfoEntityName,
|
useDefaultRevisionInfoMapping ? null : revisionInfoEntityName,
|
||||||
DEFAULT_REVISION_ENTITY_TABLE_NAME
|
DEFAULT_REVISION_ENTITY_TABLE_NAME
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -283,7 +283,6 @@ public class RevisionInfoConfiguration {
|
||||||
|
|
||||||
public RevisionEntityResolver(InFlightMetadataCollector metadata) {
|
public RevisionEntityResolver(InFlightMetadataCollector metadata) {
|
||||||
this.metadata = metadata;
|
this.metadata = metadata;
|
||||||
this.revisionInfoEntityName = getDefaultEntityName();
|
|
||||||
this.revisionInfoIdData = createPropertyData( "id", "field" );
|
this.revisionInfoIdData = createPropertyData( "id", "field" );
|
||||||
this.revisionInfoTimestampData = createPropertyData( "timestamp", "field" );
|
this.revisionInfoTimestampData = createPropertyData( "timestamp", "field" );
|
||||||
this.modifiedEntityNamesData = createPropertyData( "modifiedEntityNames", "field" );
|
this.modifiedEntityNamesData = createPropertyData( "modifiedEntityNames", "field" );
|
||||||
|
@ -294,15 +293,6 @@ public class RevisionInfoConfiguration {
|
||||||
locateRevisionEntityMapping();
|
locateRevisionEntityMapping();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getDefaultEntityName() {
|
|
||||||
if ( configuration.isNativeIdEnabled() ) {
|
|
||||||
return DefaultRevisionEntity.class.getName();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return SequenceIdRevisionEntity.class.getName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void locateRevisionEntityMapping() {
|
private void locateRevisionEntityMapping() {
|
||||||
for ( PersistentClass persistentClass : metadata.getEntityBindings() ) {
|
for ( PersistentClass persistentClass : metadata.getEntityBindings() ) {
|
||||||
// Only process POJO models, not dynamic models
|
// Only process POJO models, not dynamic models
|
||||||
|
@ -390,7 +380,6 @@ public class RevisionInfoConfiguration {
|
||||||
revisionInfoClass = configuration.isNativeIdEnabled()
|
revisionInfoClass = configuration.isNativeIdEnabled()
|
||||||
? DefaultTrackingModifiedEntitiesRevisionEntity.class
|
? DefaultTrackingModifiedEntitiesRevisionEntity.class
|
||||||
: SequenceIdTrackingModifiedEntitiesRevisionEntity.class;
|
: SequenceIdTrackingModifiedEntitiesRevisionEntity.class;
|
||||||
revisionInfoEntityName = revisionInfoClass.getName();
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
revisionInfoClass = configuration.isNativeIdEnabled()
|
revisionInfoClass = configuration.isNativeIdEnabled()
|
||||||
|
@ -398,6 +387,9 @@ public class RevisionInfoConfiguration {
|
||||||
: SequenceIdRevisionEntity.class;
|
: SequenceIdRevisionEntity.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use the simple name of default revision entities as entity name
|
||||||
|
revisionInfoEntityName = revisionInfoClass.getSimpleName();
|
||||||
|
|
||||||
timestampValueResolver = createRevisionTimestampResolver(
|
timestampValueResolver = createRevisionTimestampResolver(
|
||||||
revisionInfoClass,
|
revisionInfoClass,
|
||||||
revisionInfoTimestampData,
|
revisionInfoTimestampData,
|
||||||
|
|
|
@ -109,7 +109,7 @@ public abstract class AbstractMetadataGenerator {
|
||||||
entity,
|
entity,
|
||||||
metadataBuildingContext.getConfiguration(),
|
metadataBuildingContext.getConfiguration(),
|
||||||
metadataBuildingContext.getConfiguration().getRevisionTypePropertyType(),
|
metadataBuildingContext.getConfiguration().getRevisionTypePropertyType(),
|
||||||
metadataBuildingContext.getConfiguration().getRevisionInfo().getRevisionInfoEntityName(),
|
metadataBuildingContext.getConfiguration().getRevisionInfo().getRevisionInfoClass().getName(),
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -123,7 +123,7 @@ public abstract class AbstractMetadataGenerator {
|
||||||
entity,
|
entity,
|
||||||
metadataBuildingContext.getConfiguration(),
|
metadataBuildingContext.getConfiguration(),
|
||||||
metadataBuildingContext.getConfiguration().getRevisionTypePropertyType(),
|
metadataBuildingContext.getConfiguration().getRevisionTypePropertyType(),
|
||||||
metadataBuildingContext.getConfiguration().getRevisionInfo().getRevisionInfoEntityName(),
|
metadataBuildingContext.getConfiguration().getRevisionInfo().getRevisionInfoClass().getName(),
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -4,92 +4,13 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.envers.enhanced;
|
package org.hibernate.envers.enhanced;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import jakarta.persistence.Entity;
|
||||||
import java.util.Date;
|
|
||||||
import jakarta.persistence.GeneratedValue;
|
|
||||||
import jakarta.persistence.Id;
|
|
||||||
import jakarta.persistence.MappedSuperclass;
|
|
||||||
import jakarta.persistence.Transient;
|
|
||||||
|
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
|
||||||
import org.hibernate.annotations.Parameter;
|
|
||||||
import org.hibernate.envers.DateTimeFormatter;
|
|
||||||
import org.hibernate.envers.RevisionNumber;
|
|
||||||
import org.hibernate.envers.RevisionTimestamp;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adam Warski (adam at warski dot org)
|
* @author Adam Warski (adam at warski dot org)
|
||||||
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
||||||
* @author Chris Cranford
|
* @author Chris Cranford
|
||||||
*/
|
*/
|
||||||
@MappedSuperclass
|
@Entity
|
||||||
public class SequenceIdRevisionEntity implements Serializable {
|
public final class SequenceIdRevisionEntity extends SequenceIdRevisionMapping {
|
||||||
private static final long serialVersionUID = 4159156677698841902L;
|
|
||||||
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(generator = "RevisionNumberSequenceGenerator")
|
|
||||||
@GenericGenerator(
|
|
||||||
name = "RevisionNumberSequenceGenerator",
|
|
||||||
strategy = "org.hibernate.envers.enhanced.OrderedSequenceGenerator",
|
|
||||||
parameters = {
|
|
||||||
@Parameter(name = "table_name", value = "REVISION_GENERATOR"),
|
|
||||||
@Parameter(name = "sequence_name", value = "REVISION_GENERATOR"),
|
|
||||||
@Parameter(name = "initial_value", value = "1"),
|
|
||||||
@Parameter(name = "increment_size", value = "1")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
@RevisionNumber
|
|
||||||
private int id;
|
|
||||||
|
|
||||||
@RevisionTimestamp
|
|
||||||
private long timestamp;
|
|
||||||
|
|
||||||
public int getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(int id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transient
|
|
||||||
public Date getRevisionDate() {
|
|
||||||
return new Date( timestamp );
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getTimestamp() {
|
|
||||||
return timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public void setTimestamp(long timestamp) {
|
|
||||||
this.timestamp = timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if ( this == o ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if ( !(o instanceof SequenceIdRevisionEntity) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final SequenceIdRevisionEntity that = (SequenceIdRevisionEntity) o;
|
|
||||||
return id == that.id && timestamp == that.timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int result = id;
|
|
||||||
result = 31 * result + (int) (timestamp ^ (timestamp >>> 32));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "SequenceIdRevisionEntity(id = " + id
|
|
||||||
+ ", revisionDate = " + DateTimeFormatter.INSTANCE.format(getRevisionDate() )
|
|
||||||
+ ")";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
* Copyright Red Hat Inc. and Hibernate Authors
|
||||||
|
*/
|
||||||
|
package org.hibernate.envers.enhanced;
|
||||||
|
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.MappedSuperclass;
|
||||||
|
import jakarta.persistence.Transient;
|
||||||
|
import org.hibernate.annotations.GenericGenerator;
|
||||||
|
import org.hibernate.annotations.Parameter;
|
||||||
|
import org.hibernate.envers.DateTimeFormatter;
|
||||||
|
import org.hibernate.envers.RevisionNumber;
|
||||||
|
import org.hibernate.envers.RevisionTimestamp;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adam Warski (adam at warski dot org)
|
||||||
|
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
||||||
|
* @author Chris Cranford
|
||||||
|
*/
|
||||||
|
@MappedSuperclass
|
||||||
|
public class SequenceIdRevisionMapping implements Serializable {
|
||||||
|
private static final long serialVersionUID = 4159156677698841902L;
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(generator = "RevisionNumberSequenceGenerator")
|
||||||
|
@GenericGenerator(
|
||||||
|
name = "RevisionNumberSequenceGenerator",
|
||||||
|
strategy = "org.hibernate.envers.enhanced.OrderedSequenceGenerator",
|
||||||
|
parameters = {
|
||||||
|
@Parameter(name = "table_name", value = "REVISION_GENERATOR"),
|
||||||
|
@Parameter(name = "sequence_name", value = "REVISION_GENERATOR"),
|
||||||
|
@Parameter(name = "initial_value", value = "1"),
|
||||||
|
@Parameter(name = "increment_size", value = "1")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@RevisionNumber
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
@RevisionTimestamp
|
||||||
|
private long timestamp;
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
public Date getRevisionDate() {
|
||||||
|
return new Date( timestamp );
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTimestamp() {
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public void setTimestamp(long timestamp) {
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if ( this == o ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ( !(o instanceof SequenceIdRevisionMapping) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final SequenceIdRevisionMapping that = (SequenceIdRevisionMapping) o;
|
||||||
|
return id == that.id && timestamp == that.timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = id;
|
||||||
|
result = 31 * result + (int) (timestamp ^ (timestamp >>> 32));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "SequenceIdRevisionEntity(id = " + id
|
||||||
|
+ ", revisionDate = " + DateTimeFormatter.INSTANCE.format(getRevisionDate() )
|
||||||
|
+ ")";
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,18 +4,7 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.envers.enhanced;
|
package org.hibernate.envers.enhanced;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import jakarta.persistence.Entity;
|
||||||
import java.util.Set;
|
|
||||||
import jakarta.persistence.Column;
|
|
||||||
import jakarta.persistence.ElementCollection;
|
|
||||||
import jakarta.persistence.FetchType;
|
|
||||||
import jakarta.persistence.JoinColumn;
|
|
||||||
import jakarta.persistence.JoinTable;
|
|
||||||
import jakarta.persistence.MappedSuperclass;
|
|
||||||
|
|
||||||
import org.hibernate.annotations.Fetch;
|
|
||||||
import org.hibernate.annotations.FetchMode;
|
|
||||||
import org.hibernate.envers.ModifiedEntityNames;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extension of standard {@link SequenceIdRevisionEntity} that allows tracking entity names changed in each revision.
|
* Extension of standard {@link SequenceIdRevisionEntity} that allows tracking entity names changed in each revision.
|
||||||
|
@ -24,57 +13,6 @@ import org.hibernate.envers.ModifiedEntityNames;
|
||||||
*
|
*
|
||||||
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
||||||
*/
|
*/
|
||||||
@MappedSuperclass
|
@Entity
|
||||||
public class SequenceIdTrackingModifiedEntitiesRevisionEntity extends SequenceIdRevisionEntity {
|
public final class SequenceIdTrackingModifiedEntitiesRevisionEntity extends SequenceIdTrackingModifiedEntitiesRevisionMapping {
|
||||||
@ElementCollection(fetch = FetchType.EAGER)
|
|
||||||
@JoinTable(name = "REVCHANGES", joinColumns = @JoinColumn(name = "REV"))
|
|
||||||
@Column(name = "ENTITYNAME")
|
|
||||||
@Fetch(FetchMode.JOIN)
|
|
||||||
@ModifiedEntityNames
|
|
||||||
private Set<String> modifiedEntityNames = new HashSet<>();
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public Set<String> getModifiedEntityNames() {
|
|
||||||
return modifiedEntityNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public void setModifiedEntityNames(Set<String> modifiedEntityNames) {
|
|
||||||
this.modifiedEntityNames = modifiedEntityNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if ( this == o ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if ( !(o instanceof SequenceIdTrackingModifiedEntitiesRevisionEntity) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if ( !super.equals( o ) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final SequenceIdTrackingModifiedEntitiesRevisionEntity that = (SequenceIdTrackingModifiedEntitiesRevisionEntity) o;
|
|
||||||
|
|
||||||
if ( modifiedEntityNames == null ) {
|
|
||||||
return that.modifiedEntityNames == null;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return modifiedEntityNames.equals( that.modifiedEntityNames );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int result = super.hashCode();
|
|
||||||
result = 31 * result + (modifiedEntityNames != null ? modifiedEntityNames.hashCode() : 0);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "SequenceIdTrackingModifiedEntitiesRevisionEntity(" + super.toString()
|
|
||||||
+ ", modifiedEntityNames = " + modifiedEntityNames + ")";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
* Copyright Red Hat Inc. and Hibernate Authors
|
||||||
|
*/
|
||||||
|
package org.hibernate.envers.enhanced;
|
||||||
|
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.ElementCollection;
|
||||||
|
import jakarta.persistence.FetchType;
|
||||||
|
import jakarta.persistence.JoinColumn;
|
||||||
|
import jakarta.persistence.JoinTable;
|
||||||
|
import jakarta.persistence.MappedSuperclass;
|
||||||
|
import org.hibernate.annotations.Fetch;
|
||||||
|
import org.hibernate.annotations.FetchMode;
|
||||||
|
import org.hibernate.envers.ModifiedEntityNames;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extension of standard {@link SequenceIdRevisionMapping} that allows tracking entity names changed in each revision.
|
||||||
|
* This revision entity is implicitly used when {@code org.hibernate.envers.track_entities_changed_in_revision}
|
||||||
|
* parameter is set to {@code true}.
|
||||||
|
*
|
||||||
|
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
||||||
|
*/
|
||||||
|
@MappedSuperclass
|
||||||
|
public class SequenceIdTrackingModifiedEntitiesRevisionMapping extends SequenceIdRevisionMapping {
|
||||||
|
@ElementCollection(fetch = FetchType.EAGER)
|
||||||
|
@JoinTable(name = "REVCHANGES", joinColumns = @JoinColumn(name = "REV"))
|
||||||
|
@Column(name = "ENTITYNAME")
|
||||||
|
@Fetch(FetchMode.JOIN)
|
||||||
|
@ModifiedEntityNames
|
||||||
|
private Set<String> modifiedEntityNames = new HashSet<>();
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public Set<String> getModifiedEntityNames() {
|
||||||
|
return modifiedEntityNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public void setModifiedEntityNames(Set<String> modifiedEntityNames) {
|
||||||
|
this.modifiedEntityNames = modifiedEntityNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if ( this == o ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ( !(o instanceof SequenceIdTrackingModifiedEntitiesRevisionMapping) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( !super.equals( o ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final SequenceIdTrackingModifiedEntitiesRevisionMapping that = (SequenceIdTrackingModifiedEntitiesRevisionMapping) o;
|
||||||
|
|
||||||
|
if ( modifiedEntityNames == null ) {
|
||||||
|
return that.modifiedEntityNames == null;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return modifiedEntityNames.equals( that.modifiedEntityNames );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = super.hashCode();
|
||||||
|
result = 31 * result + (modifiedEntityNames != null ? modifiedEntityNames.hashCode() : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "SequenceIdTrackingModifiedEntitiesRevisionEntity(" + super.toString()
|
||||||
|
+ ", modifiedEntityNames = " + modifiedEntityNames + ")";
|
||||||
|
}
|
||||||
|
}
|
|
@ -547,7 +547,7 @@ public class ValidityAuditStrategy implements AuditStrategy {
|
||||||
final EntityPersister rootEntity = getEntityPersister( entity.getRootEntityName(), session );
|
final EntityPersister rootEntity = getEntityPersister( entity.getRootEntityName(), session );
|
||||||
final EntityPersister auditEntity = getEntityPersister( auditEntityName, session );
|
final EntityPersister auditEntity = getEntityPersister( auditEntityName, session );
|
||||||
final EntityPersister rootAuditEntity = getEntityPersister( auditEntity.getRootEntityName(), session );
|
final EntityPersister rootAuditEntity = getEntityPersister( auditEntity.getRootEntityName(), session );
|
||||||
final EntityPersister revisionEntity = getEntityPersister( configuration.getRevisionInfo().getRevisionInfoEntityName(), session );
|
final EntityPersister revisionEntity = getEntityPersister( configuration.getRevisionInfo().getRevisionInfoClass().getName(), session );
|
||||||
|
|
||||||
final Number revisionNumber = getRevisionNumber( configuration, revision );
|
final Number revisionNumber = getRevisionNumber( configuration, revision );
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ import java.util.Date;
|
||||||
|
|
||||||
import org.hibernate.annotations.CreationTimestamp;
|
import org.hibernate.annotations.CreationTimestamp;
|
||||||
import org.hibernate.envers.Audited;
|
import org.hibernate.envers.Audited;
|
||||||
import org.hibernate.envers.DefaultRevisionEntity;
|
import org.hibernate.envers.RevisionMapping;
|
||||||
import org.hibernate.envers.RevisionEntity;
|
import org.hibernate.envers.RevisionEntity;
|
||||||
import org.hibernate.envers.RevisionListener;
|
import org.hibernate.envers.RevisionListener;
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ public class CustomRevisionEntityTest {
|
||||||
@Entity(name = "CustomRevisionEntity")
|
@Entity(name = "CustomRevisionEntity")
|
||||||
@Table(name = "CUSTOM_REV_INFO")
|
@Table(name = "CUSTOM_REV_INFO")
|
||||||
@RevisionEntity(CustomRevisionEntityListener.class)
|
@RevisionEntity(CustomRevisionEntityListener.class)
|
||||||
public static class CustomRevisionEntity extends DefaultRevisionEntity {
|
public static class CustomRevisionEntity extends RevisionMapping {
|
||||||
|
|
||||||
private String username;
|
private String username;
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ import org.hibernate.annotations.CreationTimestamp;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.envers.Audited;
|
import org.hibernate.envers.Audited;
|
||||||
import org.hibernate.envers.DefaultTrackingModifiedEntitiesRevisionEntity;
|
import org.hibernate.envers.TrackingModifiedEntitiesRevisionMapping;
|
||||||
import org.hibernate.envers.RevisionEntity;
|
import org.hibernate.envers.RevisionEntity;
|
||||||
import org.hibernate.jpa.boot.spi.Bootstrap;
|
import org.hibernate.jpa.boot.spi.Bootstrap;
|
||||||
|
|
||||||
|
@ -198,7 +198,7 @@ public class EntityTypeChangeAuditDefaultTrackingTest extends EntityManagerFacto
|
||||||
@Table(name = "TRACKING_REV_INFO")
|
@Table(name = "TRACKING_REV_INFO")
|
||||||
@RevisionEntity
|
@RevisionEntity
|
||||||
public static class CustomTrackingRevisionEntity
|
public static class CustomTrackingRevisionEntity
|
||||||
extends DefaultTrackingModifiedEntitiesRevisionEntity {
|
extends TrackingModifiedEntitiesRevisionMapping {
|
||||||
|
|
||||||
}
|
}
|
||||||
//end::envers-tracking-modified-entities-revchanges-example[]
|
//end::envers-tracking-modified-entities-revchanges-example[]
|
||||||
|
|
|
@ -25,7 +25,7 @@ import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.envers.AuditReaderFactory;
|
import org.hibernate.envers.AuditReaderFactory;
|
||||||
import org.hibernate.envers.Audited;
|
import org.hibernate.envers.Audited;
|
||||||
import org.hibernate.envers.DefaultRevisionEntity;
|
import org.hibernate.envers.RevisionMapping;
|
||||||
import org.hibernate.envers.ModifiedEntityNames;
|
import org.hibernate.envers.ModifiedEntityNames;
|
||||||
import org.hibernate.envers.RevisionEntity;
|
import org.hibernate.envers.RevisionEntity;
|
||||||
import org.hibernate.jpa.boot.spi.Bootstrap;
|
import org.hibernate.jpa.boot.spi.Bootstrap;
|
||||||
|
@ -238,7 +238,7 @@ public class EntityTypeChangeAuditTest extends EntityManagerFactoryBasedFunction
|
||||||
@Entity(name = "CustomTrackingRevisionEntity")
|
@Entity(name = "CustomTrackingRevisionEntity")
|
||||||
@Table(name = "TRACKING_REV_INFO")
|
@Table(name = "TRACKING_REV_INFO")
|
||||||
@RevisionEntity
|
@RevisionEntity
|
||||||
public static class CustomTrackingRevisionEntity extends DefaultRevisionEntity {
|
public static class CustomTrackingRevisionEntity extends RevisionMapping {
|
||||||
|
|
||||||
@ElementCollection
|
@ElementCollection
|
||||||
@JoinTable(
|
@JoinTable(
|
||||||
|
|
|
@ -8,14 +8,14 @@ import jakarta.persistence.Column;
|
||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
|
|
||||||
import org.hibernate.envers.RevisionEntity;
|
import org.hibernate.envers.RevisionEntity;
|
||||||
import org.hibernate.envers.enhanced.SequenceIdTrackingModifiedEntitiesRevisionEntity;
|
import org.hibernate.envers.enhanced.SequenceIdTrackingModifiedEntitiesRevisionMapping;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@RevisionEntity(ExtendedRevisionListener.class)
|
@RevisionEntity(ExtendedRevisionListener.class)
|
||||||
public class ExtendedRevisionEntity extends SequenceIdTrackingModifiedEntitiesRevisionEntity {
|
public class ExtendedRevisionEntity extends SequenceIdTrackingModifiedEntitiesRevisionMapping {
|
||||||
@Column(name = "USER_COMMENT")
|
@Column(name = "USER_COMMENT")
|
||||||
private String comment;
|
private String comment;
|
||||||
|
|
||||||
|
|
|
@ -7,12 +7,12 @@ package org.hibernate.orm.test.envers.integration.reventity;
|
||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
|
|
||||||
import org.hibernate.envers.RevisionEntity;
|
import org.hibernate.envers.RevisionEntity;
|
||||||
import org.hibernate.envers.enhanced.SequenceIdRevisionEntity;
|
import org.hibernate.envers.enhanced.SequenceIdRevisionMapping;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adam Warski (adam at warski dot org)
|
* @author Adam Warski (adam at warski dot org)
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@RevisionEntity
|
@RevisionEntity
|
||||||
public class InheritedRevEntity extends SequenceIdRevisionEntity {
|
public class InheritedRevEntity extends SequenceIdRevisionMapping {
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,8 +34,7 @@ public abstract class AbstractRevisionEntityRemovalTest extends BaseEnversJPAFun
|
||||||
@Override
|
@Override
|
||||||
protected Class<?>[] getAnnotatedClasses() {
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
return new Class<?>[] {
|
return new Class<?>[] {
|
||||||
StrTestEntity.class, ListOwnedEntity.class, ListOwningEntity.class,
|
StrTestEntity.class, ListOwnedEntity.class, ListOwningEntity.class
|
||||||
getRevisionEntityClass()
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue