【问题标题】:Child entities fetches with lazy fetching子实体通过延迟获取获取
【发布时间】:2020-06-07 22:58:13
【问题描述】:

我在使用 Hibernate Spring 获取数据时遇到了问题。我试图弄清楚为什么特定的 Get 请求没有按预期工作。

Database lay out

目标是通过以下方法获取表country中所有国家的列表:

> @GetMapping("/getCountry") public List <Country> getCountry(){ 
>   return(List<Country>) countryRepo.findAll();  }

国家实体是:

@Entity
public class Country {

    @Id
    private Integer id;

    private String name;

    @OneToMany(mappedBy="country", cascade=CascadeType.ALL, fetch=FetchType.LAZY)
    @JsonManagedReference
    private List<PortOfLoading> portOfLoadings;

    public Country() {

    } 
//getters and setters omitted

装货港实体是:

@Entity

公共类 PortOfLoading {

@Id
private int id;

private String name;

@ManyToOne(fetch = FetchType.LAZY)
@JsonBackReference
private Country country;

@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "port_of_loading_id", referencedColumnName = "id")
private List<Container> containers;

public PortOfLoading() {

} //getters and setters are omitted

我希望 hibernate 进行这样的查询:

Hibernate: select country0_.id as id1_4_, country0_.name as name2_4_ from country country0_

但不是那样,hibernate 开始获取该实体的所有装载端口,然后还获取每个装载端口的所有容器:

Hibernate: select portofload0_.country_id as country_3_5_0_, portofload0_.id as id1_5_0_, portofload0_.id as id1_5_1_, portofload0_.country_id as country_3_5_1_, portofload0_.name as name2_5_1_ from port_of_loading portofload0_ where portofload0_.country_id=?

Hibernate: select containers0_.port_of_loading_id as port_of_8_2_0_, containers0_.id as id1_2_0_, containers0_.id as id1_2_1_, containers0_.carrier_id as carrier_5_2_1_, containers0_.container_reference as containe2_2_1_, containers0_.container_sort_id as containe6_2_1_, containers0_.port_of_loading_country_id as port_of_7_2_1_, containers0_.ocean_freight_costs_invoiced as ocean_fr3_2_1_, containers0_.port_of_loading_id as port_of_8_2_1_, containers0_.terminal_handeling_costs_invoiced as terminal4_2_1_ from container containers0_ where containers0_.port_of_loading_id=?

由于所有其他查询,获取数据需要很长时间,我一直在努力弄清楚为什么会这样。

提前致谢!

【问题讨论】:

  • 你能分享findAll()方法的代码吗?
  • findAll() 方法是 crudRepository 的标准方法。
  • 你能在 PortOfLoading 类中试试@JoinColumn(name = "country_id")
  • 因为您直接返回实体而不使用任何 POJO。执行findAll() 时可能不会调用其他查询。返回结果时可能会被controller 调用。拆分 findAll()return 语句并检查何时执行其他查询
  • 尝试在私有 List portOfLoadings 之上包含杰克逊注解 JsonIgnore;注释 JsonManagedReference 是引用的前向部分,通常会被序列化。这可能是子查询被执行的原因。

标签: java hibernate


【解决方案1】:

解决了!函数 FindAll() 使用正确的查询获取所有数据。但是 getCountry() 方法的 return 语句会获取所有其他实体。添加@JsonIgnore 解决了return语句的问题:

@OneToMany(mappedBy="country", cascade=CascadeType.ALL, fetch=FetchType.LAZY)
@JsonIgnore
private List<PortOfLoading> portOfLoadings;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-13
    • 2015-10-26
    • 1970-01-01
    • 2021-12-03
    • 2022-01-23
    • 1970-01-01
    相关资源
    最近更新 更多