0

我在 Java 中获取对象时遇到问题。对象 A 是实体 bean 类,它包含对象 B(其他实体 bean 类)作为字段。对象 A 是在没有 B 的情况下创建的,后来对象 B 通过某些操作附加到 A。
问题是一些用户在对象 A 中看不到对象 B,它看起来像 null。在数据库中一切都很好,一段时间后对象 A 看起来不错(包含 B)。这仅在某些情况下发生,在其他对象中从一开始就看起来不错。
我想说我们使用两个虚拟机来运行应用程序(可能是问题)和 Oracle 应用服务器。
有什么帮助吗?
斯托扬

代码如下:
实体类 A 是这样定义的(B 也是实体类)。

 @Entity
 @Table(name = "A")
 public class A{
     ...
     @ManyToOne
     @JoinColumn(name="ID_B", referencedColumnName="ID")
     private B b;
     ...
 }

A 类的对象是在某个动作中创建的,例如:

public createA_action(){
     A a = new A();
     saveObject(a);
}

其中'saveObject'是一些在数据库中持久化或合并对象的方法。

后来,还有其他方法的调用,像这样:

public addBtoA_action(){
     A a = getA();
     B b = getB();
     a.setB(b);
     saveObject(a);
}

其中 getA() 和 getB() 获取现有对象。

4

2 回答 2

0

好吧,每个 entityManager(休眠中的会话)都有自己的实体内存实例。通常,每个事务有一个 EntityManager,每个 http 请求有一个事务。

因此,如果一个实体实例在给定事务 t1 中加载,然后在另一个事务 t2 中加载,如果您在 t1 中在该实体上设置“a”字段,那么在 t1 之前您将无法看到 t2 中的修改commited * 并在给定实体上调用 EntityManager.refresh() 方法。

* JPA 中的事务隔离级别为 read_commited

于 2013-05-14T21:28:29.580 回答
0

我解决了这个问题。
就像我之前说的,我正在使用两个虚拟机。就像 Gab 之前所说的,每个虚拟机都有自己的缓存。
场景:user1 正在使用虚拟机 1 (VM1),而另一个用户 (user2) 正在使用 VM2,并且他们都看到了创建的对象(在第一次事务之后)。之后 user1 更改对象(第二个事务)。用户 2 将看不到该更改,因为 VM2 的缓存有一个旧对象。
解决方案:我正在使用 NativeQuery 从数据库中获取 id 以及通过 id 获取对象的方法。我将 EntityManager.refresh() 放在从数据库中获取对象的方法中,一切正常。
因此,在更改之前,我使用以下方法从 ids 中获取对象:

public Object getObj(Long id, Class class){
    return em.find(class, id);
}

更改后,此方法如下所示:

public Object getObj(Long id, Class class){
    Object obj = em.find(class, id);
    em.refresh(obj);
    return obj;
}
于 2013-05-16T12:35:35.633 回答