Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 添加到@ManyToOne时更新父引用_Java_Hibernate_Jpa_Spring Data_Spring Data Jpa - Fatal编程技术网

Java 添加到@ManyToOne时更新父引用

Java 添加到@ManyToOne时更新父引用,java,hibernate,jpa,spring-data,spring-data-jpa,Java,Hibernate,Jpa,Spring Data,Spring Data Jpa,让我们假设一个简单的1父->n子实体关系(省略了getter/setter): 我尝试使用不同的cascade类型,但似乎无法自动更新Child.father引用。我知道传统的方法是使用“addChild”方法,但我想知道是否有一种自动的方法可以做到这一点 我的配置是SpringBoot+JPA(Hibernate)+H2,自动创建数据库。有趣的是,我发现一些博客帖子似乎和我在这里做的完全一样,但对他们有效,但对我无效。奇怪。是的,但不是故意的。我只是真的解释它,因为它可以解释你在那些博客文章中

让我们假设一个简单的1父->n子实体关系(省略了getter/setter):

我尝试使用不同的cascade类型,但似乎无法自动更新
Child.father
引用。我知道传统的方法是使用“addChild”方法,但我想知道是否有一种自动的方法可以做到这一点


我的配置是SpringBoot+JPA(Hibernate)+H2,自动创建数据库。有趣的是,我发现一些博客帖子似乎和我在这里做的完全一样,但对他们有效,但对我无效。奇怪。

是的,但不是故意的。我只是真的解释它,因为它可以解释你在那些博客文章中看到的东西。通过删除
mappedBy
并添加
@JoinColumn
,可以使@OneToMany成为关系的拥有方。但是,这主要用于没有反向引用的情况。如果保留
@manytone
,则Hibernate将看到两个关系,它们恰好共享相同的列。然而,据我所知,它应该是有效的

我曾经见过一个不合理的引用,它可能会导致性能问题,但我再也找不到那个引用了,所以我不确定。这将有两个问题,即哪种方式可以证明选项的“这并不是你应该怎么做的”:

  • 在关闭事务/会话并从数据库重新加载子实体之前,不会更新父字段
  • 如果您以后决定实现第二级缓存,它可以更改代码的逻辑。这是因为子实体可能在一段时间内不会从数据库中重新加载,并且在重新加载之前,父字段将为null
  • 虽然您必须通过DAO/存储库来控制实体的创建,以确保它们得到代理,但您可以自己使用动态代理和反射来实现这一点


    最后,我个人不会推荐它。年龄越大,我越觉得你的应用程序中的黑魔法越少越好。

    谢谢你的回答。这里的“问题”与其说是JPA行为,不如说是Spring Data Rest中的结果,它允许我放入/father/X/children集合-但在那里什么都不做,因为它正确地添加到集合中,但这个添加不会改变任何东西…啊,我认为向父亲添加孩子的标准方法是执行
    PUT/child/X/father
    。如果您需要大量添加子元素,本文提到了一种方法,您可以使用
    uri列表来添加子元素,但这对我来说几乎不起作用,因为最后一步已经完成(子元素/注释被放入或修补到列表中,但不会更新其父元素/帖子引用)。它适用于您的变通方法,但正如您所说,这可能不是一个好主意。所以,要么我希望整个事情失败,而不是看起来成功或成功。我很困惑。你是说
    PUT
    /child/X/father
    (而不是
    father/X/children
    )更新集合而不是父引用?对我来说,这似乎很违反直觉。如果有什么我希望它更新父引用而不是集合。否,使用
    {“父亲”更新
    /children/x
    :http://...“}
    有效,但尚未尝试使用
    /children/x/father
    。只有这个方法不起作用,但它返回204,就好像它起作用一样,这也是非常违反直觉的。
    @Entity
    public class Father {
    
        @Id
        @GeneratedValue
        private Integer id;
    
        @OneToMany(mappedBy="father", cascade=CascadeType.ALL)
        private List<Child> children = new ArrayList<>();
    
        ...
    }
    
    @Entity
    public class Child {
        @Id
        @GeneratedValue
        private Integer id;
    
        @ManyToOne(cascade=CascadeType.ALL)
        private Father father;
    
        ...
    }
    
    Child child = new Child();
    // optionally persist child first, tried
    father.getChildren().add(child);
    ...save father