【发布时间】:2018-06-26 02:09:40
【问题描述】:
我有两个表,其中一个是 ESERVICE,另一个是 WORKFLOW,eservice 有一个工作流 id 作为外键。并非所有电子服务都有工作流,所以我想在存在时获取工作流名称,否则对我来说是空值或空值。
所以我写了如下的sql,这对我来说很好。 (用oracle测试)
SELECT e.EE_ESERVICE_ID,
CASE
WHEN EXISTS
(SELECT 1
FROM WORKFLOWS w
WHERE w.WORKFLOW_ID = e.WORKFLOW_ID)
THEN
(SELECT i.I18ND_TRANSLATION
FROM WORKFLOWS w, I18N_DICTIONARY i
WHERE WORKFLOW_ID = e.WORKFLOW_ID
AND i.I18N_ID = w.WORKFLOW_NAME
AND i.I18N_LOCALE_ID = 1)
ELSE
COALESCE ('', '')
END
AS WORKFLOW_NAME
FROM ESERVICES e
现在我需要把它转换成hql所以我写成
StringBuffer hql = new StringBuffer("select e.eserviceId as eserviceId,"
+ " (case when exists(select 1 from Workflow w where w.workflowId = e.workflowId)"
+ " then (select i.i18ndTranslation from Workflow w,I18nDictionary i where w.workflowId = e.workflowId and i.i18nId = w.workflowName and i.i18nLocaleId = :localeId)"
+ " else coalesce('', '') end) as workflowName"
+ " from Eservice as e");
但是当我使用它时,我得到 org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected AST node
我知道我们可以直接从左连接实现它,但由于一些限制,我们使用交叉连接,所以我需要这样做......
请分享您的想法,欢迎提出建议
更新 1 我们没有使用关联,这就是我们严格交叉连接的原因。
Eservice.java
@Entity
@Table(name = "ESERVICES")
public class Eservice implements java.io.Serializable {
private static final long serialVersionUID = -4088905661029802626L;
public Eservice() {}
@Id
@SequenceGenerator(name = "escSequence", sequenceName = "SQ_ESERVICES",allocationSize=1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "escSequence")
@Column(name = "EE_ESERVICE_ID", unique = true, nullable = false)
private BigDecimal eserviceId;
@Column(name = "WORKFLOW_ID")
private BigDecimal workflowId;
@Transient
private String workflowName;
// setter and getter
}
工作流.java
@Entity
@Table(name = "WORKFLOWS")
public class Workflow implements java.io.Serializable {
private static final long serialVersionUID = -4863237070153860617L;
public Workflow() {}
@Id
@SequenceGenerator(name = "wfSequence", sequenceName="SQ_WORKFLOWS", allocationSize=1)
@GeneratedValue(strategy=GenerationType.SEQUENCE , generator = "wfSequence")
@Column(name = "WORKFLOW_ID", unique = true, nullable = false)
private BigDecimal workflowId;
@Column(name = "I18N_WORKFLOW_NAME")
private BigDecimal workflowName;
// setter and getter
}
I18nDictionary.java
@Entity
@Table(name="I18N_DICTIONARY")
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
public class I18nDictionary implements Serializable{
/**
* The serialization runtime associates with each serializable class a version number called serialVersionUID.
*/
private static final long serialVersionUID = -2587075034303056842L;
@Id
@SequenceGenerator(name = "seqDictGenerator", sequenceName = "SQ_I18N_DICTIONARY",allocationSize=1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seqDictGenerator")
@Column(name="I18N_DICT_ID", unique = true, nullable = false)
private BigDecimal i18nDictId;
@Column(name="I18N_ID")
private BigDecimal i18nId;
@Column(name="I18ND_TRANSLATION")
private String i18ndTranslation;
@Column(name="I18N_LOCALE_ID")
private BigDecimal i18nLocaleId;
// setter and getter
}
EserviceHibDAO.java
Query query = getSession()
.createQuery(hql.toString().trim())
.setBigDecimal("localeId", i18nLocale.getI18nLocaleId())
.setResultTransformer(Transformers.aliasToBean(Eservice.class));
List<Eservice> resultSet = query.list();
【问题讨论】:
-
查询似乎正在使用 oracle 特定的方法,如合并。我猜 HQL 不支持 DB 特定方法
-
但我昨天在搜索,然后我从这个答案中得到了这个stackoverflow.com/questions/601615/how-to-simulate-nvl-in-hql,很多人都在使用它。
-
能否分享实体代码
-
为什么Eservice有workflowId但它的表(WORKFLOWS)中不存在?
-
为什么你说它在工作流表中不存在它存在....但是我们没有使用关联,所以我们没有在电子服务实体中创建工作流对象