java 一对多单向亲子ID级联保存

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1690859/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 17:37:23  来源:igfitidea点击:

One-to-Many Unidirectional Parent-Child ID Cascade Save

javahibernateparent-childone-to-many

提问by ButtersB

When trying to save an ID from my parent class into a child class, I keep getting the error "ERROR - Field 'parent_id' doesn't have a default value"

尝试将父类中的 ID 保存到子类中时,我不断收到错误消息“错误 - 字段‘parent_id’没有默认值”

I have tried all types of mappings. I am using annotations.

我已经尝试了所有类型的映射。我正在使用注释。

Any help on this would be appreciated

对此的任何帮助将不胜感激

Parent:

家长:

      @Id
      @Column(name="id")
      @GeneratedValue(strategy=GenerationType.AUTO)
      private long id;
      @Column(name="description")
      private String description;
      @OneToMany
      @Cascade(value= {org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE})
      @JoinColumn(name="parent_id")
      private List<Child> children;

Child:

孩子:

  @Id
  @Column(name="id")
  @GeneratedValue(strategy=GenerationType.AUTO)
  private long id;
  @Column(name="description")
  private String description;

Thanks.

谢谢。

回答by Henning

A late addition in case anyone ever runs into the same issue.

以防万一有人遇到同样的问题,这是一个迟到的补充。

This entity here, when persisted using Hibernate 4.1.8, willcascade the FieldChangeentities, but will notfill the join column:

这里的实体,当使用 Hibernate 4.1.8 持久化时,级联FieldChange实体,但不会填充连接列:

@Entity
public class Event {

    //ID and other fields here

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "event_id")
    private List<FieldChange<?>> fields = new ArrayList<FieldChange<?>>();

 }

Neither does the insert statement set the event_idcolumn, nor does it update the inserted entity after the fact - the event_idremains null and the relation is lost.

insert 语句既不设置event_id列,也不在事后更新插入的实体 -event_id仍然为空并且关系丢失。

If, however, the @JoinColumndefinition is changed like this:

但是,如果@JoinColumn定义更改如下:

@JoinColumn(name = "event_id", nullable = false)

, then the insert statement includes the event_idcolumn like it should, and all is well.

,然后插入语句event_id像它应该的那样包含列,一切都很好。

This may only be a regression in this particular version of Hibernate, but maybe it helps someone.

这可能只是这个特定版本的 Hibernate 的回归,但也许它对某人有帮助。

回答by slavik

In your case JPA provider to persist child object with its parent perform at least three queries on db. First two persist the objects by its own. The last one update child object with the foreign key referencing parent. The second query fail because you have a NOT NULL constraint on the foreign key column. You have three options:

在您的情况下,JPA 提供程序将子对象与其父对象持久化,至少对 db 执行三个查询。前两个通过自己的方式持久化对象。最后一个使用外键引用父对象更新子对象。第二个查询失败,因为您在外键列上有一个 NOT NULL 约束。您有三个选择:

  1. Remove NOT NULL constraint on foreign key in the child entity
  2. Use bidirectional relationship
  3. Change JPA provider to one which supports such cases.
  1. 删除子实体中外键的 NOT NULL 约束
  2. 使用双向关系
  3. 将 JPA 提供程序更改为支持此类情况的提供程序。

回答by Ryan Stewart

You must have something wrong somewhere else because those mappings will work the way they are. They could be better, but they'll work. Specifically, all the @Columnannotations are redundant and unnecessary, and as non sequitor noted, you should use the cascade property of JPA's @OneToManyinstead of Hibernate's @Cascade. I've created a runnable examplewith the cleaned-up version of what you posted. If you have git and maven, you can run it with:

您一定在其他地方出了什么问题,因为这些映射会按原样工作。它们可能会更好,但它们会起作用。具体来说,所有@Column注释都是多余的和不必要的,正如非 sequitor 所指出的,您应该使用 JPA 的级联属性@OneToMany而不是 Hibernate 的@Cascade. 我已经使用您发布的内容的清理版本创建了一个可运行的示例。如果你有 git 和 maven,你可以运行它:

git clone git://github.com/zzantozz/testbed tmp
cd tmp
mvn -q compile exec:java \
    -Dexec.mainClass=rds.hibernate.UnidirectionalManyToOneJoinColumn \
    -pl hibernate-unidirectional-one-to-many-with-join-column

It creates a parent with two children, saves them, and then loads them and prints out the graph. The output is:

它创建一个有两个孩子的父级,保存它们,然后加载它们并打印出图表。输出是:

Creating parent with two children
Loading saved parent
Parent{description='parent', children=[Child{description='child 2'}, Child{description='child 1'}]}

回答by non sequitor

Change your @OneToManyto @OneToMany(cascade=CascadeType.ALL)use JPA rather than the Hibernate extensions

将您更改@OneToMany@OneToMany(cascade=CascadeType.ALL)使用 JPA 而不是 Hibernate 扩展

回答by Josh

My guess is that the @JoinColumn annotationneeds a referencedColumnNameassigned.

我的猜测是@JoinColumn annotation需要一个referencedColumnName分配。

@JoinColumn(name = "parent_id", referencedColumnName = "id")