具有复合主键的SELECT查询

Cod*_*Med 3 java sql hibernate jpa

在使用hibernate和jpa的spring mvc应用程序中,我最近使用@Embeddable类切换到了复合主键。结果,我需要更新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();
}
Run Code Online (Sandbox Code Playgroud)

如何更改上面的查询,以便它返回effectiveTime给定值的最新的Concept id 注意,ideffectiveTime是的两个属性ConceptPK 复合主键,并且从而为属性定义和getter和setter ideffectiveTime是在ConceptPK类,而不是在Concept类。

上面抛出的错误是:

Caused by: java.lang.IllegalArgumentException:  
Parameter value [786787679] did not match expected type [myapp.ConceptPK]  
Run Code Online (Sandbox Code Playgroud)

这是现在在Concept类中定义主键的方式:

private ConceptPK conceptPK;  
Run Code Online (Sandbox Code Playgroud)

这是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;
    }
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*lev 5

要在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();
}
Run Code Online (Sandbox Code Playgroud)

Concept假设带有@Entity注释的类也命名为,我用作实体名称Concept

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