gpt4 book ai didi

java - hibernate @OneToMany导致多个选择语句

转载 作者:搜寻专家 更新时间:2023-11-01 03:37:06 25 4
gpt4 key购买 nike

我正在处理一个 Hibernate 问题,它涉及在它们自己的类中分别定义的 2 个独立的实体 bean:

  • 商店
  • 商店服务器

请注意,一个 Store 将拥有多个 StoreServer - 因此使用了 @OneToMany 注释。请看代码片段如下:

商店:

@Entity
@Table(name="Store")
public class Store implements Serializable {
/**
* Serializable class - generated UID
*/
private static final long serialVersionUID = 5644190852867691168L;

@Id
@Column(name="STORE_NO", nullable=false)
private int storeNumber;

@Column(name="STORE_NAME", nullable=false)
private String storeName;

@Column(name="STORE_PHONE", nullable=false)
private String storePhone;

//other Store fields...

@OneToMany(fetch = FetchType.EAGER)
@JoinColumn(name="STORE_NO", insertable=false, updatable=false)
private List<StoreServer> storeServers = new ArrayList<StoreServer>();

//getters and setters

商店服务器:

@Entity
@Table(name="Store_Server")
public class StoreServer implements Serializable {
/**
* Serializable class - generated UID
*/
private static final long serialVersionUID = -5410564578856243437L;

@Id
private StoreServerPK storeServerPK;

@Column(name="IP_ADDRESS", nullable=true)
private String ipAddress;

//other StoreServer fields...getters and setters

由于 StoreServer 有一个复合主键,这里是 StoreServerPK:

@Embeddable
public class StoreServerPK implements Serializable {
/**
* Serializable class - generated UID
*/
private static final long serialVersionUID = -1401889029390423604L;

@Column(name="STORE_NO", nullable=false)
protected int storeNumber;

@Column(name="SERVER_NO", nullable=false)
protected String serverNumber;

//getters and setters

目前,我得到了正确的结果,但性能慢得令人无法接受。我已打开 Hibernate 中的日志记录,我可以看到正在为每个商店实体运行一个单独的 SELECT 查询,以获取关联的 StoreServer 记录。

目前,在日志中,我看到一条用于获取 Store 记录的 SELECT 语句(返回了 200 多个结果)。然后对于每个商店,一个新的 SELECT 语句来获取 StoreServer 记录。我的问题是...为什么 Hibernate 不执行连接(运行一个查询)?

关于如何使用 JOIN 告诉 Hibernate 运行单个查询,我能得到一些帮助吗?

谢谢

最佳答案

这叫做N+1问题

解决方案实际上取决于您如何进行查询 - 如果您使用的是 Criteria API,则应使用 Root.fetch方法:

CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Store> cq = qb.createQuery(Store.class);

Root<Store> root = cq.from(Store.class);
root.fetch(App_.storeServers, JoinType.LEFT);

cq.select(root);

return em.createQuery(cq).getResultList();

如果您使用的是 HQL,则应使用 fetch 关键字:

select distinct st from Store st left join fetch st.storeServers

使用内存数据库(如 H2)验证 Hibernate 在单元测试中生成的查询数量可能是个好主意。和 JDBC Sniffer

关于java - hibernate @OneToMany导致多个选择语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27962089/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com