JPA - 仅获取父级,而不是子级

4

我有一个父元素如下:

@Entity
@Table(name="parent")
public class Parent {

    private List<Child> childs;
    private List<AnotherChild> anotherChilds;

    @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
    public List<Child> getChilds() {
        return childs;
    }

    @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
    public List<AnotherChild> getAntoherChilds() {
        return anotherChilds;
    }

    //Getters and Setters ommited
}

而像这样的两个孩子

@Entity
@Table(name="child")
public class Child {

    private Parent parent;

    @ManyToOne
    @JoinColumn(name = "column_name")
    public Parent getParent() {
        return patern;
    }
}

@Entity
@Table(name="another_child")
public class AnotherChild {

    private Parent parent;

    @ManyToOne
    @JoinColumn(name = "column_name")
    public Parent getParent() {
        return patern;
    }
}

我有一个命名查询,它获取所有的父级,但同时也会加载所有的子级。如何阻止子级自动加载?

谢谢。


请发布您的查询以获取父级。 - Abdullah Khan
1
@AbdullahWasi 这只是标准的findAll查询,并且作为一个命名查询从JAX-RS中被调用。 - iqueqiorio
懒加载是默认设置,因此如果它们正在被加载,则是您的代码在执行此操作 - 因此,请发布相关代码。 - Alan Hay
你找到了获取没有子元素的父元素的解决方案吗? - Aadam
2个回答

4

我知道我的回答有点晚,但它可能会帮助其他人,因为我曾经遇到过同样的问题。 根据这个答案,如果你使用rest API,Spring就会调用Jackson来返回Parent对象,而Jackson会调用getChild方法,因此parent的child被加载了。 一个解决方案是为Parent类定义一个Dto类,该类不包括Child,例如:

public class ParentResponseDto{
    private Long id
    private String name; 
    //and your desired attribute that you want to load
}

然后在REST控制器中返回ParenResponseDto。

@GetMapping
public ParenResponseDto getParent(Long id){
    Parent p = repository.findById(id);
    ParenResponseDto dto = mapParentToParenResponseDto();
    return dto;
}

你可以使用 ModelMapper 来映射类,这是一个很棒的模块。


1
MapStruct也非常高效,可以查看此答案以避免相同的问题:https://dev59.com/gKLia4cB1Zd3GeqPcQTh#65391112 - DependencyHell

0

惰性加载是计算机编程中常用的设计模式,它将对象的初始化推迟到需要的时候。如果正确和适当地使用,它可以有助于程序的运行效率。与惰性加载相反的是急切加载

如何在Hibernate中启用延迟加载
在进一步讨论之前,重温一下使用Hibernate映射与注释时延迟加载的默认行为非常重要。默认行为是“急切地加载属性值”和“懒惰地加载集合”。与您以前使用纯Hibernate 2(映射文件)时记住的相反,其中所有引用(包括集合)默认情况下都会急切地加载。还请注意,@OneToMany和@ManyToMany关联默认为LAZY加载;而@OneToOne和@ManyToOne默认为EAGER加载。这很重要,以避免将来出现任何问题。要显式启用延迟加载,必须在希望延迟加载的关联上使用“fetch = FetchType.LAZY”,当您使用Hibernate注释时。示例用法如下:@OneToMany(mappedBy =“category”,fetch = FetchType.LAZY)private Set products;与“FetchType.LAZY”并行的另一个属性是“FetchType.EAGER”,它与LAZY完全相反,即在第一次获取所有者实体时也会加载关联实体。Hibernate中的延迟加载工作原理Hibernate可以应用于实体和关联的最简单的延迟加载行为是提供它们的代理实现。 Hibernate通过从实体类派生代理来替换对实体的调用。如果缺少请求的信息,则在控制权移交给父实体的实现之前,将从数据库中加载该信息。请注意,当将关联表示为集合类时,将创建一个包装器(基本上是集合的代理,而不是包含它的实体的代理),并替换原始集合。当您访问此集合代理时,返回的代理集合内部获取的不是代理实体;而是实际实体。您无需过多地了解此概念,因为在运行时几乎没有影响。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接