添加到@ManyToOne

时间:2016-05-07 09:26:58

标签: java hibernate jpa spring-data spring-data-jpa

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

@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.father没有得到更新:

Child child = new Child();
// optionally persist child first, tried
father.getChildren().add(child);
...save father

我尝试使用不同的CascadeTypes,但似乎无法自动更新Child.father引用。我知道传统的方法是使用“addChild”方法,但我想知道是否有自动方法可以这样做吗?

我的配置是Spring Boot + JPA(Hibernate)+ H2,自动创建数据库。有趣的是,我发现一些博客帖子似乎与我在这里做的完全一样,但对他们来说它有效,但不适合我。奇怪。

1 个答案:

答案 0 :(得分:2)

是的,但不是故意的。我只是解释它,因为它可以解释你在这些博文中看到的内容。您可以删除mappedBy并添加@JoinColumn,使@OneToMany成为关系的拥有方。但是,这主要适用于您没有后向参考的情况。如果保留@ManyToOne,那么Hibernate会看到两个碰巧共享相同列的关系。据我所知,它应该有效。

我曾经看过一个不合理的引用,一旦它可能导致性能问题,但我不能再找到该引用,所以我不确定。它会有两个问题,它表明&#34;这不是你应该如何做到这一点&#34;选项的性质:

  1. 在关闭事务/会话并从数据库重新加载子实体之前,不会更新父字段。
  2. 如果您以后决定实施二级缓存,则可以更改代码的逻辑。这是因为子实体可能在一段时间内没有从数据库重新加载,直到它为止,父字段将为null。
  3. 您可以使用动态代理和反射自行实现此功能,但您必须通过DAO / Repository控制实体的创建,以确保它们被代理。

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