Skip to content

Commit

Permalink
HHH-18832 Don't skip bytecode enhancement just because an entity has …
Browse files Browse the repository at this point in the history
…a `@Transient` getter
  • Loading branch information
yrodiere committed Nov 13, 2024
1 parent abfe6b9 commit 1ffde48
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,11 @@ else if (methodName.startsWith("get") ||
// convert field letter to lower case
methodFieldName = methodFieldName.substring(0, 1).toLowerCase() + methodFieldName.substring(1);
TypeList typeList = methodDescription.getDeclaredAnnotations().asTypeList();
if (typeList.stream().anyMatch(typeDefinitions ->
(typeDefinitions.getName().equals("jakarta.persistence.Transient")))) {
// transient property so ignore it
continue;
}
if (typeList.stream().anyMatch(typeDefinitions ->
(typeDefinitions.getName().contains("jakarta.persistence")))) {
propertyHasAnnotation = true;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
package org.hibernate.orm.test.bytecode.enhancement.access;

import jakarta.persistence.*;
import jakarta.persistence.Access;
import jakarta.persistence.AccessType;
import jakarta.persistence.Basic;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.persistence.Transient;
import org.hibernate.testing.bytecode.enhancement.extension.BytecodeEnhanced;
import org.hibernate.testing.orm.junit.*;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.FailureExpected;
import org.hibernate.testing.orm.junit.JiraKey;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;

Expand All @@ -11,16 +21,17 @@
@DomainModel(
annotatedClasses = {
InvalidPropertyNameTest.SomeEntity.class,
InvalidPropertyNameTest.SomeEntityWithFalsePositive.class
}
)
@SessionFactory
@JiraKey("HHH-16572")
@BytecodeEnhanced
public class InvalidPropertyNameTest {


@Test
@FailureExpected(jiraKey = "HHH-16572")
@JiraKey("HHH-16572")
public void test(SessionFactoryScope scope) {
scope.inTransaction( session -> {
session.persist( new SomeEntity( 1L, "field", "property" ) );
Expand All @@ -39,15 +50,40 @@ public void test(SessionFactoryScope scope) {
} );
}

@Test
@JiraKey("HHH-18832")
public void testNoFalsePositive(SessionFactoryScope scope) {
scope.inTransaction( session -> {
session.persist( new SomeEntityWithFalsePositive( 1L, "property1-initial", "property2-initial" ) );
} );

// Before HHH-18832 was fixed, lazy-loading enhancement was (incorrectly) skipped,
// resulting at best in `property1` being null in the code below,
// at worst in other errors such as java.lang.NoSuchMethodError: 'java.lang.String org.hibernate.orm.test.bytecode.enhancement.access.InvalidPropertyNameTest$SomeEntityWithFalsePositive.$$_hibernate_read_property1()'
// (see https://hibernate.zulipchat.com/#narrow/channel/132094-hibernate-orm-dev/topic/HHH-16572/near/481330806)
scope.inTransaction( session -> {
SomeEntityWithFalsePositive entity = session.getReference( SomeEntityWithFalsePositive.class, 1L );
// Lazy-loading triggered by field access
// Proves bytecode enhancement is effective
assertThat( entity.property1 ).isEqualTo( "property1-initial" );
} );

scope.inTransaction( session -> {
SomeEntityWithFalsePositive entity = session.getReference( SomeEntityWithFalsePositive.class, 1L );
// Proves bytecode enhancement is effective even for the transient method
assertThat( entity.getProperty() ).isEqualTo( "property1-initial property2-initial" );
} );
}

@AfterEach
public void cleanup(SessionFactoryScope scope) {
// uncomment the following when @FailureExpected is removed above
// scope.inTransaction( session -> {
// session.remove( session.get( SomeEntity.class, 1L ) );
// PropertyAccessTest} );
scope.inTransaction( session -> {
session.createQuery( "delete from SomeEntity" ).executeUpdate();
session.createQuery( "delete from SomeEntityWithFalsePositive" ).executeUpdate();
} );
}

@Entity
@Entity(name = "SomeEntity")
@Table(name = "SOME_ENTITY")
static class SomeEntity {
@Id
Expand Down Expand Up @@ -84,4 +120,53 @@ public void setPropertyMethod(String property) {
this.property = property;
}
}

@Entity(name = "SomeEntityWithFalsePositive")
static class SomeEntityWithFalsePositive {

private Long id;

private String property1;

private String property2;

public SomeEntityWithFalsePositive() {
}

public SomeEntityWithFalsePositive(Long id, String property1, String property2) {
this.id = id;
this.property1 = property1;
this.property2 = property2;
}

@Id
public long getId() {
return id;
}

public void setId(long id) {
this.id = id;
}

public String getProperty1() {
return property1;
}

public void setProperty1(String property1) {
this.property1 = property1;
}

public String getProperty2() {
return property2;
}

public void setProperty2(String property2) {
this.property2 = property2;
}

@Transient
public String getProperty() {
return property1 + " " + property2;
}
}
}

0 comments on commit 1ffde48

Please sign in to comment.