我的问题非常奇怪。我的问题是这个
首先使用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();
但是当我评论第一个SELECT
语句我得到更新的值时,我没有得到“balance”字段的更新值。但在任何情况下我都需要第一个SELECT
语句,因为我想使用它。
任何人都可以告诉我它为什么会发生以及它的解决方案是什么?
答案 0 :(得分:1)
我敢打赌这是因为缓存问题。
我将假设您的manager
是EntityManager
个实例。
您正在执行第一个查询,因此PersistenceContext
从数据库中获取Subscriber
实体并将其放入缓存中。然后,您正在执行批量更新查询,该查询直接命中数据库而忽略缓存结构,因此它不会影响PersistenceContext。
最后,再次执行SELECT查询。这样做,PersistenceContext
检查它是否在某处缓存了Subscribe
个实体。它确实如此,因此它不会命中数据库,而是返回存储在其缓存中的值。
我不明白为什么你要执行批量更新查询,而不是仅仅更新对象状态并让JPA在适当的时候提交更改。
所以而不是:
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 UPDATE那么你可以尝试
manager.refresh(s);
批量UPDATE查询后。这将让JPA访问数据库而不是其缓存版本。
如果您对第一个SELECT语句发表评论,则该示例有效,因为PersistenceContext
未缓存您的实体。它在批量UPDATE查询之后第一次从数据库中获取它。