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

ber*_*tie 7 jpa jpa-2.0

以下是导致问题的序列:

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

我很困惑:

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

请赐教:)

谢谢 !

axt*_*avt 10

JPA规范说:

应用于实体X 的合并操作的语义如下:

  • 如果X是分离的实体,则将X的状态复制到具有相同标识的预先存在的管理实体实例X'上,或者创建X的新管理副本X'.

  • 如果X是新的实体实例,则创建新的管理实体实例X',并且将X的状态复制到新的管理实体实例X'中.

  • 如果X是已删除的实体实例,IllegalArgumentException则合并操作将抛出一个 (或者事务提交将失败).

  • 如果X是一个托管实体,它将被合并操作忽略,但是,如果这些关系已使用级联元素值cascade=MERGEcascade=ALL注释进行注释,则合并操作将级联到由X的关系引用的实体.

  • 对于具有级联元素值的X的关系所引用的所有实体Y,cascade=MERGE或者cascade=ALLY被递归地合并为Y'.对于由X引用的所有这样的Y,X'被设置为引用Y'.(注意,如果管理X,那么X与X'是同一个对象.)

  • 如果X是合并到X'的实体,并且引用另一个实体Y,其中cascade=MERGE或未cascade=ALL指定,则从X'导航相同的关联产生对具有与Y相同的持久标识的被管理对象Y'的引用.

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

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

  • 如果Team是拥有方,那么Team和/ 之间Player的关系将在冲洗期间被破坏(但Player除非你有orphanRemoval = true你的关系,否则它本身就会存在).
  • 否则使用空列表Team不会影响数据库.

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

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