diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/access/UnsupportedEnhancementStrategyTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/access/UnsupportedEnhancementStrategyTest.java index 902b19c9599..0e60fe6647b 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/access/UnsupportedEnhancementStrategyTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/access/UnsupportedEnhancementStrategyTest.java @@ -9,7 +9,10 @@ import jakarta.persistence.Basic; import jakarta.persistence.Entity; import jakarta.persistence.Id; -import jakarta.persistence.Table; +import jakarta.persistence.PostLoad; +import jakarta.persistence.PrePersist; +import jakarta.persistence.Transient; + import org.hibernate.bytecode.enhance.internal.bytebuddy.EnhancerImpl; import org.hibernate.bytecode.enhance.spi.EnhancementContext; import org.hibernate.bytecode.enhance.spi.EnhancementException; @@ -18,11 +21,13 @@ import org.hibernate.bytecode.internal.bytebuddy.ByteBuddyState; import org.hibernate.bytecode.spi.ByteCodeHelper; import org.hibernate.testing.bytecode.enhancement.EnhancerTestContext; +import org.hibernate.testing.orm.junit.Jira; import org.hibernate.testing.orm.junit.JiraKey; import org.junit.jupiter.api.Test; import java.io.IOException; import java.io.InputStream; +import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -39,28 +44,31 @@ public UnsupportedEnhancementStrategy getUnsupportedEnhancementStrategy() { return UnsupportedEnhancementStrategy.SKIP; } }; - byte[] originalBytes = getAsBytes( SomeEntity.class ); - byte[] enhancedBytes = doEnhance( SomeEntity.class, originalBytes, context ); + byte[] enhancedBytes = doEnhance( SomeEntity.class, context ); assertThat( enhancedBytes ).isNull(); // null means "not enhanced" } @Test public void fail() throws IOException { - var context = new EnhancerTestContext() { - @Override - public UnsupportedEnhancementStrategy getUnsupportedEnhancementStrategy() { - return UnsupportedEnhancementStrategy.FAIL; - } - }; - byte[] originalBytes = getAsBytes( SomeEntity.class ); - assertThatThrownBy( () -> doEnhance( SomeEntity.class, originalBytes, context ) ) - .isInstanceOf( EnhancementException.class ) + var context = new UnsupportedEnhancerContext(); + assertThatThrownBy( () -> doEnhance( SomeEntity.class, context ) ).isInstanceOf( EnhancementException.class ) .hasMessageContainingAll( String.format( "Enhancement of [%s] failed because no field named [%s] could be found for property accessor method [%s].", - SomeEntity.class.getName(), "propertyMethod", "getPropertyMethod" ), - "To fix this, make sure all property accessor methods have a matching field." + SomeEntity.class.getName(), + "propertyMethod", + "getPropertyMethod" + ), "To fix this, make sure all property accessor methods have a matching field." ); + assertThatThrownBy( () -> doEnhance( SomeOtherEntity.class, context ) ).isInstanceOf( EnhancementException.class ) + .hasMessageContainingAll( + String.format( + "Enhancement of [%s] failed because no field named [%s] could be found for property accessor method [%s].", + SomeOtherEntity.class.getName(), + "propertyMethod", + "setPropertyMethod" + ), "To fix this, make sure all property accessor methods have a matching field." + ); } @Test @@ -73,26 +81,49 @@ public UnsupportedEnhancementStrategy getUnsupportedEnhancementStrategy() { return UnsupportedEnhancementStrategy.LEGACY; } }; - byte[] originalBytes = getAsBytes( SomeEntity.class ); - byte[] enhancedBytes = doEnhance( SomeEntity.class, originalBytes, context ); + byte[] enhancedBytes = doEnhance( SomeEntity.class, context ); assertThat( enhancedBytes ).isNotNull(); // non-null means enhancement _was_ performed } - private byte[] doEnhance(Class someEntityClass, byte[] originalBytes, EnhancementContext context) { - final ByteBuddyState byteBuddyState = new ByteBuddyState(); - final Enhancer enhancer = new EnhancerImpl( context, byteBuddyState ); - return enhancer.enhance( someEntityClass.getName(), originalBytes ); + @Test + @Jira( "https://hibernate.atlassian.net/browse/HHH-18903" ) + @Jira( "https://hibernate.atlassian.net/browse/HHH-18904" ) + public void testEntityListeners() throws IOException { + // non-null means check passed and enhancement _was_ performed + assertThat( doEnhance( EventListenersEntity.class, new UnsupportedEnhancerContext() ) ).isNotNull(); } - private byte[] getAsBytes(Class clazz) throws IOException { + @Test + @Jira( "https://hibernate.atlassian.net/browse/HHH-18903" ) + @Jira( "https://hibernate.atlassian.net/browse/HHH-18904" ) + public void testAccessTypeFieldEntity() throws IOException { + var context = new UnsupportedEnhancerContext(); + // non-null means check passed and enhancement _was_ performed + assertThat( doEnhance( ExplicitAccessTypeFieldEntity.class, context ) ).isNotNull(); + assertThat( doEnhance( ImplicitAccessTypeFieldEntity.class, context ) ).isNotNull(); + } + + private static byte[] doEnhance(Class entityClass, EnhancementContext context) throws IOException { + final ByteBuddyState byteBuddyState = new ByteBuddyState(); + final Enhancer enhancer = new EnhancerImpl( context, byteBuddyState ); + return enhancer.enhance( entityClass.getName(), getAsBytes( entityClass ) ); + } + + private static byte[] getAsBytes(Class clazz) throws IOException { final String classFile = clazz.getName().replace( '.', '/' ) + ".class"; try (InputStream classFileStream = clazz.getClassLoader().getResourceAsStream( classFile )) { return ByteCodeHelper.readByteCode( classFileStream ); } } - @Entity - @Table(name = "SOME_ENTITY") + static class UnsupportedEnhancerContext extends EnhancerTestContext { + @Override + public UnsupportedEnhancementStrategy getUnsupportedEnhancementStrategy() { + return UnsupportedEnhancementStrategy.FAIL; + } + } + + @Entity(name = "SomeEntity") static class SomeEntity { @Id Long id; @@ -102,15 +133,6 @@ static class SomeEntity { String property; - public SomeEntity() { - } - - public SomeEntity(Long id, String field, String property) { - this.id = id; - this.field = field; - this.property = property; - } - /** * The following property accessor methods are purposely named incorrectly to * not match the "property" field. The HHH-16572 change ensures that @@ -128,4 +150,105 @@ public void setPropertyMethod(String property) { this.property = property; } } + + @Entity(name = "SomeOtherEntity") + static class SomeOtherEntity { + @Id + Long id; + + @Basic + String field; + + String property; + @Access(AccessType.PROPERTY) + public void setPropertyMethod(String property) { + this.property = property; + } + } + + @Entity(name = "EventListenersEntity") + static class EventListenersEntity { + private UUID id; + + private String status = "new"; + + @Id + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + // special case, we should let it through + public UUID get() { + return id; + } + + @PrePersist + public void setId() { + id = UUID.randomUUID(); + } + + @Transient + public String getState() { + return status; + } + + @PostLoad + public void setState() { + status = "loaded"; + } + + @Transient + public boolean isLoaded() { + return status.equals( "loaded" ); + } + } + + @Entity(name = "ExplicitAccessTypeFieldEntity") + @Access( AccessType.FIELD ) + static class ExplicitAccessTypeFieldEntity { + @Id + private Long id; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long get() { + return id; + } + + public String getSomething() { + return "something"; + } + } + + @Entity(name = "ImplicitAccessTypeFieldEntity") + static class ImplicitAccessTypeFieldEntity { + @Id + private Long id; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long get() { + return id; + } + + public String getAnother() { + return "another"; + } + } }