From 528129b69a56c1da14efa07b548b35481d972bcd Mon Sep 17 00:00:00 2001 From: Marco Belladelli Date: Mon, 30 Sep 2024 11:36:57 +0200 Subject: [PATCH] HHH-17612 HHH-18762 Add test for issue --- .../RevisionEntitiesMetamodelTest.java | 108 +++++++++++++ .../query/RevisionEntityQueryTest.java | 144 ++++++++++++++++++ 2 files changed, 252 insertions(+) create mode 100644 hibernate-envers/src/test/java/org/hibernate/orm/test/envers/integration/metamodel/RevisionEntitiesMetamodelTest.java create mode 100644 hibernate-envers/src/test/java/org/hibernate/orm/test/envers/integration/query/RevisionEntityQueryTest.java diff --git a/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/integration/metamodel/RevisionEntitiesMetamodelTest.java b/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/integration/metamodel/RevisionEntitiesMetamodelTest.java new file mode 100644 index 0000000000..e10e4a8253 --- /dev/null +++ b/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/integration/metamodel/RevisionEntitiesMetamodelTest.java @@ -0,0 +1,108 @@ +/* + * SPDX-License-Identifier: LGPL-2.1-or-later + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.orm.test.envers.integration.metamodel; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import org.hibernate.annotations.CreationTimestamp; +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.envers.Audited; +import org.hibernate.envers.configuration.EnversSettings; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.metamodel.internal.MetadataContext; +import org.hibernate.testing.logger.LogInspectionHelper; +import org.hibernate.testing.logger.TriggerOnPrefixLogListener; +import org.hibernate.testing.orm.junit.Jira; +import org.hibernate.testing.util.ServiceRegistryUtil; +import org.jboss.logging.Logger; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +import java.lang.invoke.MethodHandles; +import java.time.Instant; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Marco Belladelli + */ +@Jira( "https://hibernate.atlassian.net/browse/HHH-17612" ) +@TestInstance( TestInstance.Lifecycle.PER_CLASS ) +public class RevisionEntitiesMetamodelTest { + private TriggerOnPrefixLogListener trigger; + + @BeforeAll + public void setUp() { + trigger = new TriggerOnPrefixLogListener( "HHH015007: Illegal argument on static metamodel field injection" ); + LogInspectionHelper.registerListener( + trigger, + Logger.getMessageLogger( + MethodHandles.lookup(), + CoreMessageLogger.class, + MetadataContext.class.getName() + ) + ); + } + + @Test + public void testDefaultRevisionEntity() { + try (final SessionFactoryImplementor ignored = buildSessionFactory( false, true )) { + assertThat( trigger.wasTriggered() ).isFalse(); + } + } + + @Test + public void testSequenceIdRevisionEntity() { + try (final SessionFactoryImplementor ignored = buildSessionFactory( false, false )) { + assertThat( trigger.wasTriggered() ).isFalse(); + } + } + + @Test + public void testDefaultTrackingModifiedEntitiesRevisionEntity() { + try (final SessionFactoryImplementor ignored = buildSessionFactory( true, true )) { + assertThat( trigger.wasTriggered() ).isFalse(); + } + } + + @Test + public void testSequenceIdTrackingModifiedEntitiesRevisionEntity() { + try (final SessionFactoryImplementor ignored = buildSessionFactory( true, false )) { + assertThat( trigger.wasTriggered() ).isFalse(); + } + } + + @SuppressWarnings( "resource" ) + private static SessionFactoryImplementor buildSessionFactory(boolean trackEntities, boolean nativeId) { + final StandardServiceRegistryBuilder registryBuilder = ServiceRegistryUtil.serviceRegistryBuilder(); + registryBuilder.applySetting( EnversSettings.TRACK_ENTITIES_CHANGED_IN_REVISION, trackEntities ); + registryBuilder.applySetting( EnversSettings.USE_REVISION_ENTITY_WITH_NATIVE_ID, nativeId ); + return new MetadataSources( registryBuilder.build() ) + .addAnnotatedClasses( Customer.class ) + .buildMetadata() + .buildSessionFactory() + .unwrap( SessionFactoryImplementor.class ); + } + + @Audited + @Entity( name = "Customer" ) + @SuppressWarnings( "unused" ) + public static class Customer { + @Id + private Long id; + + private String firstName; + + private String lastName; + + @Column( name = "created_on" ) + @CreationTimestamp + private Instant createdOn; + } +} diff --git a/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/integration/query/RevisionEntityQueryTest.java b/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/integration/query/RevisionEntityQueryTest.java new file mode 100644 index 0000000000..220edd9c60 --- /dev/null +++ b/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/integration/query/RevisionEntityQueryTest.java @@ -0,0 +1,144 @@ +/* + * SPDX-License-Identifier: LGPL-2.1-or-later + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.orm.test.envers.integration.query; + +import jakarta.persistence.EntityManager; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.Root; +import org.hibernate.envers.enhanced.SequenceIdRevisionEntity; +import org.hibernate.envers.query.AuditEntity; +import org.hibernate.orm.test.envers.BaseEnversJPAFunctionalTestCase; +import org.hibernate.orm.test.envers.Priority; +import org.hibernate.orm.test.envers.entities.StrIntTestEntity; +import org.hibernate.orm.test.envers.entities.ids.EmbId; +import org.hibernate.orm.test.envers.entities.ids.EmbIdTestEntity; +import org.hibernate.orm.test.envers.entities.ids.MulId; +import org.hibernate.orm.test.envers.entities.ids.MulIdTestEntity; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Marco Belladelli + */ +public class RevisionEntityQueryTest extends BaseEnversJPAFunctionalTestCase { + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] {StrIntTestEntity.class, MulIdTestEntity.class, EmbIdTestEntity.class}; + } + + @Test + @Priority(10) + public void initData() { + // Revision 1 + final EntityManager em = getEntityManager(); + em.getTransaction().begin(); + + StrIntTestEntity site1 = new StrIntTestEntity( "a", 10 ); + StrIntTestEntity site2 = new StrIntTestEntity( "a", 10 ); + StrIntTestEntity site3 = new StrIntTestEntity( "b", 5 ); + + em.persist( site1 ); + em.persist( site2 ); + em.persist( site3 ); + + final Integer id1 = site1.getId(); + final Integer id2 = site2.getId(); + final Integer id3 = site3.getId(); + + em.getTransaction().commit(); + + // Revision 2 + em.getTransaction().begin(); + + final MulId mulId1 = new MulId( 1, 2 ); + em.persist( new MulIdTestEntity( mulId1.getId1(), mulId1.getId2(), "data" ) ); + + final EmbId embId1 = new EmbId( 3, 4 ); + em.persist( new EmbIdTestEntity( embId1, "something" ) ); + + site1 = em.find( StrIntTestEntity.class, id1 ); + site2 = em.find( StrIntTestEntity.class, id2 ); + + site1.setStr1( "aBc" ); + site2.setNumber( 20 ); + + em.getTransaction().commit(); + + // Revision 3 + em.getTransaction().begin(); + + site3 = em.find( StrIntTestEntity.class, id3 ); + + site3.setStr1( "a" ); + + em.getTransaction().commit(); + + // Revision 4 + em.getTransaction().begin(); + + site1 = em.find( StrIntTestEntity.class, id1 ); + + em.remove( site1 ); + + em.getTransaction().commit(); + } + + @Test + public void testRevisionEntityHqlQuery() { + final EntityManager em = getEntityManager(); + em.getTransaction().begin(); + + final List resultList = em.createQuery( + "select e from SequenceIdRevisionEntity e", + SequenceIdRevisionEntity.class + ).getResultList(); + + assertThat( resultList ).hasSize( 4 ); + + assertThat( em.createQuery( + String.format( "select e from %s e", SequenceIdRevisionEntity.class.getName() ), + SequenceIdRevisionEntity.class + ).getResultList() ).containsAll( resultList ); + + em.getTransaction().commit(); + } + + @Test + public void testRevisionEntityCriteriaQuery() { + final EntityManager em = getEntityManager(); + em.getTransaction().begin(); + + final CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder(); + final CriteriaQuery query = criteriaBuilder.createQuery( Integer.class ); + final Root from = query.from( SequenceIdRevisionEntity.class ); + final List resultList = em.createQuery( query.select( from.get( "id" ) ) ).getResultList(); + + assertThat( resultList ).hasSize( 4 ).allSatisfy( Assertions::assertNotNull ); + + em.getTransaction().commit(); + } + + @Test + public void testQueryForRevisionsOfEntity() { + final EntityManager em = getEntityManager(); + em.getTransaction().begin(); + + //noinspection unchecked + final List resultList = getAuditReader().createQuery() + .forRevisionsOfEntity( StrIntTestEntity.class, true ) + .add( AuditEntity.id().eq( 1 ) ) + .add( AuditEntity.revisionNumber().between( 1, 3 ) ) + .getResultList(); + + assertThat( resultList ).hasSize( 2 ).allMatch( r -> r instanceof SequenceIdRevisionEntity ); + + em.getTransaction().commit(); + } +}