每个JPA实体都必须有一个主键。如果您的JPA实体不能正确地反映数据库表上的主键(如果有的话),则可能会出现问题。
我也遇到了同样的问题。在我的模型类中,我只有一个用@Id注释的类变量。然而,这并不是表本身的准确反映,因为它有一个复合主键。因此,我的查询结果返回了正确数量的行,但每一行都包含相同的值,尽管实际数据在数据库中是不同的。例如,这个查询:
Query query = entityManager.createQuery
("SELECT tbl FROM Tbl tbl WHERE tbl.id = 100
and tbl.code in ('A','B','C')");
...返回了10行数据,每行都显示一个代码为"A"的code。但实际上,这10行中有9行具有不同的code值("B"或"C")。似乎结果被缓存和/或tbl.code谓词被忽略了。(无论我是使用JPQL还是本地SQL,情况都是如此。)非常令人困惑。
为了解决这个问题,我在我的模型中添加了一个额外的@Id注释来反映复合主键:
@Id
@Column(name = "Code")
public String getCode() {
return this.code;
}
现在查询已经正确返回数据,
code选择条件不再被忽略。
编辑:虽然上述方法对我有效,但进一步研究表明,最好的方法是配置一个单独的JPA Entity组合主键类。请参见http://docs.oracle.com/cd/E16439_01/doc.1013/e13981/cmp30cfg001.htm。
例如,这是一个具有嵌入式主键的实体类(请参见@EmbeddedId):
@Entity
@Table(name = "SOME_TABLE")
public class SomeTable implements Serializable {
@EmbeddedId
private SomeTablePk id;
@Column(name = "NUMBER_HRS")
private BigDecimal numberHrs;
...
以下是复合主键类(请参见@Embeddable):
@Embeddable
public class SomeTablePk implements Serializable {
@Column(name = "SOME_ID")
private String someId;
@Column(name = "ANOTHER_ID")
private BigDecimal anotherId;
public String getSomeId() {
return someId;
}
...