如何在使用 Criteria 时避免休眠与 OneToMany 进行左外连接
How to avoid hibernate from doing left outer join with OneToMany while using Criteria
我有一个请求对象,它具有到 KPI 的 OneToMany 映射(请求有一个 KPI 列表)...现在我需要根据数据(不是数据库约束)使用 criteria 中设置的一些参数来获取某个请求传递的参数应该只有 return 一个 Request 对象,问题是创建的 hibernate 查询已经离开了 KPI 的外部连接,所以如果 Request 内部有 5 个 KPI,5 个重复的行是 returned .. .我只需要一个...我怎样才能实现这个
阅读代码:
Criteria criteria = session.createCriteria(GroupKpiRequest.class);
criteria.add(Restrictions.eq("levelCategory",LevelCategory.COMPANY));
if(cycleNumber == 0){
cycleNumber = getActiveCycleNo();
}
criteria.add(Restrictions.eq("cycleNumber",cycleNumber));
List<GroupKpiRequest> matchingRequests = (List<GroupKpiRequest>)
criteria.list();
if(matchingRequests != null && matchingRequests.size() == 1 ){
GroupKpiRequest companyRequestToDelete =
matchingRequests.get(0);
请求class:
public class GroupKpiRequest {
.
.
.
@OneToMany(mappedBy="groupKpiRequest", cascade={CascadeType.ALL}, fetch=FetchType.LAZY)
@Cascade({
org.hibernate.annotations.CascadeType.SAVE_UPDATE,
org.hibernate.annotations.CascadeType.DELETE,
org.hibernate.annotations.CascadeType.MERGE,
org.hibernate.annotations.CascadeType.PERSIST,
org.hibernate.annotations.CascadeType.DELETE_ORPHAN//,
org.hibernate.annotations.CascadeType.EVICT
})
@OrderBy("groupKpiId")
@Fetch(FetchMode.SUBSELECT)
private List<GroupKPI> kpiSet;
KPI class :
public class GroupKPI implements Serializable{
@OneToOne(fetch=FetchType.EAGER)
@JoinColumn(name="CALCULATION_METHOD",referencedColumnName="METHOD_NAME")
private CalculationMethod calculationMethod;
@ManyToOne
@JoinColumns({
@JoinColumn(name="GRP_KPI_REQ_ID",referencedColumnName="GRP_KPI_REQ_ID" , nullable=false)
}
)
@Fetch(FetchMode.JOIN)
private GroupKpiRequest groupKpiRequest;
查询:
select .....
from
REQUEST this_
left outer join
GROUP_KPI kpiset2_
on this_.GRP_KPI_REQ_ID=kpiset2_.GRP_KPI_REQ_ID
left outer join
CALC_METHOD calculatio3_
on kpiset2_.CALCULATION_METHOD=calculatio3_.METHOD_NAME
left outer join
ORGANIZATION organizati4_
on this_.CYCLE_NO=organizati4_.CYCLE_NO
and this_.ORG_ID=organizati4_.ORG_ID
where
this_.deleted = 0
and this_.GRP_KPI_REQ_ID=?
order by
kpiset2_.GRP_KPI_ID asc
显然你有一个 left outer join
原因
order by
kpiset2_.GRP_KPI_ID asc
kpiSet
字段有@OrderBy("groupKpiId")
注解的顺序原因
要删除重复的行,您可以尝试使用 DISTINCT_ROOT_ENTITY
transformer
Criteria.DISTINCT_ROOT_ENTITY vs Projections.distinct
最好不要使用 @OrderBy
,在我看来,这不是一种非常灵活的方法。
我有一个请求对象,它具有到 KPI 的 OneToMany 映射(请求有一个 KPI 列表)...现在我需要根据数据(不是数据库约束)使用 criteria 中设置的一些参数来获取某个请求传递的参数应该只有 return 一个 Request 对象,问题是创建的 hibernate 查询已经离开了 KPI 的外部连接,所以如果 Request 内部有 5 个 KPI,5 个重复的行是 returned .. .我只需要一个...我怎样才能实现这个
阅读代码:
Criteria criteria = session.createCriteria(GroupKpiRequest.class);
criteria.add(Restrictions.eq("levelCategory",LevelCategory.COMPANY));
if(cycleNumber == 0){
cycleNumber = getActiveCycleNo();
}
criteria.add(Restrictions.eq("cycleNumber",cycleNumber));
List<GroupKpiRequest> matchingRequests = (List<GroupKpiRequest>)
criteria.list();
if(matchingRequests != null && matchingRequests.size() == 1 ){
GroupKpiRequest companyRequestToDelete =
matchingRequests.get(0);
请求class:
public class GroupKpiRequest {
.
.
.
@OneToMany(mappedBy="groupKpiRequest", cascade={CascadeType.ALL}, fetch=FetchType.LAZY)
@Cascade({
org.hibernate.annotations.CascadeType.SAVE_UPDATE,
org.hibernate.annotations.CascadeType.DELETE,
org.hibernate.annotations.CascadeType.MERGE,
org.hibernate.annotations.CascadeType.PERSIST,
org.hibernate.annotations.CascadeType.DELETE_ORPHAN//,
org.hibernate.annotations.CascadeType.EVICT
})
@OrderBy("groupKpiId")
@Fetch(FetchMode.SUBSELECT)
private List<GroupKPI> kpiSet;
KPI class :
public class GroupKPI implements Serializable{
@OneToOne(fetch=FetchType.EAGER)
@JoinColumn(name="CALCULATION_METHOD",referencedColumnName="METHOD_NAME")
private CalculationMethod calculationMethod;
@ManyToOne
@JoinColumns({
@JoinColumn(name="GRP_KPI_REQ_ID",referencedColumnName="GRP_KPI_REQ_ID" , nullable=false)
}
)
@Fetch(FetchMode.JOIN)
private GroupKpiRequest groupKpiRequest;
查询:
select .....
from
REQUEST this_
left outer join
GROUP_KPI kpiset2_
on this_.GRP_KPI_REQ_ID=kpiset2_.GRP_KPI_REQ_ID
left outer join
CALC_METHOD calculatio3_
on kpiset2_.CALCULATION_METHOD=calculatio3_.METHOD_NAME
left outer join
ORGANIZATION organizati4_
on this_.CYCLE_NO=organizati4_.CYCLE_NO
and this_.ORG_ID=organizati4_.ORG_ID
where
this_.deleted = 0
and this_.GRP_KPI_REQ_ID=?
order by
kpiset2_.GRP_KPI_ID asc
显然你有一个 left outer join
原因
order by
kpiset2_.GRP_KPI_ID asc
kpiSet
字段有@OrderBy("groupKpiId")
注解的顺序原因
要删除重复的行,您可以尝试使用 DISTINCT_ROOT_ENTITY
transformer
Criteria.DISTINCT_ROOT_ENTITY vs Projections.distinct
最好不要使用 @OrderBy
,在我看来,这不是一种非常灵活的方法。