手动设置实体的 ID

Setting an entity's ID manually

我遇到了一个我无法理解的小问题。 使用这段代码:

IEntity myEntity = controller.entityFactory.createEntityInstance(MyEntity.class)
myEntity.straightSetProperty(IEntity.ID, "anId")
myEntity.setReferenceProperty(someReference)

我收到 "UOW bad usage" 错误

BAD SESSION USAGE You are modifying an entity ()[MyEntity] that has not been previously merged in the session. You should 1st merge your entities in the session by using the backendController.merge(...) method. The property being modified is [referenceProperty].

但是换线的时候没问题

IEntity myEntity = controller.entityFactory.createEntityInstance(MyEntity.class)
myEntity.setReferenceProperty(someReference)
myEntity.straightSetProperty(IEntity.ID, "anId")

知道我为什么会遇到这个问题吗?

Jspresso 根据实体的 id 计算实体的 hashcode。这个哈希码被 Jspresso 内部间接使用,通过在 Hash[Map|Set].

中使用它来执行一些控制和其他操作

这就是为什么它是强制性的:

  1. 一旦实体实例被创建并且在对实体执行任何setter或操作之前分配id。
  2. id 在实体的生命周期内不会改变。

当你打电话时:

IEntity myEntity = entityFactory.createEntityInstance(MyEntity.class)

生成的 ID 已分配给实体。

在场景 1 中,您首先更改 id(这会破坏哈希码),然后调用 setter。 Jspresso 认为这个实体没有被正确注册,因为它无法从内部的、基于哈希码的存储中检索它的 id。

在场景 2 中,同样的违规行为,但您在 更改 ID 之前调用了 setter 。但是我想如果你之后调用另一个 setter,它也会以同样的方式失败。

解决方案是使用 entityFactory 创建方法的另一个签名,允许将 id 作为参数传递,例如

IEntity myEntity = entityFactory.createEntityInstance(MyEntity.class, "anId")
myEntity.setReferenceProperty(someReference)

这会立即将您的 ID 分配给实体,然后执行所有必要的操作。