JPA通过Hibernate生成的N select连接获取关联表?

时间:2011-06-27 13:46:46

标签: hibernate jpa

我正在使用JPA和Hibernate3作为实现。我有一个关联表UsrGrp

Usr.java
@Id
@Basic(optional = false)
@Column(name = "usr_id")
private String usrId;
@OneToMany(mappedBy = "usr")
private List<UsrGrp> usrGrpList;

UsrGrp.java
@EmbeddedId
protected UsrGrpPK usrGrpPK;
@Column(name = "updated_by")
private String updatedBy;
@Column(name = "updated_date")
@Temporal(TemporalType.TIMESTAMP)
private Date updatedDate;
@JoinColumn(name = "grp_id", referencedColumnName = "grp_id", insertable = false, updatable = false)
@ManyToOne(optional = false)
private Grp grp;
@JoinColumn(name = "usr_id", referencedColumnName = "usr_id", insertable = false, updatable = false)
@ManyToOne(optional = false)
private Usr usr;

Grp.java
@Id
@Basic(optional = false)
@Column(name = "grp_id")
@OneToMany(mappedBy = "grp")
private List<UsrGrp> usrGrpList;

(Usr)1 -------- *(UsrGrp)* -------- 1(Grp)

当我执行以下sql。

SELECT DISTINCT usr FROM Usr usr LEFT JOIN FETCH usr.usrGrpList

Hibernate实际执行与我拥有的Grp数量相同的选择查询量。

select grp0_.grp_id as grp1_6_0_ from grp grp0_ where grp0_.grp_id=?
select grp0_.grp_id as grp1_6_0_ from grp grp0_ where grp0_.grp_id=?
...

无论如何都要避免这个N选择查询?感谢。

2 个答案:

答案 0 :(得分:0)

是。你可以将获取模式从懒惰改为急切:

Criteria crit = session.createCriteria( Usr.class )
                           .setFetchMode( "usrgrp", FetchMode.JOIN )

其中usrgrp是Usr.class中的一个集合。

答案 1 :(得分:0)

执行这些查询以加载每个提取的grp的{​​{1}}。将ManyToOne从UsrGrp标记为UsrGrp为懒惰,这些查询应该会消失。或者,如果要在同一查询中加载组,可以向查询添加左连接提取:

Grp

您也可以启用batch fetching来减少查询次数。

PS:元音很酷。 UserGroup比UsrGrp

更具可读性