Java 选择具有复合主键的查询
在使用hibernate和jpa的spring mvc应用程序中,我最近使用了一个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
@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
子句并检查错误是否仍然存在。第二,在这里也放一个概念
类,我认为查看它的映射可能有助于解决您的问题。第三,不要这么咄咄逼人。我在另一个冬眠问题上悬赏。你愿意帮我吗?以下是链接: