简体   繁体   中英

LAZY Loading not working Spring Data 3.0.0 Hibernate - After Spring Boot Migration to 3.0

After migrating to Spring Boot 3.0 our integration test showed that deleting a user did not work properly.

The User has two properties, where both are defined the same (at least thats what I think, see below).

What I figured is, when I load the User object one of the properties of User are not loaded. Only if I define the property, which can not be loaded, as EAGER. If I now try to delete the User, this does not work because there is still the one property in DB which reference to the User.

I can not figure out whats the problem maybe I am missing something

My User Entity

@Entity
@Data
@Table(name = "user_model")
public class User extends BaseEntity {
    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    private String id;
    
    ...

    @OneToOne(fetch = FetchType.LAZY, mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
    private UserSettings userSettings;

    @OneToOne(fetch = FetchType.LAZY, mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
    private UserTermsOfUse userTermsOfUse;
    
    ...
}

User Terms Of Use which works to load

@Entity
@Table(name = "user_termsofuse")
@Data
public class UserTermsOfUse extends BaseEntity {

    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    private String id;

    @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumn(name = "user_id", referencedColumnName = "id")
    @ToString.Exclude
    private User user;

    @Column(name = "accepted_termsofuse")
    private String acceptedTermsOfUse;

}

My Settings which does not load:

@Entity
@Table(name = "user_settings")
@Data
public class UserSettings extends BaseEntity {

    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    private String id;

    @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumn(name = "user_id", referencedColumnName = "id")
    @ToString.Exclude
    private User user;

    private String language;

    private String lastActiveClientId;

}

As you can see in my screenshot, when I load the entity User by ID it only shows the User Terms of Use ant not the User Settings在此处输入图像描述

Just to make clear, they are within the DB:) 在此处输入图像描述

Hope Someone can point me to a correct direction

UPDATE

I made a sample project to prove it does not work. The test fails with an NullPonterException once I try to access the UserSettings .

https://github.com/de313e/SpringEagerLoadingIssue

This is clearly a bug for hibernate project.

Have opened a ticket for it here with both the bug described in the question from kism3t and also with what seems to be a workaround to bypass the issue.

Have checked the current non stable released versions of hibernate 6.2.0 and the bug is still there. So probably is undetected yet.

For the moment the following workaround seems to bypass the issue

   @Entity
   public class User {

      @OneToOne(fetch = FetchType.LAZY, mappedBy = "user") 
      private UserSettings userSettings;

      @OneToOne(fetch = FetchType.LAZY, mappedBy = "user") 
      private UserTermsOfUse userTermsOfUse;
  }

If the owning side of the @OneToOne declares the same fetchType of Lazy somehow the issue is bypassed.

So it works with

@Entity
public class UserTermsOfUse {

    ....

    @OneToOne(fetch = FetchType.LAZY)  // <-------------
    private User user;
}

and

@Entity
public class UserSettings {

    ....

    @OneToOne(fetch = FetchType.LAZY)  // <-------------
    private User user;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM