【问题标题】:Hibernate annotations work better the "wrong" way around?Hibernate 注释以“错误”的方式更好地工作?
【发布时间】:2015-12-09 22:34:06
【问题描述】:

我一直在网上寻找一个不错的答案,但我得到的只是困惑。我正在为 hibernate 中的 @ManyToOne 注释应该如何工作而苦苦挣扎 - 因为 @OneToMany@JoinColumn 似乎要好得多,因为 hibernate 正确地插入了外键,而不是我必须在保存之前在 java 中分配子对象。

基本上作为最简单的例子,我有这样的事情:

Parent Table:  id int,
Child Table :  id int, parentFk int


public class Parent{
    @Id
    @GeneratedValue
    private Integer id;

    @OneToMany
    @JoinColumn(name = "parentFk")
    private List<Child> children;

    //setters and getters
}

public class Child{
    @Id
    @GeneratedValue
    private Integer id;

    @Column
    private Integer parentFk;

    //setters and getters
}

现在,如果我发送一些映射到 Parent 类的 json 并要求 hibernate 保存它,它将保存表中的所有内容,包括 parentFk 字段中父级的新 ID。然而,我一直认为这实际上是错误的做事方式,我应该在 Parent 类中做 @OneToMany(mappedBy = "id") - 然后还有 @ManyToOne@JoinColumn 和 @987654330 Child 类中的 @ 对象。

问题是这样做的,我必须通过 java 代码手动设置子对象中的父对象,然后休眠才能正确地将父对象的 id 保存在 parentFk 字段中......这看起来很冗长做一些对我来说已经很完美的事情(尽管我无法从孩子那里访问父对象)。

此外,我尝试删除子对象中的 parentFk 字段并将@ManyToOne 与父对象引用一起使用,但休眠似乎不喜欢它。我做错了吗?

【问题讨论】:

  • 你应该映射对象而不是 id 你的 Child 应该引用 Parent 而不是父的 id。
  • 这也要看你的需求,你需要它是双向关系还是单关系。但是,您现在所拥有的是错误的,因为您应该映射对象而不是普通的 id。

标签: java spring hibernate annotations


【解决方案1】:

你的映射应该是这样的。

public class Parent{
    @Id
    @GeneratedValue
    private Integer id;

    @OneToMany(mappedBy="parent", cascade={CascadeType.ALL})
    private List<Child> children;

    //setters and getters
}

public class Child{
    @Id
    @GeneratedValue
    private Integer id;

    @ManyToOne
    @JoinColumn(name="parentFk")
    private Parent parent;

    //setters and getters
}

您还应该在您的父级(和删除)上有一个 add(Child child) 方法来管理关系。假设ParentChild 在同一个包中,我将使Child 包上的setParent 受到保护,即没有访问修饰符(setParent(Parent parent) { this.parent=parent})

public void add(Child child) {
    child.setParent(this);
    this.children.add(child);
}

当这样做时,hibernate 将能够执行正确的查询。

【讨论】:

  • 这样做会让hibernate插入行但外键为空......就目前而言,我不需要在java中设置孩子的父母来插入fk
  • 您需要包含级联,否则它将不起作用,您必须管理依赖项。就像add 方法一样。这种方法是有原因的。此外,如果您现在保存 Child,则应该存储 Parent 而不是 Child,父级将不会被存储。
  • 这就是我的意思 - 我目前不需要管理依赖项。基本上,我的 json 字符串有许多嵌套的子对象,我希望 hibernate 处理整个对象,而不必手动设置任何东西(当 joincolumn 位于父类中时,它当前会这样做)。我试过包括级联但仍然没有。我总是保存父对象。
  • 那你在其他地方有问题。你的对象应该是关于域的,而不是关于 JSON 输出的。
【解决方案2】:

通过在@OneToMany 映射上使用@JsonManagedReference 和在@ManyToOne 上使用@JsonBackReference 修复

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多