如何复制一个实体及其所有属性和集合

How to duplicate an entity with all of its properties and collections

标准 Jspresso 操作 cloneEntityCollectionFrontAction 允许复制 table 中的选定行。 复制仅限于当前模型,如果存在则不考虑集合(即:集合不会自动复制)

如何深度复制实体及其所有集合?

第二个相关问题:为了实现集合的复制,我尝试自己写了一个action。下面是我写的动作的一部分:

Offer newOffer = bc.getEntityFactory().createEntityInstance(Offer.class);
Offer clonedNewOffer = bc.cloneInUnitOfWork(newOffer);

clonedNewOffer.setCustomer(curOf.getCustomer());
clonedNewOffer.setEndApplicationDate(curOf.getEndApplicationDate());
clonedNewOffer.setName(curOf.getName());
clonedNewOffer.setStartApplicationDate(curOf.getStartApplicationDate());

我为每个 属性 调用了 getter 和 setter 这并不令人满意,因为如果我向模型添加新的 属性 或集合,该方法必须是手动更新。

有没有办法写出更聪明/灵活的方法?

嗨,文森特, 关于您的回答和您的最新建议,我将后端更改为以下:

Offer newOffer = bc.getEntityFactory().createEntityInstance(Offer.class);
Offer clonedNewOffer = bc.cloneInUnitOfWork(newOffer);

CarbonEntityCloneFactory.carbonCopyComponent(curOf, clonedNewOffer, bc.getEntityFactory());

bc.registerForUpdate(clonedNewOffer);

但是 registerForUpdate 由于 Data constraints are not satisfied 错误而失败。

我检查了 clonedNewOffer 的 Id 属性,该 Id 已经与 curOf Id 属性 相同。 我理解 "carbon copy" 的含义,它是所有属性的严格副本,因此,从后端,

如何复制一个实体以创建一个新实体?

CloneComponentCollectionActionCloneComponentAction 都使用实现 IEntityCloneFactory 的可配置策略执行实际的组件和实体克隆。 Jspresso 提供了这个接口的 3 个实现:

  • CarbonEntityCloneFactory 处理标量可克隆属性但忽略所有关系。它几乎从未被应用程序代码直接使用。
  • SmartEntityCloneFactory 继承自 CarbonEntityCloneFactory 并按以下方式处理关系:
    • 如果引用是组合,则克隆它们或将相同的引用分配给克隆。
    • 将克隆的组件添加到与原始组件相同的集合中。
  • HibernateAwareSmartEntityCloneFactory 继承自 SmartEntityCloneFactory 并处理惰性初始化属性。如果您使用 Hibernate 后端,这是默认使用的实现。

根据经验,您可以期望 SmartEntityCloneFactory 执行您对引用的期望,但忽略依赖集合以避免太深的递归克隆;所以你所经历的是每个设计。如果您觉得还有改进的余地,请随时在 Jspresso GitHub 上提出功能请求。考虑一下,我们也许可以在依赖组合的集合上做得更好。

如果您想处理比 SmartEntityCloneFactory(或 HibernateSmartEntityCloneFactory)提供的更深的克隆,方法是创建您自己的克隆策略。当然你也可以继承默认策略,通过调用super实现重写cloneEntity方法完成克隆,具体处理你要克隆的集合

实施您的策略后,只需通过替换默认策略将其全局注入应用程序即可,即:

bean('smartEntityCloneFactory', class: 'your.CustomEntityCloneFactory',
     parent: 'smartEntityCloneFactoryBase')

或者通过在操作中注入自定义策略来专门针对应用程序的克隆操作之一,例如:

bean('myCustomEntityCloneFactory', class: 'your.CustomEntityCloneFactory',
     parent: 'smartEntityCloneFactoryBase')

action('customCloneAction', parent: 'cloneEntityCollectionFrontAction',
       custom:[entityCloneFactory_ref: 'myCustomEntityCloneFactory']
)

关于你的第二个相关问题,如果你在你的实体克隆工厂实现中(或有权访问它的一个实例)并且想要使用该策略克隆一个实体或组件,只需调用 cloneComponentcloneEntity 方法。
如果您只想复制克隆上实体或组件的所有标量属性并且无权访问克隆工厂,则可以使用以下静态实用程序方法:

CarbonEntityCloneFactory.carbonCopyComponent(IComponent, IComponent, IEntityFactory)

使用上述方法将解决您的实施健壮性问题。