From 47bdd016a1077975f5e305ab2d740deb526d4bda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoann=20Rodi=C3=A8re?= Date: Wed, 12 Apr 2023 11:34:49 +0200 Subject: [PATCH] HHH-16459 Test bytecode-enhanced inline dirty tracking for generic associations from mapped superclasses --- .../dirty/DirtyTrackingInheritanceTest.java | 84 +++++++++++++ ...tyTrackingInheritanceWithGenericsTest.java | 114 ++++++++++++++++++ .../enhancement/EnhancerTestUtils.java | 18 ++- 3 files changed, 206 insertions(+), 10 deletions(-) create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/dirty/DirtyTrackingInheritanceTest.java create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/dirty/DirtyTrackingInheritanceWithGenericsTest.java diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/dirty/DirtyTrackingInheritanceTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/dirty/DirtyTrackingInheritanceTest.java new file mode 100644 index 0000000000..c0345d001f --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/dirty/DirtyTrackingInheritanceTest.java @@ -0,0 +1,84 @@ +/* + * 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.bytecode.enhancement.dirty; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner; +import org.hibernate.testing.bytecode.enhancement.EnhancementOptions; +import org.hibernate.testing.bytecode.enhancement.EnhancerTestUtils; +import org.hibernate.testing.orm.junit.Jira; +import org.junit.Test; +import org.junit.runner.RunWith; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.MappedSuperclass; + +/** + * @author Yoann Rodière + * @author Marco Belladelli + */ +@RunWith( BytecodeEnhancerRunner.class ) +@EnhancementOptions( inlineDirtyChecking = true ) +@Jira( "https://hibernate.atlassian.net/browse/HHH-16459" ) +public class DirtyTrackingInheritanceTest { + @Test + public void test() { + final ChildItem entity = new ChildItem(); + EnhancerTestUtils.checkDirtyTracking( entity ); + entity.setBasicValue( "basic_value" ); + entity.setAssociation( new Other() ); + EnhancerTestUtils.checkDirtyTracking( entity, "basicValue", "association" ); + } + + @Entity( name = "Other" ) + public static class Other { + @Id + @GeneratedValue + private Long id; + } + + @MappedSuperclass + public static abstract class Item { + private String basicValue; + @ManyToOne + private Other association; + + public String getBasicValue() { + return basicValue; + } + + public void setBasicValue(String basicValue) { + this.basicValue = basicValue; + } + + public Other getAssociation() { + return association; + } + + public void setAssociation(Other association) { + this.association = association; + } + } + + @Entity( name = "ChildItem" ) + public static class ChildItem extends Item { + @Id + @GeneratedValue + private Long id; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/dirty/DirtyTrackingInheritanceWithGenericsTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/dirty/DirtyTrackingInheritanceWithGenericsTest.java new file mode 100644 index 0000000000..be2824478e --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/dirty/DirtyTrackingInheritanceWithGenericsTest.java @@ -0,0 +1,114 @@ +/* + * 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.bytecode.enhancement.dirty; + +import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner; +import org.hibernate.testing.bytecode.enhancement.EnhancementOptions; +import org.hibernate.testing.bytecode.enhancement.EnhancerTestUtils; +import org.hibernate.testing.orm.junit.Jira; +import org.junit.Test; +import org.junit.runner.RunWith; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.MappedSuperclass; + +/** + * @author Yoann Rodière + * @author Marco Belladelli + */ +@RunWith( BytecodeEnhancerRunner.class ) +@EnhancementOptions( inlineDirtyChecking = true ) +@Jira( "https://hibernate.atlassian.net/browse/HHH-16459" ) +public class DirtyTrackingInheritanceWithGenericsTest { + @Test + public void testOne() { + final ChildItemOne entity = new ChildItemOne(); + EnhancerTestUtils.checkDirtyTracking( entity ); + entity.setBasicValue( "basic_value" ); + entity.setAssociation( new OtherOne() ); + EnhancerTestUtils.checkDirtyTracking( entity, "basicValue", "association" ); + } + + @Test + public void testTwo() { + final ChildItemTwo entity = new ChildItemTwo(); + EnhancerTestUtils.checkDirtyTracking( entity ); + entity.setBasicValue( 123 ); + entity.setAssociation( new OtherTwo() ); + EnhancerTestUtils.checkDirtyTracking( entity, "basicValue", "association" ); + } + + @Entity( name = "OtherOne" ) + public static class OtherOne { + @Id + @GeneratedValue + private Long id; + } + + @Entity( name = "OtherTwo" ) + public static class OtherTwo { + @Id + @GeneratedValue + private Long id; + } + + @MappedSuperclass + public static abstract class Item { + private T basicValue; + @ManyToOne + private S association; + + public T getBasicValue() { + return basicValue; + } + + public void setBasicValue(T basicValue) { + this.basicValue = basicValue; + } + + public S getAssociation() { + return association; + } + + public void setAssociation(S association) { + this.association = association; + } + } + + @Entity( name = "ChildItemOne" ) + public static class ChildItemOne extends Item { + @Id + @GeneratedValue + private Long id; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + } + + @Entity( name = "ChildItemTwo" ) + public static class ChildItemTwo extends Item { + @Id + @GeneratedValue + private Long id; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + } +} diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/bytecode/enhancement/EnhancerTestUtils.java b/hibernate-testing/src/main/java/org/hibernate/testing/bytecode/enhancement/EnhancerTestUtils.java index 77174c36b8..0e250319d0 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/bytecode/enhancement/EnhancerTestUtils.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/bytecode/enhancement/EnhancerTestUtils.java @@ -6,6 +6,8 @@ */ package org.hibernate.testing.bytecode.enhancement; +import java.lang.reflect.Field; + import org.hibernate.LockMode; import org.hibernate.engine.internal.MutableEntityEntryFactory; import org.hibernate.engine.spi.EntityEntry; @@ -15,11 +17,7 @@ import org.hibernate.internal.util.ReflectHelper; import org.hibernate.testing.junit4.BaseUnitTestCase; -import java.lang.reflect.Field; -import java.util.Arrays; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; /** @@ -53,11 +51,11 @@ public abstract class EnhancerTestUtils extends BaseUnitTestCase { * compares the dirty fields of an entity with a set of expected values */ public static void checkDirtyTracking(Object entityInstance, String... dirtyFields) { - SelfDirtinessTracker selfDirtinessTracker = (SelfDirtinessTracker) entityInstance; - assertEquals( dirtyFields.length > 0, selfDirtinessTracker.$$_hibernate_hasDirtyAttributes() ); - String[] tracked = selfDirtinessTracker.$$_hibernate_getDirtyAttributes(); - assertEquals( dirtyFields.length, tracked.length ); - assertTrue( Arrays.asList( tracked ).containsAll( Arrays.asList( dirtyFields ) ) ); + final SelfDirtinessTracker selfDirtinessTracker = (SelfDirtinessTracker) entityInstance; + assertThat( selfDirtinessTracker.$$_hibernate_getDirtyAttributes() ) + .containsExactlyInAnyOrder( dirtyFields ); + assertThat( selfDirtinessTracker.$$_hibernate_hasDirtyAttributes() ) + .isEqualTo( dirtyFields.length > 0 ); } public static EntityEntry makeEntityEntry() {