繁体   English   中英

Hibernate @OneToMany导致多个选择语句

[英]Hibernate @OneToMany causing multiple select statements

我正在研究一个Hibernate问题,该问题涉及在自己的类中分别定义的2个单独的Entity bean:

  • 商店
  • 商店服务器

请注意,一个商店将具有多个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

StoreServer:

@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记录。

当前,在日志中,我看到单个SELECT语句来获取Store记录(返回了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

使用诸如H2JDBC Sniffer之类的内存数据库在单元测试中验证Hibernate生成的查询数量可能是一个好主意

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM