首页 > 解决方案 > hibernate + spring data jpa 会自动创建具有 OneToOne 关系的父实体的子实体记录吗?

问题描述

在我每天花费 8 小时的商店中,我使用 jsf 2.x Web 应用程序。在其中,hibernate + spring data jpa 一起用于数据库事务。

我在该 Web 应用程序中共享FooJava 实体的简化版本。

@Entity
@Table(name="FOO")
public class Foo {
    @Id
    @Column(name="FOO_ID", nullable=false)
    private UUID fooId;

    @OneToOne(mappedBy="Foo", cascade=CascadeType.ALL, 
       orphanRemoval=true)
    @NotFound(action=NotFoundAction.IGNORE)
    @LazyCollection(LazyCollectionOption.FALSE)
    private Bar bar;

    @OneToOne(mappedBy="Foo", cascade=CascadeType.ALL, 
       orphanRemoval=true)
    @NotFound(action=NotFoundAction.IGNORE)
    @LazyCollection(LazyCollectionOption.FALSE)
    private Zoo zoo;

    }

如您所见,java实体FooBar具有OneToOne关系。在 UI 方面,当我进入需要填写表单的页面时,我将为该表单填写的数据将创建Foo实例和子实例之一BarZoo. 填写表格后,只有将实例CrudRepository.save(foo)持久化到数据库的出口入口。Foo其关联的子实体要么BarZoo将被封装在Foo实例中。

这是我遇到的一个奇特事件:

  1. 填写表格并保存它,这反过来会在每个表和数据库中分别创建一个记录FooBar实例。FooTableBarTable
  2. 没有找到ZooTable预期的记录。
  3. Foo从网络应用程序重新访问相同的实例然后发生了一些奇怪的事情。
  4. 我注意到一条记录ZooTable仅在其自身的主键中创建,zoo_id其父键作为外键foo_id,但其余列映射为 NULL 形成数据。

我在应用程序中的方法中设置了一个断点,save()期望页面加载时我希望它会被击中,但它从来没有这样做过。看起来应用程序正在绕过正确的出口入口以持久化到数据库,而是使用隐藏的后门出去并持久化到数据库。

我正在努力寻找答案,但我没有成功。我在这里读了几篇关于jpa auto save这里的文章,但我既不完全理解也不完全理解他们提出的案例与我的场景相匹配。

我的猜测是它OneToOneFoo它的子实体BarZoo. 当您重新访问Foo实例时,它会期望丢失的子实体会被提取(?)但是因为它没有单独找到休眠或弹簧数据 jpa 或者一起工作会创建一个幻像条目?

标签: javahibernatespring-data-jpa

解决方案


推荐阅读