【发布时间】:2012-12-17 22:45:03
【问题描述】:
我的问题是:JPA merge 在无状态 Web 应用程序中是否有过角色?
关于 JPA 中的merge 操作,有很多关于 SO 的讨论。还有一个great article on the subject,它通过更手动的 Do-It-Yourself 流程(您可以通过实体管理器找到实体并进行更改)来对比 JPA 合并。
我的应用程序有一个丰富的域模型(ala 域驱动设计),它使用@Version 注释来利用乐观锁定。我们还创建了 DTO,以作为 RESTful Web 服务的一部分通过网络发送。这个 DTO 层的创建还允许我们向客户端发送它需要的所有东西,而不是它不需要的东西。
到目前为止,我了解这是一个相当典型的架构。我的问题是关于需要更新(即 HTTP PUT)现有对象的服务方法。在这种情况下,我们有这两种方法:1) JPA Merge,和 2) DIY。
我不明白 JPA 合并如何被视为处理更新的选项。这是我的想法,我想知道是否有什么我不明白的:
1) 为了从有线 DTO 正确创建分离的 JPA 实体,必须正确设置版本号...否则会引发 OptimisticLockException。但是 JPA 规范说:
实体可以访问其版本字段或属性的状态,或者 导出一个方法供应用程序使用以访问版本,但是 不得修改版本值[30]。只有持久化提供者 允许设置或更新版本属性的值 对象。
2) 合并不处理双向关系...后向字段总是以 null 结束。
3) 如果 DTO 中缺少任何字段或数据(由于部分更新),则 JPA 合并将删除这些关系或使这些字段无效。 Hibernate 可以处理部分更新,但不能处理 JPA 合并。 DIY 可以处理部分更新。
4) 合并方法首先会在数据库中查询实体 ID,因此与 DIY 相比没有性能优势。
5) 在 DYI 更新中,我们加载实体并根据 DTO 进行更改——没有调用 merge 或 persist 因为 JPA 上下文实现了 unit-of-开箱即用的工作模式。
我有这个直吗?
编辑:
6) 延迟加载关系的合并行为可以differ amongst providers。
【问题讨论】: