HHH-17189 Respect Audited annotations in component mapped super types
This commit is contained in:
parent
1cc7def6f9
commit
586cafa4a1
|
@ -114,6 +114,11 @@ public class ComponentAuditedPropertiesReader extends AuditedPropertiesReader {
|
|||
return true;
|
||||
}
|
||||
|
||||
// make sure that if a component is annotated with audited, it is honored.
|
||||
if ( allClassAudited != null ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// assumption here is if a component reader is looking at a @MappedSuperclass, it should be treated
|
||||
// as not being audited if we have reached htis point; allowing components and any @Embeddable
|
||||
// class being audited by default.
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* 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.orm.test.envers.integration.components.mappedsuperclass;
|
||||
|
||||
import jakarta.persistence.Access;
|
||||
import jakarta.persistence.AccessType;
|
||||
import jakarta.persistence.MappedSuperclass;
|
||||
|
||||
import org.hibernate.envers.Audited;
|
||||
|
||||
/**
|
||||
* @author Chris Cranford
|
||||
*/
|
||||
@MappedSuperclass
|
||||
@Access(AccessType.FIELD)
|
||||
@Audited
|
||||
public abstract class AbstractAuditedEmbeddable {
|
||||
|
||||
/**
|
||||
* Initial Value
|
||||
*/
|
||||
protected static final int UNDEFINED = -1;
|
||||
|
||||
private int code = UNDEFINED;
|
||||
|
||||
|
||||
protected AbstractAuditedEmbeddable() {
|
||||
this( UNDEFINED );
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with code
|
||||
*/
|
||||
public AbstractAuditedEmbeddable(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + code;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if ( this == obj ) {
|
||||
return true;
|
||||
}
|
||||
if ( obj == null ) {
|
||||
return false;
|
||||
}
|
||||
if ( getClass() != obj.getClass() ) {
|
||||
return false;
|
||||
}
|
||||
AbstractAuditedEmbeddable other = (AbstractAuditedEmbeddable) obj;
|
||||
if ( code != other.code ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* 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.orm.test.envers.integration.components.mappedsuperclass;
|
||||
|
||||
import jakarta.persistence.Embeddable;
|
||||
|
||||
import org.hibernate.envers.Audited;
|
||||
|
||||
/**
|
||||
* @author Chris Cranford
|
||||
*/
|
||||
@Embeddable
|
||||
@Audited
|
||||
public class AuditedEmbeddableWithDeclaredData extends AbstractAuditedEmbeddable {
|
||||
|
||||
private String codeArt;
|
||||
|
||||
public AuditedEmbeddableWithDeclaredData(int code, String codeArt) {
|
||||
super( code );
|
||||
this.codeArt = codeArt;
|
||||
}
|
||||
|
||||
// Needed for @Embeddable
|
||||
protected AuditedEmbeddableWithDeclaredData() {
|
||||
this( UNDEFINED, null );
|
||||
}
|
||||
|
||||
public String getCodeart() {
|
||||
return codeArt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ( ( codeArt == null ) ? 0 : codeArt.hashCode() );
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if ( this == obj ) {
|
||||
return true;
|
||||
}
|
||||
if ( !super.equals( obj ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( getClass() != obj.getClass() ) {
|
||||
return false;
|
||||
}
|
||||
AuditedEmbeddableWithDeclaredData other = (AuditedEmbeddableWithDeclaredData) obj;
|
||||
if ( codeArt == null ) {
|
||||
if ( other.codeArt != null ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if ( !codeArt.equals( other.codeArt ) ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* 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.orm.test.envers.integration.components.mappedsuperclass;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.envers.AuditReader;
|
||||
import org.hibernate.envers.AuditReaderFactory;
|
||||
import org.hibernate.orm.test.envers.BaseEnversJPAFunctionalTestCase;
|
||||
import org.hibernate.orm.test.envers.Priority;
|
||||
|
||||
import org.hibernate.testing.orm.junit.JiraKey;
|
||||
import org.hibernate.testing.transaction.TransactionUtil;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Chris Cranford
|
||||
*/
|
||||
@JiraKey("HHH-17189")
|
||||
public class AuditedEmbeddableWithDeclaredDataTest extends BaseEnversJPAFunctionalTestCase {
|
||||
|
||||
private long id;
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class[] {
|
||||
EntityWithAuditedEmbeddableWithDeclaredData.class,
|
||||
AbstractAuditedEmbeddable.class,
|
||||
AuditedEmbeddableWithDeclaredData.class
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
@Priority(10)
|
||||
public void initData() {
|
||||
this.id = TransactionUtil.doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
final EntityWithAuditedEmbeddableWithDeclaredData entity = new EntityWithAuditedEmbeddableWithDeclaredData();
|
||||
entity.setName( "Entity 1" );
|
||||
entity.setValue( new AuditedEmbeddableWithDeclaredData( 42, "Data" ) );
|
||||
|
||||
entityManager.persist(entity);
|
||||
return entity.getId();
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmbeddableThatExtendsAuditedMappedSuperclass() {
|
||||
TransactionUtil.doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
final EntityWithAuditedEmbeddableWithDeclaredData entity = entityManager.find(
|
||||
EntityWithAuditedEmbeddableWithDeclaredData.class,
|
||||
id
|
||||
);
|
||||
|
||||
final AuditReader auditReader = AuditReaderFactory.get( entityManager );
|
||||
|
||||
final List<Number> revisions = auditReader.getRevisions( EntityWithAuditedEmbeddableWithDeclaredData.class, id );
|
||||
assertThat( revisions ).hasSize( 1 );
|
||||
|
||||
final EntityWithAuditedEmbeddableWithDeclaredData entityRevision1 = auditReader.find(
|
||||
EntityWithAuditedEmbeddableWithDeclaredData.class,
|
||||
id,
|
||||
revisions.get( 0 )
|
||||
);
|
||||
assertThat( entityRevision1.getName() ).isEqualTo( entity.getName() );
|
||||
|
||||
// All fields should be audited because the mapped superclass is annotated
|
||||
assertThat( entity.getValue().getCodeart() ).isEqualTo( entityRevision1.getValue().getCodeart() );
|
||||
assertThat( entityRevision1.getValue().getCode() ).isEqualTo( 42 );
|
||||
} );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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.orm.test.envers.integration.components.mappedsuperclass;
|
||||
|
||||
import jakarta.persistence.Embeddable;
|
||||
|
||||
import org.hibernate.envers.Audited;
|
||||
|
||||
/**
|
||||
* @author Chris Cranford
|
||||
*/
|
||||
@Embeddable
|
||||
@Audited
|
||||
public class AuditedEmbeddableWithNoDeclaredData extends AbstractAuditedEmbeddable {
|
||||
|
||||
public AuditedEmbeddableWithNoDeclaredData(int code) {
|
||||
super( code );
|
||||
}
|
||||
|
||||
// Needed for @Embeddable
|
||||
protected AuditedEmbeddableWithNoDeclaredData() {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* 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.orm.test.envers.integration.components.mappedsuperclass;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.envers.AuditReader;
|
||||
import org.hibernate.envers.AuditReaderFactory;
|
||||
import org.hibernate.orm.test.envers.BaseEnversJPAFunctionalTestCase;
|
||||
import org.hibernate.orm.test.envers.Priority;
|
||||
|
||||
import org.hibernate.testing.orm.junit.JiraKey;
|
||||
import org.hibernate.testing.transaction.TransactionUtil;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Chris Cranford
|
||||
*/
|
||||
@JiraKey("HHH-17189")
|
||||
public class AuditedEmbeddableWithNoDeclaredDataTest extends BaseEnversJPAFunctionalTestCase {
|
||||
|
||||
private long id;
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class[] {
|
||||
EntityWithAuditedEmbeddableWithNoDeclaredData.class,
|
||||
AbstractAuditedEmbeddable.class,
|
||||
AuditedEmbeddableWithDeclaredData.class
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
@Priority(10)
|
||||
public void initData() {
|
||||
this.id = TransactionUtil.doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
final EntityWithAuditedEmbeddableWithNoDeclaredData entity = new EntityWithAuditedEmbeddableWithNoDeclaredData();
|
||||
entity.setName( "Entity 1" );
|
||||
entity.setValue( new AuditedEmbeddableWithNoDeclaredData( 42 ) );
|
||||
|
||||
entityManager.persist(entity);
|
||||
return entity.getId();
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmbeddableThatExtendsAuditedMappedSuperclass() {
|
||||
TransactionUtil.doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
final EntityWithAuditedEmbeddableWithNoDeclaredData entity = entityManager.find(
|
||||
EntityWithAuditedEmbeddableWithNoDeclaredData.class,
|
||||
id
|
||||
);
|
||||
|
||||
final AuditReader auditReader = AuditReaderFactory.get( entityManager );
|
||||
|
||||
final List<Number> revisions = auditReader.getRevisions( EntityWithAuditedEmbeddableWithNoDeclaredData.class, id );
|
||||
assertThat( revisions ).hasSize( 1 );
|
||||
|
||||
final EntityWithAuditedEmbeddableWithNoDeclaredData entityRevision1 = auditReader.find(
|
||||
EntityWithAuditedEmbeddableWithNoDeclaredData.class,
|
||||
id,
|
||||
revisions.get( 0 )
|
||||
);
|
||||
assertThat( entityRevision1.getName() ).isEqualTo( entity.getName() );
|
||||
|
||||
// All fields should be audited because the mapped superclass is annotated
|
||||
assertThat( entityRevision1.getValue().getCode() ).isEqualTo( 42 );
|
||||
} );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* 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.orm.test.envers.integration.components.mappedsuperclass;
|
||||
|
||||
import jakarta.persistence.Access;
|
||||
import jakarta.persistence.AccessType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Embedded;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import org.hibernate.envers.Audited;
|
||||
|
||||
/**
|
||||
* @author Chris Cranford
|
||||
*/
|
||||
@Entity
|
||||
@Table(name="EntEmbWAuditedDeclData")
|
||||
@Access(AccessType.FIELD)
|
||||
@Audited
|
||||
public class EntityWithAuditedEmbeddableWithDeclaredData {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private long id;
|
||||
|
||||
@Column(name = "NAME", length = 100)
|
||||
private String name;
|
||||
|
||||
@Embedded
|
||||
private AuditedEmbeddableWithDeclaredData value;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public AuditedEmbeddableWithDeclaredData getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(AuditedEmbeddableWithDeclaredData value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (int) ( id ^ ( id >>> 32 ) );
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if ( this == obj ) {
|
||||
return true;
|
||||
}
|
||||
if ( obj == null ) {
|
||||
return false;
|
||||
}
|
||||
if ( getClass() != obj.getClass() ) {
|
||||
return false;
|
||||
}
|
||||
EntityWithAuditedEmbeddableWithDeclaredData other = (EntityWithAuditedEmbeddableWithDeclaredData) obj;
|
||||
if ( id != other.id ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* 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.orm.test.envers.integration.components.mappedsuperclass;
|
||||
|
||||
import jakarta.persistence.Access;
|
||||
import jakarta.persistence.AccessType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Embedded;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import org.hibernate.envers.Audited;
|
||||
|
||||
/**
|
||||
* @author Chris Cranford
|
||||
*/
|
||||
@Entity
|
||||
@Table(name="EntEmbWAuditedNoDeclData")
|
||||
@Access(AccessType.FIELD)
|
||||
@Audited
|
||||
public class EntityWithAuditedEmbeddableWithNoDeclaredData {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private long id;
|
||||
|
||||
@Column(name = "NAME", length = 100)
|
||||
private String name;
|
||||
|
||||
@Embedded
|
||||
private AuditedEmbeddableWithNoDeclaredData value;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public AuditedEmbeddableWithNoDeclaredData getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(AuditedEmbeddableWithNoDeclaredData value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (int) ( id ^ ( id >>> 32 ) );
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if ( this == obj ) {
|
||||
return true;
|
||||
}
|
||||
if ( obj == null ) {
|
||||
return false;
|
||||
}
|
||||
if ( getClass() != obj.getClass() ) {
|
||||
return false;
|
||||
}
|
||||
EntityWithAuditedEmbeddableWithNoDeclaredData other = (EntityWithAuditedEmbeddableWithNoDeclaredData) obj;
|
||||
if ( id != other.id ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue