【发布时间】:2020-06-07 22:58:13
【问题描述】:
我在使用 Hibernate Spring 获取数据时遇到了问题。我试图弄清楚为什么特定的 Get 请求没有按预期工作。
目标是通过以下方法获取表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 是引用的前向部分,通常会被序列化。这可能是子查询被执行的原因。