EJB3.0更新然后选择工作不正常jboss5.1.0.G

EJB3.0更新然后选择工作不正常jboss5.1.0.G,jboss,ejb-3.0,Jboss,Ejb 3.0,我遇到了一个非常奇怪的问题。我的问题是 首先,我使用ejb3.0和jboss5.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(

我遇到了一个非常奇怪的问题。我的问题是

首先,我使用
ejb3.0
jboss5.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();
然后我再次选择这样的实体

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
语句,因为我想使用它


有谁能告诉我为什么会发生这种情况以及它的解决方案是什么吗?

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

我将假定您的
管理器
是一个
实体管理器
实例

您正在执行第一个查询,因此
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);
虽然如果你仍然真的需要使用巴赫更新,那么你可以尝试这样做

manager.refresh(s);
在批更新查询之后。这将允许JPA访问数据库,而不是其缓存版本


如果您对第一条SELECT语句进行注释,则该示例会起作用,因为
PersistenceContext
没有缓存您的实体。它是在批量更新查询之后第一次从数据库中获取它。

如果它起作用并回答了您的问题,请随意接受这个答案。