延迟加载无法在 JPA 中使用 hibernate [英] Lazy loading not working in JPA with hibernate

查看:35
本文介绍了延迟加载无法在 JPA 中使用 hibernate的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Spring Boot 应用程序中使用 JPA 和 hibernate.每当我尝试使用 jpa 方法获取实体时,它都会返回实体以及其中存在的所有关联.我想按需获取关联实体(延迟加载),因此我在域类中提供了 fetch=FetchType.LAZY.但它仍然返回所有条目.

I am using JPA with hibernate in my spring boot application. Whenever I try to fetch the enities using jpa methods, its returning the entity plus all the association present inside it. I wanted to fetch the associated entities on demand(lazy loading), so I have provided fetch=FetchType.LAZY in my domain class. But still its returning all the entries.

代码如下:Case.java

    @Entity
    @Table(name="smss_case")
    public class Case implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = -2608745044895898119L;

    @Id
    @Column(name = "case_id", nullable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer caseId;

    @Column( name="case_title" )
    private String caseTitle;

    @JsonManagedReference
    @OneToMany(mappedBy="smmsCase", cascade = CascadeType.ALL, fetch=FetchType.LAZY)
    private Set<Task> tasks;

    }

}

Task.java

@Entity
@Table(name="task_prop")
public class Task implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = -483515808714392369L;

    @Id
    @Column(name = "task_id", nullable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer taskId;

    @Column(name="task_title")
    private String taskTitle;

    @JsonBackReference
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn( name="case_id", nullable=false)
    private Case smmsCase;
// getters and setters
}

Service.java

public Case getCases(Integer id) {
        return dao.findById(1).get();
}

Dao.java

public interface ServiceDao extends JpaRepository<Case, Integer>{

}

{
"caseId":1,"caseTitle":"人体工程学",任务":[
{
任务ID":1,"taskTitle":"ca"},{
任务ID":2,"taskTitle":"危险"},{
任务ID":3,"taskTitle":"补救措施"}]}

{
"caseId":1, "caseTitle":"ergonomics", "tasks":[
{
"taskId":1, "taskTitle":"ca" }, {
"taskId":2, "taskTitle":"hazards" }, {
"taskId":3, "taskTitle":"remedy" } ] }

任何帮助将不胜感激!

谢谢!

推荐答案

调查起来很棘手,但我在使用 mapstruct 并且它碰巧做了深度/嵌套映射,并且在这个过程中,它调用延迟加载属性的getter.当我使用 mapstrct @BeforeMapping 时,问题得到解决.

Was tricky to investigate but I had this issue as I was using mapstruct and it happens to do deep/ nested mapping and in the process, it calls getter of the lazy loaded property. The issue was resolved when I used mapstrct @BeforeMapping.

@Mapper
public interface HibernateAwareMapper {
    @BeforeMapping
    default <T> Set<T> fixLazyLoadingSet(Collection<?> c, @TargetType Class<?> targetType) {
        if (!Util.wasInitialized(c)) {
            return Collections.emptySet();
        }
        return null;
    }

    @BeforeMapping
    default <T> List<T> fixLazyLoadingList(Collection<?> c, @TargetType Class<?> targetType) {
        if (!Util.wasInitialized(c)) {
            return Collections.emptyList();
        }
        return null;
    }

   class Util {
       static boolean wasInitialized(Object c) {
           if (!(c instanceof PersistentCollection)) {
               return true;
           }

           PersistentCollection pc = (PersistentCollection) c;
           return pc.wasInitialized();
       }
   }
}

参考.作者:kokorin

这篇关于延迟加载无法在 JPA 中使用 hibernate的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆