以下是导致该问题的序列:

  • 我有一个团队记录,并且在数据库中有3个Player记录。团队实体具有使用FetchType.LAZY,CascadeType.ALL
  • 的列表
  • 单击webui上的搜索按钮
  • 调用服务器端使用JPA查询的
  • 查询,查找所有Team记录,在这种情况下,仅从查询返回的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规范说:



    如您所见,这里没有魔术。分离实例的状态将复制到新创建的托管实例中。由于您的分离实例的列表为空,因此托管实例也将具有此列表。

    进一步的行为取决于关系的所有权,因为数据库中的表示反射(reflect)了关系的所有权:

  • 如果Team是所有者,则在刷新期间TeamPlayer之间的关系将被破坏(但除非您的关系上有Player,否则orphanRemoval = true本身将继续存在)。
  • 否则,在Team中包含空列表不会影响数据库。

  • 如果在刷新上下文之前刷新Team,则Team的所有属性都将被数据库中的值重写,因此Player的列表将被还原(因为尚未清空空的播放器列表)。

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

    10-07 19:52