我遇到了一个非常奇怪的问题。我的问题是这
首先,我使用EJB 3.0和jboss 5.1.0.GA从数据库中选择实体
Subscriber s = (Subscriber)manager.createQuery("SELECT s FROM Subscriber s " +
"WHERE s.subscriber_id = ?1").setParameter(1,123).getSingleResult();然后,我使用如下查询对实体进行更新
int a = manager.createQuery(" UPDATE Subscriber s SET s.balance = s.balance + "+10+"WHERE s.subscriber_id = ?1").setParameter(1,123).executeUpdate();然后,我像这样选择实体
s = (Subscriber)manager.createQuery("SELECT s FROM Subscriber s " +
"WHERE s.subscriber_id = ?1").setParameter(1,123).getSingleResult();但是我没有得到"balance“字段的更新值,但是一旦我注释了第一个SELECT语句,我就得到了更新值。但无论如何我都需要第一个SELECT语句,因为我想使用它。
谁能告诉我为什么会发生这种情况,它的解决方案是什么?
发布于 2011-11-21 19:23:38
我敢打赌,这是因为缓存问题。
我将假设您的manager是一个EntityManager实例。
您正在执行第一个查询,因此PersistenceContext将从数据库获取Subscriber实体并将其放入缓存中。然后,您将执行批量更新查询,该查询直接命中数据库,省略了缓存结构,因此它不会影响PersistenceContext。
最后,再次执行SELECT查询。这样做,PersistenceContext会检查它是否在某个地方缓存了Subscribe实体。它是这样做的,所以它不会命中数据库,而是返回存储在其缓存中的值。
我不太明白为什么要执行JPA query,而不是只更新对象状态,并在适当的时候让提交更改。
因此,不是:
int a = manager.createQuery("UPDATE Subscriber s SET s.balance = s.balance +
"+10+"WHERE s.subscriber_id = ?1")
.setParameter(1,123).executeUpdate();你可以这样做:
// 's' is the Subscribe entity previously fetched from the database
s.setBalance(s.getBalance() + 10);不过,如果您仍然需要来使用bach更新,那么您可以尝试这样做
manager.refresh(s);在批量更新查询之后。这将允许JPA访问数据库,而不是它的缓存版本。
如果您注释第一个SELECT语句,则该示例可以工作,因为PersistenceContext没有缓存您的实体。它在批量更新查询之后第一次从数据库中获取它。
https://stackoverflow.com/questions/8210471
复制相似问题