0

为什么打开一个未实例化的(实体)对象列表会恢复对同一事务中任何一个所述对象所做的更改?

设想:

  • A、B 和 C 都是实体
  • A 持有对 B 的特定实例的引用,可通过 a.getB() 检索;
  • C 有一个 B 对象的列表,可通过 c.getListOfB() 检索
  • 以下是正确的: c.getListOfB().contains(a.getB())
  • 以下内容也已经过测试:a.getB() == c.getListOfB().get(properIndex) (相同的对象引用)

如果我在交易中执行以下操作:

B b = a.getB();    
b.setOk(true); // <-- Changed from false to true

然后跟随:

c.getListOfB().isEmpty() // <-- Any function will do, I just used .isEmpty() to test it

然后 b 立即将 OK 值再次设置为 false :/

这发生在同一个事务中,在提交到数据库之前。

有人可以向我解释为什么 EntityManager 不知道事务中对上述实体所做的更改,以及如何确保它保留它们?这导致我进行了长时间的错误搜索,我对如何在网上找到任何有用的结果一无所知。

编辑:问题是当我使用 .isEmpty() 方法实例化 List 时,JPA“再次”从数据库中读取子对象,恢复我在事务早期对其一个子对象所做的更改。我觉得它应该知道其中一个子对象已经在持久性上下文中并且没有被弄乱。

我目前正在通过调用c.getListOfB().isEmpty() 来解决这个问题,即在对b 进行更改之前实例化列表,但这几乎不是一个令人满意的解决方案,更不用说对问题的解释了。

4

2 回答 2

0

使变量静态,以便使用相同的实例。

于 2013-08-26T03:12:57.783 回答
0

a.getB() == c.getListOfB().get(properIndex) 不正确。

在比较两个对象时,请使用 equals() 方法而不是“==”

== 将比较对象引用。

equals() 比较对象属性。

在您的情况下,您需要比较该对象的主键,它是实体对象的一个​​属性。

以下是正确的: c.getListOfB().contains(a.getB())

以下也是正确的:a.getB().equals(c.getListOfB().get(properIndex))

不确定休眠在调用 a.getB() 和 c.getListOfB().get(properIndex) 时是否会返回相同的引用实例,因此在比较两个对象属性时不要使用 ==

于 2013-08-26T04:10:20.060 回答