带有外连接的休眠 HQL 查询
Posted
技术标签:
【中文标题】带有外连接的休眠 HQL 查询【英文标题】:Hibernate HQL Query with outer join 【发布时间】:2013-01-19 01:53:22 【问题描述】:我想问一下如何将 OUTER 从 Informix 更改为 HQL 查询。当前面临unexpected token:outer
的错误
SQL查询:
select a.SC_OB_PROFILE_CODE, b.SC_ORIG_SF_GROUP_CODE, f.SC_ORIG_SAC,
f.SC_ORIG_FAC,b.SC_PROD_CONT_GROUP_CODE, d.SC_PROD_CONT_CODE, e.GP_CD, a.SC_ORIG_COUNTRY,
a.SC_DEST_COUNTRY, a.SC_DEST_SAC, a.SC_DEST_FAC, a.SC_SEND_DOW,
a.SC_OB_SORT_CODE, a.ORIG_OB_SORT_CODE, a.TARGET_OB_SORT_CODE, a.SC_TIMESTAMP
from SC_OB_TEMP_AUDIT2 a, SC_OB_ALLOCATION b, outer SC_FAC_GROUP f,
outer (SC_OB_PROD_GROUP d, GBL_PRODUCT e)
where a.SC_ORIG_COUNTRY = 'MY'
and a.EXPORT_FLAG = 'N'
and a.SC_OB_PROFILE_CODE = b.SC_OB_PROFILE_CODE
and a.SC_ORIG_COUNTRY = b.SC_ORIG_COUNTRY
and f.SC_ORIG_COUNTRY = b.SC_ORIG_COUNTRY
and b.SC_ORIG_SF_GROUP_CODE = f.SC_FAC_GROUP_CODE
and d.SC_ORIG_COUNTRY = b.SC_ORIG_COUNTRY
and b.SC_PROD_CONT_GROUP_CODE = d.SC_PROD_GROUP_CODE
and e.GP_CNT_CD = d.SC_PROD_CONT_CODE
order by a.SC_TIMESTAMP, a.SC_OB_PROFILE_CODE, a.SC_DEST_COUNTRY
HQL 查询:
@SuppressWarnings("unchecked")
public List<LoginCountryEBean> getExportDetails(String country)
List<LoginCountryEBean> expDel = null;
Query q= em1.createQuery("select a.obProfileCode, b.sfGroupCode, f.orgSac," +
"f.sc_orig_fac,b.contGroupCode, d.prodContCode, e.gpCd, a.origCountry," +
"a.destCountry, a.destSac, a.destFac, a.sendDow, a.obSortCode, " +
"a.origObSortCode, a.targetObSortCode, a.timeStamp from AuditBean a, " +
"AllocationEBean b, **outer** FacGroupEBean f,**outer**(ProdGroupEBean d, glbProductEBean e)" +
"where a.origCountry :country and a.exportFlag = 'N' " +
"and a.obProfileCode = b.profileCode" +
"and a.origCountry = b.orgCountry" +
"and f.orgCountry = b.orgCountry" +
"and b.sfGroupCode = f.facGroupCode" +
"and d.orgCountry = b.orgCountry" +
"and b.contGroupCode = d.prodGroupCode" +
"and e.gpCntCd = d.prodContCode" +
"order by a.timeStamp, a.obProfileCode, a.destCountry");
q.setParameter("country", country);
expDel = q.getResultList();
return expDel;
//
AllocationEBean
package com.dhl.gls.persistence.bean;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="SC_OB_ALLOCATION")
public class AllocationEBean implements Serializable
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@Column(name="sc_orig_country")
private String orgCountry;
@Id
@Column(name="sc_orig_sf_group_code")
private String sfGroupCode;
@Id
@Column(name="sc_prod_cont_group_code")
private String contGroupCode;
@Id
@Column(name="sc_ob_profile_code")
private String profileCode;
public String getOrgCountry()
return orgCountry;
public void setOrgCountry(String orgCountry)
this.orgCountry = orgCountry;
public String getSfGroupCode()
return sfGroupCode;
public void setSfGroupCode(String sfGroupCode)
this.sfGroupCode = sfGroupCode;
public String getContGroupCode()
return contGroupCode;
public void setContGroupCode(String contGroupCode)
this.contGroupCode = contGroupCode;
public String getProfileCode()
return profileCode;
public void setProfileCode(String profileCode)
this.profileCode = profileCode;
//
AuditEBean
package com.dhl.gls.persistence.bean;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="sc_ob_temp_audit2")
public class AuditBean implements Serializable
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@Column(name="audit_Id")
private long auditId;
@Column(name="sc_ob_profile_code")
private String obProfileCode = null;
@Column(name="sc_orig_country")
private String origCountry = null;
@Column(name="sc_dest_country")
private String destCountry = null;
@Column(name="sc_dest_sac")
private String destSac = null;
@Column(name="sc_dest_fac")
private String destFac = null;
@Column(name="sc_send_dow")
private String sendDow = null;
@Column(name="sc_ob_sort_code")
private String obSortCode = null;
@Column(name="orig_ob_sort_code")
private String origObSortCode = null;
@Column(name="target_ob_sort_code")
private String targetObSortCode = null;
@Column(name="usr_id")
private String userId = null;
@Column(name="sc_timestamp")
private Date timeStamp = null;
@Column(name="export_flag")
private String exportFlag = null;
public String getObProfileCode()
return obProfileCode;
public String getOrigCountry()
return origCountry;
public String getDestCountry()
return destCountry;
public String getDestSac()
return destSac;
public String getDestFac()
return destFac;
public String getSendDow()
return sendDow;
public String getObSortCode()
return obSortCode;
public String getOrigObSortCode()
return origObSortCode;
public String getTargetObSortCode()
return targetObSortCode;
public Date getTimeStamp()
return timeStamp;
public String getExportFlag()
return exportFlag;
public void setObProfileCode(String obProfileCode)
this.obProfileCode = obProfileCode;
public void setOrigCountry(String origCountry)
this.origCountry = origCountry;
public void setDestCountry(String destCountry)
this.destCountry = destCountry;
public void setDestSac(String destSac)
this.destSac = destSac;
public void setDestFac(String destFac)
this.destFac = destFac;
public void setSendDow(String sendDow)
this.sendDow = sendDow;
public void setObSortCode(String obSortCode)
this.obSortCode = obSortCode;
public void setOrigObSortCode(String origObSortCode)
this.origObSortCode = origObSortCode;
public void setTargetObSortCode(String targetObSortCode)
this.targetObSortCode = targetObSortCode;
public void setTimeStamp(Date timeStamp)
this.timeStamp = timeStamp;
public void setExportFlag(String exportFlag)
this.exportFlag = exportFlag;
public long getAuditId()
return auditId;
public void setAuditId(long auditId)
this.auditId = auditId;
public String getUserId()
return userId;
public void setUserId(String userId)
this.userId = userId;
//
prodGroupEBean
package com.dhl.gls.persistence.bean;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="SC_OB_PROD_GROUP")
public class ProdGroupEBean implements Serializable
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@Column(name="sc_orig_country")
private String orgCountry;
@Id
@Column(name="sc_prod_cont_code")
private String prodContCode;
@Id
@Column(name="sc_prod_group_code")
private String prodGroupCode;
public String getOrgCountry()
return orgCountry;
public void setOrgCountry(String orgCountry)
this.orgCountry = orgCountry;
public String getProdContCode()
return prodContCode;
public void setProdContCode(String prodContCode)
this.prodContCode = prodContCode;
public String getProdGroupCode()
return prodGroupCode;
public void setProdGroupCode(String prodGroupCode)
this.prodGroupCode = prodGroupCode;
//
FacGroupEBean
package com.dhl.gls.persistence.bean;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="SC_FAC_GROUP")
public class FacGroupEBean implements Serializable
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@Column(name="sc_orig_country")
private String orgCountry;
@Id
@Column(name="sc_orig_sac")
private String orgSac;
@Id
@Column(name="sc_orig_fac")
private String orgFac;
@Id
@Column(name="sc_fac_group_code")
private String facGroupCode;
public String getOrgCountry()
return orgCountry;
public void setOrgCountry(String orgCountry)
this.orgCountry = orgCountry;
public String getOrgSac()
return orgSac;
public void setOrgSac(String orgSac)
this.orgSac = orgSac;
public String getOrgFac()
return orgFac;
public void setOrgFac(String orgFac)
this.orgFac = orgFac;
public String getFacGroupCode()
return facGroupCode;
public void setFacGroupCode(String facGroupCode)
this.facGroupCode = facGroupCode;
//
glsproductionEBean
package com.dhl.gls.persistence.bean;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="GBL_PRODUCT")
public class glbProductEBean implements Serializable
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@Column(name="gp_cd")
private String gpCd;
@Column(name="gp_cnt_cd")
private String gpCntCd;
@Column(name="gp_sort_cd")
private String gpSortCd;
@Column(name="gp_short_nm")
private String gp_short_nm;
@Column(name="hf_lk")
private Long hfkl;
@Column(name="pasdt_cd")
private String pasdtCd;
@Column(name="psd_cd")
private Short psdCd;
@Column(name="gp_geo_markt")
private String gpGeoMarkt;
@Column(name="gp_doc_ndoc_ind")
private String gpDocNdocInd;
public String getGpCd()
return gpCd;
public void setGpCd(String gpCd)
this.gpCd = gpCd;
public String getGpCntCd()
return gpCntCd;
public void setGpCntCd(String gpCntCd)
this.gpCntCd = gpCntCd;
public String getGpSortCd()
return gpSortCd;
public void setGpSortCd(String gpSortCd)
this.gpSortCd = gpSortCd;
public String getGp_short_nm()
return gp_short_nm;
public void setGp_short_nm(String gp_short_nm)
this.gp_short_nm = gp_short_nm;
public Long getHfkl()
return hfkl;
public void setHfkl(Long hfkl)
this.hfkl = hfkl;
public String getPasdtCd()
return pasdtCd;
public void setPasdtCd(String pasdtCd)
this.pasdtCd = pasdtCd;
public Short getPsdCd()
return psdCd;
public void setPsdCd(Short psdCd)
this.psdCd = psdCd;
public String getGpGeoMarkt()
return gpGeoMarkt;
public void setGpGeoMarkt(String gpGeoMarkt)
this.gpGeoMarkt = gpGeoMarkt;
public String getGpDocNdocInd()
return gpDocNdocInd;
public void setGpDocNdocInd(String gpDocNdocInd)
this.gpDocNdocInd = gpDocNdocInd;
【问题讨论】:
【参考方案1】:您遇到的问题是(过时的)旧式 Informix OUTER 连接表示法不被其他系统(例如 HQL)理解。这是原始 Informix 查询的略微简化版本:
select a.*, b.*, d.*, e.*, f.*
from SC_OB_TEMP_AUDIT2 a,
SC_OB_ALLOCATION b,
outer SC_FAC_GROUP f,
outer (SC_OB_PROD_GROUP d, GBL_PRODUCT e)
where a.SC_ORIG_COUNTRY = 'MY'
and a.EXPORT_FLAG = 'N'
and a.SC_OB_PROFILE_CODE = b.SC_OB_PROFILE_CODE
and a.SC_ORIG_COUNTRY = b.SC_ORIG_COUNTRY
and f.SC_ORIG_COUNTRY = b.SC_ORIG_COUNTRY
and b.SC_ORIG_SF_GROUP_CODE = f.SC_FAC_GROUP_CODE
and d.SC_ORIG_COUNTRY = b.SC_ORIG_COUNTRY
and b.SC_PROD_CONT_GROUP_CODE = d.SC_PROD_GROUP_CODE
and e.GP_CNT_CD = d.SC_PROD_CONT_CODE
order by a.SC_TIMESTAMP, a.SC_OB_PROFILE_CODE, a.SC_DEST_COUNTRY;
首先,我通过使用a.*
表示法从每个别名表名中选择列来简化选择列表,并且更清楚地公开了 FROM 子句的内容。
a
和 b
表(带有别名 - 但我将假装别名是表名)是内连接的。即外连接到f
;它也独立地外连接到d
的结果,外连接到e
。为了重写它以便 HQL 有机会理解它,我们将不得不写一些接近这个的东西:
SELECT a.*, b.*, d.*, ef.*
FROM sc_ob_temp_audit2 AS a
JOIN sc_ob_allocation AS b
ON a.sc_ob_profile_code = b.sc_ob_profile_code
AND a.sc_orig_country = b.sc_ob_orig_country
OUTER JOIN sc_fac_group AS f
ON b.sc_orig_country = f.sc_orig_country
AND b.sc_orig_sf_group_code = f.sc_fac_group_code
OUTER JOIN (SELECT e.*, f.*
FROM sc_ob_prod_group AS d
OUTER JOIN gbl_produce AS e
ON d.sc_prod_cont_code = e. gp_cnt_cd
) AS ef.*
ON b.sc_orig_country = ef.sc_orig_country
AND b.sc_prod_cont_group_code = ef.sc_prod_group_code
WHERE a.sc_orig_country = 'MY'
AND a.export_flag = 'N'
ORDER BY a.sc_timestamp, a.sc_ob_profile_code, a.sc_dest_country;
除了反转关键字与数据库对象的大小写之外,这是对原始查询的相当直接的翻译。您会注意到,在此版本中,外部连接的子查询被赋予了别名ef
。这是必要的; SQL 标准要求为此类子查询指定别名。因此,您可能会遇到模棱两可的列错误。您可以通过将子查询中的 *
表示法替换为您要选择的确切列名集来解决这些问题。当然,您需要再次将选择列表中的 *
符号替换为您想要的列集。
【讨论】:
感谢@Jonathan Leffler,代码在将 * 替换为列名后有效。【参考方案2】:连接的语法是
select ... from Entity1 e1
[inner | left [outer]] join e1.entity2s e2
[inner | left [outer]] join e2.entity3s e3
...
阅读the documentation
【讨论】:
以上是关于带有外连接的休眠 HQL 查询的主要内容,如果未能解决你的问题,请参考以下文章