3

我遇到了集成在 Play Framework 2.0.4 中的 Ebean 2.7.3 的问题。

让我先解释一下它在框架中是如何工作的。当我想创建一个新对象时,我调用一个函数,该函数创建模型对象的新实例并将其发送到 Web 表单。提交表单后,将调用 save() 函数。此函数绑定表单中的值并将它们分配给模型对象的另一个新实例。然后它在对象上调用 update() 函数,并且所有内容都正确写入数据库。当我想更新一个对象时,方式几乎相同,只是有一些小区别。一开始,对象从数据库中加载,发送到表单,然后解析回来。不同之处在于,我也在解析更新对象的原始主键。然后,当我调用 update() 函数时,所有内容都正确写入,因为 ebean 知道主 ID,因此可以更新正确的对象。

问题开始了,当我添加一个@Embedded模型的属性。我能够创建新对象,保存它,读取它,但我无法更新它。当我尝试使用与我描述的相同的原理更新对象时,我遇到了 OptimisticLockException。当我调查 SQL 日志时,我发现 Ebean 正在使用 SQL 的 SET 部分中的所有模型属性以及 WHERE 子句中的所有属性进行更新。我知道这与 Ebean 文档中描述的乐观锁定机制有关。问题是 Ebean 在两个部分(SET 和 WHERE)中使用相同的值。似乎 Ebean 无法查找原始实体,因此无法使用 WHERE 部分中的旧值。因此,数据库中的对应实体永远不会被发现,也永远不会更新,返回一个 OptimistickLockException。@Version注解。所以我创建了一个名为 updatedStamp 的新属性,并用@Version. 使用这个原理,我在调用 update() 时遇到了 NullPointerException。

Caused by: java.lang.NullPointerException: null
com.avaje.ebeaninternal.server.core.PersistRequestBean.hasChanged(PersistRequestBean.java:728)

所以我的问题是.. 有没有@Embedded在模型中使用属性的正确方法?我知道这在以前的 Ebean 版本中已经讨论过,但似乎没有可用的解决方案。

嗯..实际上我找到了一种方法来做到这一点。当我从 db 加载一个对象并保留这个类实例时,我可以更改它的属性并毫无问题地调用 update()。但实际上这对我来说不是一个解决方案,因为播放框架是无状态的,所以我无法在会话期间保留原始对象。我必须创建一个新的,用值填充它并保存它。没有@Embedded,这可以正常工作。

关于如何解决的任何线索?

4

0 回答 0