JPA:与惰性初始化集合合并的行为是什么?

前端之家收集整理的这篇文章主要介绍了JPA:与惰性初始化集合合并的行为是什么?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
以下是导致问题的序列:

>我有一个团队记录,数据库中有3个玩家记录. Team实体有一个使用FetchType.LAZY,CascadeType.ALL的List
>单击webui上的搜索按钮
>调用服务器端使用JPA查询查询,查找所有Team记录,在这种情况下,只查询查询​​返回的团队实体的1条记录(其中包含播放器实体列表的代理)
>将此teamEntity映射到DTO,并将此DTO返回到webui,跳过播放器实体列表的映射
> Webui以html格式呈现DTO,准备接收用户修改
>用户修改团队的属性,例如团队成立的日期
>单击webui上的保存按钮
>将DTO转换为团队实体,用于更新现有团队记录
>但是在这种情况下,如果我要使用em.merge(teamEntity),团队记录将会更新,但是玩家列表会发生什么?因为从DTO转换到团队实体时,teamEntity有一个空的玩家实体列表.合并后,我注意到teamEntity的大小为0.但在刷新该实体em.refresh(teamEntity)后,它将返回3个细节大小.

我很困惑:

>合并后为什么大小为0?这就像不再代表记录了
>在进行测试之前,我认为细节将被删除,因为我将teamEntity与空细节合并.

请赐教:)

谢谢 !

解决方法

JPA规范说:

The semantics of the merge operation
applied to an entity X are as follows:

  • 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 or
    cascade=ALL annotation.

  • For all
    entities Y referenced by relationships
    from X having the cascade element
    value cascade=MERGE or cascade=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 or cascade=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.

如你所见,这里没有魔力.已分离实例的状态将复制到新创建的托管实例中.由于您的分离实例有一个空列表,因此托管实例也会拥有它.

进一步的行为取决于关系的所有权,因为数据库中的表示反映了关系的拥有方:

>如果Team是拥有者,那么团队和玩家之间的关系将在刷新期间被销毁(但是除非你的关系中有orphanRemoval = true,否则玩家本身会存活).
>否则在Team中拥有空列表不会影响数据库.

如果在刷新上下文之前刷新团队,则Team的所有属性都将由数据库中的值重写,因此将恢复播放器列表(因为尚未刷新播放器的空列表).

如果在调用refresh()之前调用flush(),并且Team是拥有者,则list将为空,因为在flush()期间,关系的破坏会传播到数据库.

猜你在找的Java相关文章