使用JPA更新的最佳方法 [英] best approach for updation using JPA
问题描述
使用JPA更新时应该遵循哪种方法?
Using JPA which method should I follow while updating?
方法1
obj o = new obj()
o.setName('val')
set other values
entitymanger.merge(ibj)
方法2
obj o = getObjFromDb(obj)
obj.setval(name)
//not am not updating other attributes
entitymanage.merge(obj)
推荐答案
您确实需要了解merge
操作的语义,因此我将重复JPA规范中所说的内容:
You really need to understand the semantics of the merge
operation so I'll repeat what the JPA spec is saying:
3.2.4.1合并独立的实体状态
合并操作允许 脱离状态的传播 实体到持久实体 由EntityManager管理.
3.2.4.1 Merging Detached Entity State
The merge operation allows for the propagation of state from detached entities onto persistent entities managed by the EntityManager.
合并操作的语义 应用于实体X的情况如下:
The semantics of the merge operation applied to an entity X are as follows:
- 如果X是独立实体,则X的状态将复制到预先存在的实体上 相同的管理实体实例X' 身份或X的新托管副本X' 已创建.
- 如果X是一个新的实体实例,则创建一个新的受管实体实例X' 并将X的状态复制到 新的受管实体实例X'.
- 如果X是已删除的实体实例,则
IllegalArgumentException
将是 由合并操作(或 事务提交将失败). - 如果X是一个受管实体,则合并操作会忽略它,
但是,合并操作是
级联到所引用的实体
来自X的关系(如果有)
关系已被注释为
级联元素值
cascade=MERGE
或cascade=ALL
注释. - 对于由X的关系引用的所有具有Y的实体Y
级联元素值
cascade=MERGE
或cascade=ALL
,Y递归合并 作为Y'.对于所有由 X,X'设置为参考Y'. (笔记 如果X被管理,那么X是 与X'是同一对象.) - 如果X是合并到X'的实体,并引用另一个实体Y,则其中
cascade=MERGE
或cascade=ALL
是 未指定,则导航 X'的相同关联产生a 引用管理对象Y' 与Y具有相同的持久身份.
- If X is a detached entity, the state of X is copied onto a pre-existing managed entity instance X' of the same identity or a new managed copy X' of X is created.
- If X is a new entity instance, a new managed entity instance X' is created and the state of X is copied into the new managed entity instance X'.
- If X is a removed entity instance, an
IllegalArgumentException
will be thrown by the merge operation (or the transaction commit will fail). - If X is a managed entity, it is ignored by the merge operation,
however, the merge operation is
cascaded to entities referenced by
relationships from X if these
relationships have been annotated with
the cascade element value
cascade=MERGE
orcascade=ALL
annotation. - For all entities Y referenced by relationships from X having the
cascade element value
cascade=MERGE
orcascade=ALL
, Y is merged recursively as Y'. For all such Y referenced by X, X' is set to reference Y'. (Note that if X is managed then X is the same object as X'.) - If X is an entity merged to X', with a reference to another entity Y, where
cascade=MERGE
orcascade=ALL
is not specified, then navigation of the same association from X' yields a reference to a managed object Y' with the same persistent identity as Y.
持久性提供程序不得 合并标记为LAZY的字段,这些字段没有 被获取:它必须忽略这样的 合并时的字段.
The persistence provider must not merge fields marked LAZY that have not been fetched: it must ignore such fields when merging.
实体必须由
持久性运行时实现
在合并操作期间和/或
刷新或提交时间.离席期间
Version
列中没有
进行的附加版本检查
持久性提供程序运行时
在合并操作期间.
Any Version
columns used by the
entity must be checked by the
persistence runtime implementation
during the merge operation and/or at
flush or commit time. In the absence
of Version
columns there is no
additional version checking done by
the persistence provider runtime
during the merge operation.
换句话说,merge
操作将传递的实体的状态复制到具有相同数据库身份(将在必要的情况下加载到持久性上下文中)的 managed 实体中,然后返回对该托管实体的引用(并且传递的对象未附加到持久性上下文).
In other words, the merge
operation copies the state of the passed entity to a managed entity with the same database identity (that will be loaded in the persistence context if necessary) and then returns a reference to that managed entity (and the object passed is not attached to the persistence context).
现在回到最初的问题.在这两种情况下,数据库值都将被传递的实体的完整状态覆盖,包括非null(和null)值.在实践中:
Back to the initial question now. In both case, the database values will be overridden with the full state of the passed entity, including non null (and null) values. In practice:
- 方法2,即直接在分离的实体上工作更容易
- 方法1听起来像DTO的反模式,意味着更多的痛苦
如果可以的话,请选择方法2.
Prefer approach 2 if you can.
这篇关于使用JPA更新的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!