EJB 3.0 Update然后选择jboss5.1.0.G无法正常工作

时间:2011-11-21 10:39:15

标签: jboss ejb-3.0

我的问题非常奇怪。我的问题是这个

首先使用EJB 3.0jboss 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语句,因为我想使用它。

任何人都可以告诉我它为什么会发生以及它的解决方案是什么?

1 个答案:

答案 0 :(得分:1)

我敢打赌这是因为缓存问题。

我将假设您的managerEntityManager个实例。

您正在执行第一个查询,因此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查询之后第一次从数据库中获取它。