HHH-11595 Introduce `CollectionAuditTable` support
This commit is contained in:
parent
d9fa35c6f1
commit
99c13e5965
|
@ -350,6 +350,9 @@ It may be tedious to add this annotation to every audited entity, so if possible
|
|||
If you have a mapping with secondary tables, audit tables for them will be generated in the same way (by adding the prefix and suffix).
|
||||
If you wish to overwrite this behavior, you can use the `@SecondaryAuditTable` and `@SecondaryAuditTables` annotations.
|
||||
|
||||
If you have a mapping with collection tables, the audit table for them will be generated in the same way (by using the prefix and suffix).
|
||||
If you wish to overwrite this behavior, you can use the `@CollectionAuditTable` annotations.
|
||||
|
||||
If you'd like to override auditing behavior of some fields/properties inherited from `@MappedSuperclass` or in an embedded component,
|
||||
you can apply the `@AuditOverride` annotation on the subtype or usage site of the component.
|
||||
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.envers;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.hibernate.Incubating;
|
||||
|
||||
/**
|
||||
* Allows for the customization of an Envers audit collection table.
|
||||
*
|
||||
* @author Chris Cranford
|
||||
*/
|
||||
@Incubating
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.FIELD, ElementType.METHOD})
|
||||
public @interface CollectionAuditTable {
|
||||
/**
|
||||
* The name of the table
|
||||
*/
|
||||
String name();
|
||||
|
||||
/**
|
||||
* The schema of the table. Defaults to the schema of the mapping.
|
||||
*/
|
||||
String schema() default "";
|
||||
|
||||
/**
|
||||
* The catalog of the table. Defaults to the catalog of the mapping.
|
||||
*/
|
||||
String catalog() default "";
|
||||
}
|
|
@ -80,7 +80,7 @@ public abstract class AbstractMetadataGenerator {
|
|||
|
||||
protected String getSchemaName(String schemaFromAnnotation, Table table) {
|
||||
String schemaName = schemaFromAnnotation;
|
||||
if ( StringTools.isEmpty(schemaName ) ) {
|
||||
if ( StringTools.isEmpty( schemaName ) ) {
|
||||
schemaName = metadataBuildingContext.getConfiguration().getDefaultSchemaName();
|
||||
if ( StringTools.isEmpty( schemaName ) ) {
|
||||
schemaName = table.getSchema();
|
||||
|
@ -91,7 +91,7 @@ public abstract class AbstractMetadataGenerator {
|
|||
|
||||
protected String getCatalogName(String catalogFromAnnotation, Table table) {
|
||||
String catalogName = catalogFromAnnotation;
|
||||
if ( StringTools.isEmpty(catalogName ) ) {
|
||||
if ( StringTools.isEmpty( catalogName ) ) {
|
||||
catalogName = metadataBuildingContext.getConfiguration().getDefaultCatalogName();
|
||||
if ( StringTools.isEmpty( catalogName ) ) {
|
||||
catalogName = table.getCatalog();
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.envers.configuration.internal.metadata;
|
||||
|
||||
import org.hibernate.envers.CollectionAuditTable;
|
||||
import org.hibernate.envers.boot.model.CompositeIdentifier;
|
||||
import org.hibernate.envers.boot.model.RootPersistentEntity;
|
||||
import org.hibernate.envers.boot.spi.EnversMetadataBuildingContext;
|
||||
|
@ -23,7 +24,6 @@ import org.hibernate.envers.internal.tools.StringTools;
|
|||
import org.hibernate.mapping.Collection;
|
||||
import org.hibernate.mapping.OneToMany;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.mapping.Table;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
|
@ -194,17 +194,19 @@ public class MiddleTableCollectionMetadataGenerator extends AbstractCollectionMe
|
|||
);
|
||||
}
|
||||
// Hibernate uses a middle table for mapping this relation, so we get its name directly.
|
||||
CollectionAuditTable collectionAuditTable = context.getPropertyAuditingData().getCollectionAuditTable();
|
||||
if ( collectionAuditTable != null ) {
|
||||
return collectionAuditTable.name();
|
||||
}
|
||||
return collection.getCollectionTable().getName();
|
||||
}
|
||||
|
||||
private RootPersistentEntity createMiddleEntity(CollectionMetadataContext context, String tableName, String entityName) {
|
||||
final AuditJoinTableData joinTable = context.getPropertyAuditingData().getJoinTable();
|
||||
final Table collectionTable = context.getCollection().getCollectionTable();
|
||||
final AuditTableData auditTableData = new AuditTableData(
|
||||
entityName,
|
||||
tableName,
|
||||
getSchemaName( joinTable.getSchema(), collectionTable ),
|
||||
getCatalogName( joinTable.getCatalog(), collectionTable )
|
||||
resolveSchema( context ),
|
||||
resolveCatalog( context )
|
||||
);
|
||||
|
||||
final RootPersistentEntity entity = new RootPersistentEntity( auditTableData, null );
|
||||
|
@ -229,6 +231,25 @@ public class MiddleTableCollectionMetadataGenerator extends AbstractCollectionMe
|
|||
return entity;
|
||||
}
|
||||
|
||||
private String resolveSchema(CollectionMetadataContext context) {
|
||||
final CollectionAuditTable collectionAuditTable = context.getPropertyAuditingData().getCollectionAuditTable();
|
||||
if ( collectionAuditTable != null && !StringTools.isEmpty( collectionAuditTable.schema() ) ) {
|
||||
return collectionAuditTable.schema();
|
||||
}
|
||||
|
||||
final AuditJoinTableData joinTable = context.getPropertyAuditingData().getJoinTable();
|
||||
return getSchemaName( joinTable.getSchema(), context.getCollection().getCollectionTable() );
|
||||
}
|
||||
|
||||
private String resolveCatalog(CollectionMetadataContext context) {
|
||||
final CollectionAuditTable collectionAuditTable = context.getPropertyAuditingData().getCollectionAuditTable();
|
||||
if ( collectionAuditTable != null && !StringTools.isEmpty( collectionAuditTable.catalog() ) ) {
|
||||
return collectionAuditTable.catalog();
|
||||
}
|
||||
final AuditJoinTableData joinTable = context.getPropertyAuditingData().getJoinTable();
|
||||
return getCatalogName( joinTable.getCatalog(), context.getCollection().getCollectionTable() );
|
||||
}
|
||||
|
||||
private boolean isRevisionTypeInId(CollectionMetadataContext context) {
|
||||
return isEmbeddableElementType( context ) || isLobMapElementType( context );
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.hibernate.envers.AuditMappedBy;
|
|||
import org.hibernate.envers.AuditOverride;
|
||||
import org.hibernate.envers.AuditOverrides;
|
||||
import org.hibernate.envers.Audited;
|
||||
import org.hibernate.envers.CollectionAuditTable;
|
||||
import org.hibernate.envers.NotAudited;
|
||||
import org.hibernate.envers.RelationTargetAuditMode;
|
||||
import org.hibernate.envers.RelationTargetNotFoundAction;
|
||||
|
@ -540,6 +541,7 @@ public class AuditedPropertiesReader {
|
|||
propertyData.setAccessType( accessType );
|
||||
|
||||
addPropertyJoinTables( property, propertyData );
|
||||
addPropertyCollectionAuditTable( property, propertyData );
|
||||
addPropertyAuditingOverrides( property, propertyData );
|
||||
if ( !processPropertyAuditingOverrides( property, propertyData ) ) {
|
||||
// not audited due to AuditOverride annotation
|
||||
|
@ -677,6 +679,13 @@ public class AuditedPropertiesReader {
|
|||
}
|
||||
}
|
||||
|
||||
private void addPropertyCollectionAuditTable(XProperty property, PropertyAuditingData propertyAuditingData) {
|
||||
final CollectionAuditTable collectionAuditTableAnn = property.getAnnotation( CollectionAuditTable.class );
|
||||
if ( collectionAuditTableAnn != null ) {
|
||||
propertyAuditingData.setCollectionAuditTable( collectionAuditTableAnn );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the {@link AuditOverride} annotations.
|
||||
*
|
||||
|
|
|
@ -14,6 +14,7 @@ import jakarta.persistence.EnumType;
|
|||
|
||||
import org.hibernate.envers.AuditOverride;
|
||||
import org.hibernate.envers.AuditOverrides;
|
||||
import org.hibernate.envers.CollectionAuditTable;
|
||||
import org.hibernate.envers.RelationTargetAuditMode;
|
||||
import org.hibernate.envers.RelationTargetNotFoundAction;
|
||||
import org.hibernate.envers.internal.entities.PropertyData;
|
||||
|
@ -33,6 +34,7 @@ public class PropertyAuditingData {
|
|||
private String beanName;
|
||||
private String mapKey;
|
||||
private EnumType mapKeyEnumType;
|
||||
private CollectionAuditTable collectionAuditTable;
|
||||
private AuditJoinTableData joinTable;
|
||||
private String accessType;
|
||||
private final List<AuditOverrideData> auditJoinTableOverrides = new ArrayList<>( 0 );
|
||||
|
@ -329,6 +331,14 @@ public class PropertyAuditingData {
|
|||
this.virtualPropertyType = virtualPropertyType;
|
||||
}
|
||||
|
||||
public CollectionAuditTable getCollectionAuditTable() {
|
||||
return collectionAuditTable;
|
||||
}
|
||||
|
||||
public void setCollectionAuditTable(CollectionAuditTable collectionAuditTable) {
|
||||
this.collectionAuditTable = collectionAuditTable;
|
||||
}
|
||||
|
||||
public PropertyData resolvePropertyData() {
|
||||
if ( propertyType != null && virtualPropertyType != null ) {
|
||||
return new PropertyData(
|
||||
|
|
Loading…
Reference in New Issue