JPQL查询未返回预期结果

时间:2014-05-06 18:03:21

标签: java sql spring spring-mvc jpa

以下JPQL查询未返回结果。如何更改它以便返回预期的结果?

@SuppressWarnings("unchecked")
public Collection<Description> findDescriptionsForConcept(Concept conc) {
    System.out.println("in JpaSnomedRepository(), conc.getConceptPk().getId() is: "+conc.getConceptPk().getId());;
    Query query = this.em.createQuery("SELECT descr FROM Description descr WHERE descr.concept =:cid");
    query.setParameter("cid", conc);
    return query.getResultList();
}

注意:解决方案是更改描述类中manytoone关系中某个joincolumns的名称。但我将下面的答案之一标记为已接受,因为此人投入了大量资金时间试图帮助我。

2 个答案:

答案 0 :(得分:2)

hibernate生成的查询很好。让我们一步一步地分析。

  • 我们有一个 SnomedDescription 实体,它有一个由两个组成的复杂密钥 列: id effectiveTime
  • SnomedDescription 实体与另一个名为SnomedConcept的实体有@ManyTwoOne关系。
  • SnomedConcept 还有一个复杂的密钥。从您的问题我们不确定它是由哪些列组成的,但是从@ManyTwoOne关系定义我们可以假设它也是 id effectiveTime 。这实际上是奇怪的,因为这意味着@OneToOne关系应该更合适,就像@Alex Malev建议的那样(或者映射定义不正确)。基本上我们不能有两个具有相同id和effectiveTime的SnomedDescriptions,因此一次最多只有一个SnomedDescription与一个SnomedConcept相关联。
  • 为什么生成的查询正常?因为

    DESCRIPTION.CONCEPT.CONCEPTPK.ID = DESCRIPTION.ID

    这就是定义关系的方式!

  • 如果JPQL类似于"SELECT descr FROM SnomedDescription descr WHERE descr.concept = :concept",则生成的查询将有两个约束: id effectiveTime 并且最多匹配一行

  • 如果您仍想使用@ManyToOne关系,我相信只需删除第二个@JoinColumn - name =“effectiveTime” - 就可以了。

答案 1 :(得分:1)

尝试稍微更改方法,将id设置为参数,而不是整个Concept

此代码假定您的SnomedDescription课程类似于private Concept concept

Query query = this.em.createQuery("SELECT descr FROM SnomedDescription descr WHERE descr.concept.conceptPk.id =:cid");
query.setParameter("cid", conc.getConceptPk().getId());

还有一件事对我来说很可疑 - ConceptDescription与一对多关系绑定。考虑修改,您可能希望Concept只有一个Description