Java 选择具有复合主键的查询

Java 选择具有复合主键的查询,java,sql,hibernate,jpa,Java,Sql,Hibernate,Jpa,在使用hibernate和jpa的spring mvc应用程序中,我最近使用了一个@embeddedable类切换到一个复合主键。因此,我需要更新JPA查询,该查询根据给定对象的唯一id返回给定对象。以下是过去工作但不再返回结果的JPA代码: @SuppressWarnings("unchecked") public Concept findConceptById(BigInteger id) { Query query = this.em.createQuery("SELECT con

在使用hibernate和jpa的spring mvc应用程序中,我最近使用了一个
@embeddedable
类切换到一个复合主键。因此,我需要更新JPA查询,该查询根据给定对象的唯一id返回给定对象。以下是过去工作但不再返回结果的JPA代码:

@SuppressWarnings("unchecked")
public Concept findConceptById(BigInteger id) {
    Query query = this.em.createQuery("SELECT conc FROM Concept conc WHERE conc.id =:cid");
    query.setParameter("cid", id);
    return (Concept) query.getSingleResult();
}
如何更改上述查询,使其返回给定
id
的最新
effectiveTime
概念?
请注意
id
effectiveTime
ConceptPK
复合主键的两个属性,因此,
id
effectiveTime
的属性定义、getter和setter在
ConceptPK
类中,而不是在
Concept
类中

上述操作引发的错误是:

Caused by: java.lang.IllegalArgumentException:  
Parameter value [786787679] did not match expected type [myapp.ConceptPK]  
这就是主键现在在
概念
类中的定义方式:

private ConceptPK conceptPK;  
@Embeddable
class ConceptPK implements Serializable {

    @Column(name="id", nullable=false)
    protected BigInteger id;

    @Column(name="effectiveTime", nullable=false)
    @Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime")
    private DateTime effectiveTime;

    public ConceptPK() {}
    public ConceptPK(BigInteger bint, DateTime dt) {
        this.id = bint;
        this.effectiveTime = dt;
    }

    /** getters and setters **/
    public DateTime getEffectiveTime(){return effectiveTime;}
    public void setEffectiveTime(DateTime ad){effectiveTime=ad;}

    public void setId(BigInteger id) {this.id = id;}
    public BigInteger getId() {return id;}

    @Override
    public boolean equals(Object obj) { 
        if (this == obj) return true;
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;
        final ConceptPK other = (ConceptPK) obj;
        if (effectiveTime == null) {
            if (other.effectiveTime != null) return false;
            } else if (!effectiveTime.equals(other.effectiveTime)) return false;
        if (id == null) {
            if (other.id != null) return false;
        } else if (!id.equals(other.id)) return false;
        return true;
    }

    @Override
    public int hashCode() { 
        int hash = 3;
        hash = 53 * hash + ((effectiveTime == null) ? 0 : effectiveTime.hashCode());
        hash = 53 * hash + ((id == null) ? 0 : id.hashCode());
        return hash;
    }
}
下面是
ConceptPK
类的代码:

private ConceptPK conceptPK;  
@Embeddable
class ConceptPK implements Serializable {

    @Column(name="id", nullable=false)
    protected BigInteger id;

    @Column(name="effectiveTime", nullable=false)
    @Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime")
    private DateTime effectiveTime;

    public ConceptPK() {}
    public ConceptPK(BigInteger bint, DateTime dt) {
        this.id = bint;
        this.effectiveTime = dt;
    }

    /** getters and setters **/
    public DateTime getEffectiveTime(){return effectiveTime;}
    public void setEffectiveTime(DateTime ad){effectiveTime=ad;}

    public void setId(BigInteger id) {this.id = id;}
    public BigInteger getId() {return id;}

    @Override
    public boolean equals(Object obj) { 
        if (this == obj) return true;
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;
        final ConceptPK other = (ConceptPK) obj;
        if (effectiveTime == null) {
            if (other.effectiveTime != null) return false;
            } else if (!effectiveTime.equals(other.effectiveTime)) return false;
        if (id == null) {
            if (other.id != null) return false;
        } else if (!id.equals(other.id)) return false;
        return true;
    }

    @Override
    public int hashCode() { 
        int hash = 3;
        hash = 53 * hash + ((effectiveTime == null) ? 0 : effectiveTime.hashCode());
        hash = 53 * hash + ((id == null) ? 0 : id.hashCode());
        return hash;
    }
}
请试试这个

@SuppressWarnings("unchecked")
public Concept findConceptById(BigInteger id) {
    Query query = this.em.createQuery("from Concept conc WHERE conc.conceptPK.id = :cid order by conc.conceptPK.effectiveTime desc");
    query.setParameter("cid", id);
    return (Concept) query.getSingleResult();
}

确保conceptPK在Concept类中有getter和setter方法。

要在JPA查询中使用复合主键的部分,必须使用其变量名对其进行寻址:

public Concept findConceptById(BigInteger id) {
    Query query = this.em.createQuery("SELECT conc FROM Concept conc WHERE conc.conceptPK.id =:cid order by conc.conceptPK.effectiveTime desc");
    query.setParameter("cid", id);
    return (Concept) query.getSingleResult();
}
我使用
Concept
作为实体名称,假设带有
@entity
注释的类也被命名为
Concept


包含类似问题的信息,您可能会发现它是有用的。

我认为您应该考虑查询<代码>从概念CONC中选择CONC,其中C.ID.ID=:CID顺序由C.I.ActudieTimeDISC/代码>得到它的<代码> UNIGRESULTULT()/代码>。您是否看到我需要创建一个
conceptPK
?在上面的代码中,
effectiveTime
不能为空?因此,我不知道如何在不做一些更改的情况下获得最新的
有效时间。在上面的查询函数中,
id
是一个大整数,而不是主键。为什么需要创建
conceptPK
?哪里它的字段不可为空,是的,但我看不出这与问题和我之前的评论有什么关系。关于
Concept
类-我假设它在名为
id
的字段中有
ConceptPK
。如果不是-只需重命名我上面查询中两个点之间的
id
。@AlexeyMalev我尝试了你的代码,得到了以下新错误:
,原因是:org.hibernate.hql.internal.ast.QuerySyntaxException:Concept未映射[SELECT conc FROM Concept conc其中conc.conceptPK.id=:cid order by conc.conceptPK.effectiveTime desc]
。您有什么建议?首先-删除
orderby
子句并检查错误是否仍然存在。第二,在这里也放一个
概念
类,我认为查看它的映射可能有助于解决您的问题。第三,不要这么咄咄逼人。我在另一个冬眠问题上悬赏。你愿意帮我吗?以下是链接: