HHH-9043
Added the ability to customize the modified field name for audited fields.
This commit is contained in:
parent
3cc8cb3113
commit
6f6b3264f3
|
@ -73,4 +73,10 @@ public @interface Audited {
|
|||
* This can be used for example in queries.
|
||||
*/
|
||||
boolean withModifiedFlag() default false;
|
||||
|
||||
/**
|
||||
* The column name of the modified field. Analogous to the name attribute of the @{@link javax.persistence.Column}
|
||||
* annotation. Ignored if withModifiedFlag is false.
|
||||
*/
|
||||
String modifiedColumnName() default "";
|
||||
}
|
||||
|
|
|
@ -141,7 +141,7 @@ public final class AuditMetadataGenerator {
|
|||
revMapping.addAttribute( "name", verEntCfg.getRevisionFieldName() );
|
||||
if ( globalCfg.isCascadeDeleteRevision() ) {
|
||||
revMapping.addAttribute( "on-delete", "cascade" );
|
||||
}
|
||||
}
|
||||
|
||||
MetadataTools.addOrModifyColumn( revMapping, verEntCfg.getRevisionFieldName() );
|
||||
|
||||
|
@ -325,7 +325,8 @@ public final class AuditMetadataGenerator {
|
|||
MetadataTools.addModifiedFlagProperty(
|
||||
parent,
|
||||
propertyAuditingData.getName(),
|
||||
globalCfg.getModifiedFlagSuffix()
|
||||
globalCfg.getModifiedFlagSuffix(),
|
||||
propertyAuditingData.getModifiedFlagName()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -101,10 +101,10 @@ public final class MetadataTools {
|
|||
return addProperty( parent, name, type, insertable, false, key );
|
||||
}
|
||||
|
||||
public static Element addModifiedFlagProperty(Element parent, String propertyName, String suffix) {
|
||||
public static Element addModifiedFlagProperty(Element parent, String propertyName, String suffix, String modifiedFlagName) {
|
||||
return addProperty(
|
||||
parent,
|
||||
getModifiedFlagPropertyName( propertyName, suffix ),
|
||||
(modifiedFlagName != null) ? modifiedFlagName : getModifiedFlagPropertyName( propertyName, suffix ),
|
||||
"boolean",
|
||||
true,
|
||||
false,
|
||||
|
|
|
@ -518,19 +518,12 @@ public class AuditedPropertiesReader {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if ( !this.checkAudited( property, propertyData, allClassAudited ) ) {
|
||||
final String propertyName = propertyNamePrefix + property.getName();
|
||||
if ( !this.checkAudited( property, propertyData,propertyName, allClassAudited, globalCfg.getModifiedFlagSuffix() ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final String propertyName = propertyNamePrefix + property.getName();
|
||||
propertyData.setName( propertyName );
|
||||
propertyData.setModifiedFlagName(
|
||||
MetadataTools.getModifiedFlagPropertyName(
|
||||
propertyName,
|
||||
globalCfg.getModifiedFlagSuffix()
|
||||
)
|
||||
);
|
||||
propertyData.setBeanName( property.getName() );
|
||||
propertyData.setAccessType( accessType );
|
||||
|
||||
|
@ -550,7 +543,8 @@ public class AuditedPropertiesReader {
|
|||
|
||||
protected boolean checkAudited(
|
||||
XProperty property,
|
||||
PropertyAuditingData propertyData, Audited allClassAudited) {
|
||||
PropertyAuditingData propertyData, String propertyName,
|
||||
Audited allClassAudited, String modifiedFlagSuffix) {
|
||||
// Checking if this property is explicitly audited or if all properties are.
|
||||
Audited aud = ( property.isAnnotationPresent( Audited.class ) )
|
||||
? property.getAnnotation( Audited.class )
|
||||
|
@ -566,6 +560,13 @@ public class AuditedPropertiesReader {
|
|||
propertyData.setStore( aud.modStore() );
|
||||
propertyData.setRelationTargetAuditMode( aud.targetAuditMode() );
|
||||
propertyData.setUsingModifiedFlag( checkUsingModifiedFlag( aud ) );
|
||||
if(aud.modifiedColumnName() != null && !"".equals(aud.modifiedColumnName())) {
|
||||
propertyData.setModifiedFlagName(aud.modifiedColumnName());
|
||||
} else {
|
||||
propertyData.setModifiedFlagName(
|
||||
MetadataTools.getModifiedFlagPropertyName(propertyName, modifiedFlagSuffix)
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
|
@ -682,6 +683,11 @@ public class AuditedPropertiesReader {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String modifiedColumnName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Annotation> annotationType() {
|
||||
return this.getClass();
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.hibernate.annotations.common.reflection.XProperty;
|
|||
import org.hibernate.envers.Audited;
|
||||
import org.hibernate.envers.ModificationStore;
|
||||
import org.hibernate.envers.configuration.internal.GlobalConfiguration;
|
||||
import org.hibernate.envers.configuration.internal.metadata.MetadataTools;
|
||||
|
||||
/**
|
||||
* Reads the audited properties for components.
|
||||
|
@ -52,14 +53,21 @@ public class ComponentAuditedPropertiesReader extends AuditedPropertiesReader {
|
|||
@Override
|
||||
protected boolean checkAudited(
|
||||
XProperty property,
|
||||
PropertyAuditingData propertyData,
|
||||
Audited allClassAudited) {
|
||||
PropertyAuditingData propertyData, String propertyName,
|
||||
Audited allClassAudited, String modifiedFlagSuffix) {
|
||||
// Checking if this property is explicitly audited or if all properties are.
|
||||
final Audited aud = property.getAnnotation( Audited.class );
|
||||
if ( aud != null ) {
|
||||
propertyData.setStore( aud.modStore() );
|
||||
propertyData.setRelationTargetAuditMode( aud.targetAuditMode() );
|
||||
propertyData.setUsingModifiedFlag( checkUsingModifiedFlag( aud ) );
|
||||
if(aud.modifiedColumnName() != null && !"".equals(aud.modifiedColumnName())) {
|
||||
propertyData.setModifiedFlagName(aud.modifiedColumnName());
|
||||
} else {
|
||||
propertyData.setModifiedFlagName(
|
||||
MetadataTools.getModifiedFlagPropertyName( propertyName, modifiedFlagSuffix )
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
propertyData.setStore( ModificationStore.FULL );
|
||||
|
|
|
@ -170,6 +170,10 @@ public class PropertyAuditingData {
|
|||
this.usingModifiedFlag = usingModifiedFlag;
|
||||
}
|
||||
|
||||
public String getModifiedFlagName() {
|
||||
return modifiedFlagName;
|
||||
}
|
||||
|
||||
public void setModifiedFlagName(String modifiedFlagName) {
|
||||
this.modifiedFlagName = modifiedFlagName;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
package org.hibernate.envers.test.integration.naming;
|
||||
|
||||
import java.util.List;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Query;
|
||||
import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase;
|
||||
import org.hibernate.envers.test.Priority;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class AuditColumnNameTest extends BaseEnversJPAFunctionalTestCase {
|
||||
private Integer id;
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class[] {NamingTestEntity2.class};
|
||||
}
|
||||
|
||||
@Test
|
||||
@Priority(10)
|
||||
public void initData() {
|
||||
NamingTestEntity2 nte1 = new NamingTestEntity2("data1" );
|
||||
EntityManager em = getEntityManager();
|
||||
em.getTransaction().begin();
|
||||
em.persist( nte1 );
|
||||
em.getTransaction().commit();
|
||||
this.id = nte1.getId();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testColumnName() {
|
||||
EntityManager em = getEntityManager();
|
||||
em.getTransaction().begin();
|
||||
Query query = em.createNativeQuery(
|
||||
"select nte_data, data_MOD_different from naming_test_entity_2_versions where nte_id = :nteId");
|
||||
query.setParameter("nteId", this.id);
|
||||
List<Object[]> resultList = query.getResultList();
|
||||
Assert.assertNotNull(resultList);
|
||||
Assert.assertTrue(resultList.size() > 0);
|
||||
Object[] result = resultList.get(0);
|
||||
Assert.assertEquals(result.length, 2);
|
||||
em.getTransaction().commit();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
package org.hibernate.envers.test.integration.naming;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import org.hibernate.envers.AuditTable;
|
||||
import org.hibernate.envers.Audited;
|
||||
|
||||
@Entity
|
||||
@Table(name = "naming_test_entity_2")
|
||||
@AuditTable("naming_test_entity_2_versions")
|
||||
public class NamingTestEntity2 {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
@Column(name = "nte_id")
|
||||
@Audited(withModifiedFlag = true)
|
||||
private Integer id;
|
||||
|
||||
@Column(name = "nte_data")
|
||||
@Audited(withModifiedFlag = true, modifiedColumnName = "data_MOD_different")
|
||||
private String data;
|
||||
|
||||
public NamingTestEntity2() {
|
||||
}
|
||||
|
||||
public NamingTestEntity2(String data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public NamingTestEntity2(Integer id, String data) {
|
||||
this.id = id;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(String data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if ( this == o ) {
|
||||
return true;
|
||||
}
|
||||
if ( !(o instanceof NamingTestEntity2) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NamingTestEntity2 that = (NamingTestEntity2) o;
|
||||
|
||||
if ( data != null ? !data.equals( that.data ) : that.data != null ) {
|
||||
return false;
|
||||
}
|
||||
if ( id != null ? !id.equals( that.id ) : that.id != null ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int result;
|
||||
result = (id != null ? id.hashCode() : 0);
|
||||
result = 31 * result + (data != null ? data.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue