Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Access to public field returns null for Hibernate entity lazy-loaded from polymorphic toOne association #8932

Closed
jrongs opened this issue Apr 28, 2020 · 8 comments · Fixed by #24059
Labels
area/hibernate-orm Hibernate ORM area/persistence OBSOLETE, DO NOT USE kind/bug Something isn't working
Milestone

Comments

@jrongs
Copy link

jrongs commented Apr 28, 2020

Describe the bug
Since release 1.3.2.Final, I noticed hibernate lazy load is no long working properly in my project. here is the hierarchy of the entities:

@MappedSuperclass
public abstract class EntityBase extends PanacheEntityBase {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long id;
}

@Entity
public class EntityA extends EntityBase  {
   @Column(nullable = false)
    public String name;
}

@Entity
**@Inheritance(strategy = InheritanceType.JOINED)**
public class EntityB extends EntityBase  {
	@ManyToOne(fetch = FetchType.LAZY, optional = false)
	public EntityA a;
}

@Entity
public class EntityC  extends EntityBase  {
	@ManyToOne(fetch = FetchType.LAZY, optional = false)
	public EntityB b;
        @Column(nullable = false)
        public String uuid;
}

and I'm getting NPE when accessing the entities this way:

EntityC  c= EntityC .find("uuid=?1", id).firstResult();

if (c.b.a.name.equals("") { ... 
}

c.b.a is null, because c.b is a hibernate proxy and it is not getting lazy loaded. everything worked fine before 1.3.2.Final.

Expected behavior
Hibernate lazy load works for all entities.

Actual behavior
Hibernate lazy load not working for entities annotated with Inheritance

To Reproduce
see description above.

Configuration

# Add your application.properties here, if applicable.
quarkus.datasource.url = jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
quarkus.datasource.driver = com.mysql.cj.jdbc.Driver
quarkus.datasource.username = usr
quarkus.datasource.password = pwd

quarkus.hibernate-orm.database.generation = none
quarkus.hibernate-orm.log.sql = true
quarkus.hibernate-orm.dialect = org.hibernate.dialect.MySQLDialect

Environment (please complete the following information):

  • Output of uname -a or ver: Linux orchid 4.15.0-96-generic Fix circularity detection and add a test #97-Ubuntu SMP Wed Apr 1 03:25:46 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
  • Output of java -version: java 11.0.1 2018-10-16 LTS
  • GraalVM version (if different from Java): n/a
  • Quarkus version or git rev: 1.3.2.Final and 1.4.1.Final
  • Build tool (ie. output of mvnw --version or gradlew --version): Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
@jrongs jrongs added the kind/bug Something isn't working label Apr 28, 2020
@jrongs
Copy link
Author

jrongs commented Apr 29, 2020

looks like lazy load is not getting triggered when the entity is annotated with:
@Inheritance(strategy = InheritanceType.JOINED)

@gsmet
Copy link
Member

gsmet commented Apr 29, 2020

@jrongs could you prepare a simple Maven project reproducing the issue?

/cc @Sanne @dreab8

@gsmet gsmet added the area/persistence OBSOLETE, DO NOT USE label Apr 29, 2020
@Sanne Sanne added the area/hibernate-orm Hibernate ORM label Apr 29, 2020
@jrongs
Copy link
Author

jrongs commented Apr 29, 2020

@gsmet thanks for the quick reply. I have attached a simple maven project to demonstrate the issue.

download, extract, and run the project:
./mvnw quarkus:dev

then run the curl:
curl -v -w "\n" localhost:8080/hello

you'll get the following message:
name: null

in the quarkus console, you'll notice that lazy load was never triggered on the "Content" entity:

Hibernate: 
    select
        folder0_.id as id1_1_0_,
        folder0_.content_id as content_2_1_0_ 
    from
        folder folder0_ 
    where
        folder0_.id=?

working as expected if I remove the following line from the "Content" entity:

@Inheritance(strategy = InheritanceType.JOINED)

curl command returns:
name: it is working!

and we get the following in the quarkus console output:

Hibernate: 
    select
        folder0_.id as id1_1_0_,
        folder0_.content_id as content_2_1_0_ 
    from
        folder folder0_ 
    where
        folder0_.id=?
Hibernate: 
    select
        content0_.id as id1_0_0_,
        content0_.name as name2_0_0_ 
    from
        content content0_ 
    where
        content0_.id=?

please let me know if you need more details to troubleshoot. Thanks!

code-with-quarkus.zip

dreab8 added a commit to dreab8/quarkus that referenced this issue May 15, 2020
dreab8 added a commit to dreab8/quarkus that referenced this issue May 15, 2020
dreab8 added a commit to dreab8/quarkus that referenced this issue May 15, 2020
dreab8 added a commit to dreab8/quarkus that referenced this issue May 15, 2020
Sanne pushed a commit to Sanne/quarkus that referenced this issue May 15, 2020
Sanne pushed a commit to Sanne/quarkus that referenced this issue May 15, 2020
@jrongs
Copy link
Author

jrongs commented Jan 2, 2021

still experiencing the same issue in release 1.10.5.Final. we did find a workaround by manually define the getters and setters on entities in the inheritance hierarchy:

 @MappedSuperclass
public abstract class EntityBase extends PanacheEntityBase {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long id;
    
    public Long getId() {
        return id;
    }
}

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class File extends EntityBase  {
       @Column(nullable = false)
	public String name;
	
	public String getName() {
	    return name;
	}
	public void setName(String name) {
	    this.name = name;
	}
}

@Entity
public class Image extends File {
    @Column(nullable = false)
    public int size;
    
    public int getSize() {
        return size;
    }
    public void setSize(int size) {
        this.size = size;
    }
}

@Entity
public class Folder extends BaseEntity {
    @ManyToOne(fetch=FetchType.Lazy)
    public File file;
}

with those getters/settings, everything works as expected:

Folder f = Folder.findById(1L);
System.out.println(f.file.name); //we get null without the getter (File.getName()).  

Hope this helps.

@HonoluluHenk
Copy link

Maybe related to this Hibernate-Bug?
https://hibernate.atlassian.net/browse/HHH-14549
In case this is the cause: just bump hibernate to 5.4.31

@dan-dr
Copy link

dan-dr commented Nov 26, 2021

Encountered this on 1.13.7 Final. same with @jrongs , i can circumvent it with getters, but really don't want to... any other solution?

@Sanne what happened to the test case you PR'd?

@yrodiere
Copy link
Member

I was able to reproduce the problem on Quarkus 2.7.2.Final with @jrongs 's reproducer (thanks for that!). Removing the @Inheritance annotation doesn't change anything for me, though.

I'll try to find out where the problem comes from exactly.

@yrodiere
Copy link
Member

yrodiere commented Feb 24, 2022

The problem appears to be in Hibernate ORM itself. I created https://hibernate.atlassian.net/browse/HHH-15090 and will handle this upstream.

EDIT: As it turns out, there is also a problem in Quarkus: proxy classes are generated before we add getter/setter methods for the public fields, which means those getter/setter methods are not intercepted by the proxy, and as a result they do not trigger initialization... I'll need to address that, too.

@yrodiere yrodiere changed the title Hibernate Lazy load issue Access to public field returns null for Hibernate entity lazy-loaded from polymorphic toOne association Feb 24, 2022
@quarkus-bot quarkus-bot bot added this to the 2.9 - main milestone Apr 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/hibernate-orm Hibernate ORM area/persistence OBSOLETE, DO NOT USE kind/bug Something isn't working
Projects
None yet
6 participants