diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/CollectionMetadataGenerator.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/CollectionMetadataGenerator.java index 4869f1f3c1..fd14cb2a42 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/CollectionMetadataGenerator.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/CollectionMetadataGenerator.java @@ -605,8 +605,7 @@ public final class CollectionMetadataGenerator { final ReflectionManager reflectionManager = mainGenerator.getCfg().getReflectionManager(); new ComponentAuditedPropertiesReader( - true, // TODO: is this correct??? - ModificationStore.FULL, + true, // true because the collection is being audited new AuditedPropertiesReader.ComponentPropertiesSource( reflectionManager, component ), auditData, mainGenerator.getGlobalCfg(), reflectionManager, "" ).read(); diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/AnnotationsMetadataReader.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/AnnotationsMetadataReader.java index b9d00b3066..627ae68bdd 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/AnnotationsMetadataReader.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/AnnotationsMetadataReader.java @@ -65,7 +65,7 @@ public final class AnnotationsMetadataReader { auditData = new ClassAuditingData(); } - private ModificationStore getDefaultAudited(XClass clazz) { + private ModificationStore getDefaultAuditedModStore(XClass clazz) { final Audited defaultAudited = clazz.getAnnotation( Audited.class ); if ( defaultAudited != null ) { @@ -115,14 +115,13 @@ public final class AnnotationsMetadataReader { try { final XClass xclass = reflectionManager.classForName( pc.getClassName(), this.getClass() ); - final ModificationStore defaultStore = getDefaultAudited( xclass ); + final ModificationStore defaultStore = getDefaultAuditedModStore( xclass ); if ( defaultStore != null ) { auditData.setDefaultAudited( true ); } new AuditedPropertiesReader( auditData.isAudited(), - defaultStore, new PersistentClassPropertiesSource( xclass ), auditData, globalCfg, diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/AuditedPropertiesReader.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/AuditedPropertiesReader.java index fee50a62f7..980605641b 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/AuditedPropertiesReader.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/AuditedPropertiesReader.java @@ -73,8 +73,6 @@ import static org.hibernate.envers.internal.tools.Tools.newHashSet; */ public class AuditedPropertiesReader { private final boolean defaultAudited; - // TODO: can defaultStore be made private? - protected final ModificationStore defaultStore; private final PersistentPropertiesSource persistentPropertiesSource; private final AuditedPropertiesHolder auditedPropertiesHolder; private final GlobalConfiguration globalCfg; @@ -94,14 +92,12 @@ public class AuditedPropertiesReader { public AuditedPropertiesReader( boolean defaultAudited, - ModificationStore defaultStore, PersistentPropertiesSource persistentPropertiesSource, AuditedPropertiesHolder auditedPropertiesHolder, GlobalConfiguration globalCfg, ReflectionManager reflectionManager, String propertyNamePrefix) { this.defaultAudited = defaultAudited; - this.defaultStore = defaultStore; this.persistentPropertiesSource = persistentPropertiesSource; this.auditedPropertiesHolder = auditedPropertiesHolder; this.globalCfg = globalCfg; @@ -436,7 +432,7 @@ public class AuditedPropertiesReader { propertyValue ); final AuditedPropertiesReader audPropReader = new AuditedPropertiesReader( - defaultAudited, ModificationStore.FULL, componentPropertiesSource, componentData, globalCfg, + defaultAudited, componentPropertiesSource, componentData, globalCfg, reflectionManager, propertyNamePrefix + MappingTools.createComponentPrefix( embeddedName ) ); audPropReader.read(); @@ -463,7 +459,6 @@ public class AuditedPropertiesReader { final ComponentAuditedPropertiesReader audPropReader = new ComponentAuditedPropertiesReader( isAudited, - ModificationStore.FULL, componentPropertiesSource, componentData, globalCfg, diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/ComponentAuditedPropertiesReader.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/ComponentAuditedPropertiesReader.java index 7e5af671b5..0d945ebf68 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/ComponentAuditedPropertiesReader.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/ComponentAuditedPropertiesReader.java @@ -39,13 +39,12 @@ public class ComponentAuditedPropertiesReader extends AuditedPropertiesReader { public ComponentAuditedPropertiesReader( boolean defaultAudited, - ModificationStore defaultStore, PersistentPropertiesSource persistentPropertiesSource, AuditedPropertiesHolder auditedPropertiesHolder, GlobalConfiguration globalCfg, ReflectionManager reflectionManager, String propertyNamePrefix) { super( - defaultAudited, defaultStore, persistentPropertiesSource, auditedPropertiesHolder, + defaultAudited, persistentPropertiesSource, auditedPropertiesHolder, globalCfg, reflectionManager, propertyNamePrefix ); } diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/collections/mappedsuperclasselement/AbstractCode.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/collections/mappedsuperclasselement/AbstractCode.java new file mode 100644 index 0000000000..0c4c75f836 --- /dev/null +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/collections/mappedsuperclasselement/AbstractCode.java @@ -0,0 +1,88 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2014, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.envers.test.integration.components.collections.mappedsuperclasselement; + +import javax.persistence.Access; +import javax.persistence.AccessType; +import javax.persistence.MappedSuperclass; + +/** + * @author Jakob Braeuchi. + */ + +@MappedSuperclass +@Access(AccessType.PROPERTY) +public abstract class AbstractCode { + /** + * Initial Value + */ + protected static final int UNDEFINED = -1; + + private int code = UNDEFINED; + + protected AbstractCode() { + this( UNDEFINED ); + } + + /** + * Constructor with code + */ + public AbstractCode(int code) { + this.code = code; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = 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; + } + AbstractCode other = (AbstractCode) obj; + if ( code != other.code ) { + return false; + } + return true; + } +} \ No newline at end of file diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/collections/mappedsuperclasselement/Code.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/collections/mappedsuperclasselement/Code.java new file mode 100644 index 0000000000..a2ffbb4023 --- /dev/null +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/collections/mappedsuperclasselement/Code.java @@ -0,0 +1,41 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2014, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.envers.test.integration.components.collections.mappedsuperclasselement; + +import javax.persistence.Embeddable; +import javax.persistence.Transient; + +/** + * @author Jakob Braeuchi. + */ +@Embeddable +public class Code extends AbstractCode { + + public Code() { + } + + public Code(int code) { + super( code ); + } +} \ No newline at end of file diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/collections/mappedsuperclasselement/CollectionOfMappedSuperclassComponentsTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/collections/mappedsuperclasselement/CollectionOfMappedSuperclassComponentsTest.java new file mode 100644 index 0000000000..99f2d71ac0 --- /dev/null +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/collections/mappedsuperclasselement/CollectionOfMappedSuperclassComponentsTest.java @@ -0,0 +1,102 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2014, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.envers.test.integration.components.collections.mappedsuperclasselement; + +import java.util.Arrays; +import java.util.Set; +import javax.persistence.EntityManager; + +import org.junit.Test; + +import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; +import org.hibernate.envers.test.Priority; +import org.hibernate.testing.TestForIssue; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author Gail Badner + */ +@TestForIssue( jiraKey = "HHH-8908" ) +public class CollectionOfMappedSuperclassComponentsTest extends BaseEnversJPAFunctionalTestCase { + private Integer id1; + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] {MappedSuperclassComponentSetTestEntity.class, Code.class}; + } + + @Test + @Priority(10) + public void initData() { + // Revision 1 + EntityManager em = getEntityManager(); + em.getTransaction().begin(); + + MappedSuperclassComponentSetTestEntity cte1 = new MappedSuperclassComponentSetTestEntity(); + + em.persist( cte1 ); + + em.getTransaction().commit(); + + // Revision 2 + em = getEntityManager(); + em.getTransaction().begin(); + + cte1 = em.find( MappedSuperclassComponentSetTestEntity.class, cte1.getId() ); + + cte1.getComps().add( new Code( 1 ) ); + cte1.getCompsNotAudited().add( new Code( 100 ) ); + + em.getTransaction().commit(); + + id1 = cte1.getId(); + } + + @Test + public void testRevisionsCounts() { + assertEquals( + Arrays.asList( 1, 2 ), + getAuditReader().getRevisions( MappedSuperclassComponentSetTestEntity.class, id1 ) + ); + } + + @Test + public void testHistoryOfId1() { + MappedSuperclassComponentSetTestEntity entity = getAuditReader().find( + MappedSuperclassComponentSetTestEntity.class, + id1, + 1 + ); + assertEquals( 0, entity.getComps().size() ); + assertEquals( 0, entity.getCompsNotAudited().size() ); + + entity = getAuditReader().find( MappedSuperclassComponentSetTestEntity.class, id1, 2 ); + Set comps1 = entity.getComps(); + assertEquals( 1, comps1.size() ); + assertTrue( comps1.contains( new Code( 1 ) ) ); + assertEquals( 0, entity.getCompsNotAudited().size() ); + } +} \ No newline at end of file diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/collections/mappedsuperclasselement/MappedSuperclassComponentSetTestEntity.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/collections/mappedsuperclasselement/MappedSuperclassComponentSetTestEntity.java new file mode 100644 index 0000000000..c9df73c737 --- /dev/null +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/collections/mappedsuperclasselement/MappedSuperclassComponentSetTestEntity.java @@ -0,0 +1,123 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2014, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.envers.test.integration.components.collections.mappedsuperclasselement; + +import java.util.HashSet; +import java.util.Set; +import javax.persistence.CollectionTable; +import javax.persistence.ElementCollection; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; + +import org.hibernate.envers.Audited; +import org.hibernate.envers.NotAudited; + +/** + * @author Adam Warski (adam at warski dot org) + */ +@Entity +@Audited +public class MappedSuperclassComponentSetTestEntity { + @Id + @GeneratedValue + private Integer id; + + @ElementCollection + @CollectionTable(name = "MCompTestEntityComps", joinColumns = @JoinColumn(name = "entity_id")) + private Set comps = new HashSet(); + + @NotAudited + @ElementCollection + @CollectionTable(name = "MCompTestEntityCompsNotAudited", joinColumns = @JoinColumn(name = "entity_id")) + private Set compsNotAudited = new HashSet(); + + public MappedSuperclassComponentSetTestEntity() { + } + + public MappedSuperclassComponentSetTestEntity(Integer id) { + this.id = id; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Set getComps() { + return comps; + } + + public void setComps(Set comps) { + this.comps = comps; + } + + public Set getCompsNotAudited() { + return compsNotAudited; + } + + public void setCompsNotAudited(Set comps) { + this.compsNotAudited = compsNotAudited; + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( !(o instanceof MappedSuperclassComponentSetTestEntity ) ) { + return false; + } + + MappedSuperclassComponentSetTestEntity that = (MappedSuperclassComponentSetTestEntity) o; + + if ( comps != null ? !comps.equals( that.comps ) : that.comps != null ) { + return false; + } + if ( id != null ? !id.equals( that.id ) : that.id != null ) { + return false; + } + + return true; + } + + @Override + public int hashCode() { + int result = id != null ? id.hashCode() : 0; + result = 31 * result + (comps != null ? comps.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "ComponentSetTestEntity{" + + "id=" + id + + ", comps=" + comps + + '}'; + } +} \ No newline at end of file diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/mappedsuperclass/MappedSuperclassEmbeddableTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/mappedsuperclass/MappedSuperclassEmbeddableTest.java index efd244c301..08a487751a 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/mappedsuperclass/MappedSuperclassEmbeddableTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/mappedsuperclass/MappedSuperclassEmbeddableTest.java @@ -33,11 +33,15 @@ import org.junit.Test; import org.hibernate.envers.AuditReader; import org.hibernate.envers.AuditReaderFactory; import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; +import org.hibernate.envers.test.Priority; +import org.hibernate.testing.TestForIssue; /** * @author Jakob Braeuchi. */ +@TestForIssue(jiraKey = "HHH-8908") public class MappedSuperclassEmbeddableTest extends BaseEnversJPAFunctionalTestCase { + private long id; @Override protected Class[] getAnnotatedClasses() { @@ -45,37 +49,44 @@ public class MappedSuperclassEmbeddableTest extends BaseEnversJPAFunctionalTestC } @Test - public void testEmbeddableThatExtendsMappedSuperclass() { + @Priority(10) + public void initData() { EntityManager em = getEntityManager(); SimplePerson person = new SimplePerson(); - person.setName("Person 1"); - person.setTestCode(new TestCode(84)); - person.setGenericCode(new Code(42, "TestCodeart")); + person.setName( "Person 1" ); + person.setTestCode( new TestCode( 84 ) ); + person.setGenericCode( new Code( 42, "TestCodeart" ) ); EntityTransaction tx = em.getTransaction(); tx.begin(); - em.persist(person); + em.persist( person ); tx.commit(); em.close(); + id = person.getId(); + } + + @Test + public void testEmbeddableThatExtendsMappedSuperclass() { + // Reload and Compare Revision - em = getEntityManager(); - SimplePerson personLoaded = em.find(SimplePerson.class, person.getId()); + EntityManager em = getEntityManager(); + SimplePerson personLoaded = em.find( SimplePerson.class, id ); AuditReader reader = AuditReaderFactory.get( em ); - List revs = reader.getRevisions(SimplePerson.class, person.getId()); + List revs = reader.getRevisions( SimplePerson.class, id ); Assert.assertEquals( 1, revs.size() ); - SimplePerson personRev1 = reader.find(SimplePerson.class, person.getId(), revs.get(0)); + SimplePerson personRev1 = reader.find( SimplePerson.class, id, revs.get( 0 ) ); - Assert.assertEquals(personLoaded.getName(), personRev1.getName()); + Assert.assertEquals( personLoaded.getName(), personRev1.getName() ); // Generic Code is read from AUD Table - Assert.assertEquals(personLoaded.getGenericCode(), personRev1.getGenericCode()); + Assert.assertEquals( personLoaded.getGenericCode(), personRev1.getGenericCode() ); // Test Code is read from AUD Table - Assert.assertEquals(personLoaded.getTestCode(), personRev1.getTestCode()); + Assert.assertEquals( personLoaded.getTestCode(), personRev1.getTestCode() ); } }