【问题标题】:JPA - Only get parent, not childrenJPA - 只得到父母,而不是孩子
【发布时间】:2017-04-30 13:59:02
【问题描述】:

我有这样的父母:

@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;
    }
}

我有一个获取所有父母的命名查询,但这也加载了所有孩子?如何阻止孩子自动加载?

谢谢。

【问题讨论】:

  • 请发布您获取父级的查询。
  • @AbdullahWasi 它只是标准的 findAll 查询,并被称为 JAX-RS 作为命名查询
  • 延迟加载是默认设置,因此如果正在加载它们,那么它正在执行的是您的代码 - 所以发布相关代码。
  • 你有没有为这个没有孩子的抓取父母找到任何解决方案?

标签: java sql spring hibernate jpa


【解决方案1】:

延迟加载是计算机编程中常用的一种设计模式,用于将对象的初始化推迟到需要它的时候。如果使用得当和适当,它可以提高程序运行的效率。延迟加载的反面是急切加载

如何在 Hibernate 中启用延迟加载

在继续之前,重要的是回顾一下默认行为 在使用休眠映射与注释的情况下延迟加载。 默认行为是加载“属性值急切”并加载 '收集懒惰'。与你可能记得的相反,如果你有 之前使用过普通的 Hibernate 2(映射文件),其中所有引用 (包括集合)默认加载。另请注意 @OneToMany 和 @ManyToMany 关联默认为 LAZY 加载; @OneToOne 和 @ManyToOne 默认为 EAGER 加载。这是 重要的是要记住,以避免将来出现任何陷阱。启用懒惰 显式加载你必须使用“fetch = FetchType.LAZY” 使用休眠时要延迟加载的关联 注释。示例用法如下所示:@OneToMany( mappedBy = "category", fetch = FetchType.LAZY ) 私有集产品; 与“FetchType.LAZY”平行的另一个属性是“FetchType.EAGER” 这与 LAZY 正好相反,即它将关联实体加载为 好吧,当第一次获取所有者实体时。延迟加载的工作原理 在 Hibernate 中 Hibernate 可以应用延迟加载的最简单方法 对您的实体和关联的行为是通过提供代理 它们的实施。 Hibernate 通过以下方式拦截对实体的调用 用从实体类派生的代理替换它。在哪里 请求的信息丢失,将从数据库中加载 在将控制权交给父实体的实施之前。请 请注意,当关联表示为集合类时, 然后是一个包装器(本质上是集合的代理,而不是 对于它包含的实体)被创建并替换为 原创收藏。当您访问此集合代理时,那么 您进入返回的代理集合不是代理实体; 相反,它们是实际的实体。你不需要施加太大的压力 理解这个概念,因为在运行时它几乎不重要。

【讨论】:

    【解决方案2】:

    我知道我的答案迟了,但它可能会帮助其他人,因为我有一段时间遇到同样的问题, 基于此answer 如果您使用rest API,Spring 调用Jackson 返回Parent 对象,Jackson 调用getChild,因此,加载了父母的孩子。 一种解决方案是为不包含 Child 的 Parent 类定义一个 Dto 类,例如

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

    然后在休息控制器中返回 ParenResponseDto

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

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

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-25
    • 2014-12-06
    • 2017-10-25
    • 1970-01-01
    • 2016-03-05
    • 1970-01-01
    相关资源
    最近更新 更多