本地查询(JPA)未重置并返回相同的旧结果。

8

我有一个原生的 SQL 查询,如下:

for (init i=0; i<=2 ; i++) {
    String sql = "Select * from accounts where id = ?"; 
    Query query = em.createNativeQuery(sql,AccountBean.class); 
    query.setParameter(1, i ); 

    AccountBean accountBean = (AccountBean)query.getSingleResult(); 
} 

第一次循环正常工作,但是第一个之后的循环返回与第一个相同的结果,我进行了调试,参数已更改,如果我更改它,它就可以正常工作。

Query query = em.createNativeQuery(sql,AccountBean.class); 

to

Query query = em.createNativeQuery(queryString); 

问候,Wish79

1个回答

5
每个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):

/**
 * The persistent class for the SOME_TABLE database table.
 */
@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;
    }
    ...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接