【问题标题】:One-to-Many Unidirectional Parent-Child ID Cascade Save一对多单向父子ID级联保存
【发布时间】:2009-11-06 22:17:53
【问题描述】:

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

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

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

家长:

      @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;

孩子:

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

谢谢。

【问题讨论】:

  • “尝试将我的父类中的 ID 保存到子类中时”是什么意思。你能详细说明一下吗?

标签: java hibernate parent-child one-to-many


【解决方案1】:

后期添加,以防万一有人遇到同样的问题。

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

@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<?>>();

 }

插入语句既没有设置event_id 列,也没有在事后更新插入的实体-event_id 保持为空并且关系丢失。

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

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

,那么插入语句就应该包含event_id 列,一切都很好。

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

【讨论】:

  • 我真的为这个问题摸不着头脑,将@JoinColumn(name = "event_id") 更改为@JoinColumn(name = "event_id", nullable = false) 解决了这个问题。
【解决方案2】:

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

  1. 删除子实体中外键的 NOT NULL 约束
  2. 使用双向关系
  3. 将 JPA 提供程序更改为支持此类情况的提供程序。

【讨论】:

  • 选项 1 使用 EclipseLink 2.5.1 为我解决了这个问题,谢谢!
【解决方案3】:

您肯定在其他地方出了点问题,因为这些映射会按原样工作。他们可能会更好,但他们会工作。具体来说,所有@Column 注释都是多余且不必要的,并且正如非sequitor 指出的那样,您应该使用JPA 的@OneToMany 的级联属性而不是Hibernate 的@Cascade。我已经创建了一个runnable example,其中包含您发布的内容的清理版本。如果你有 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

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

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

【讨论】:

    【解决方案4】:

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

    【讨论】:

    • 虽然肯定是一个有效的建议,但这并不能完全回答 OP 的问题。
    • 绝对正确 ChssPly76 我认为他在这里使用扩展是没有根据的,因为parent_id 没有被正确传播。除了我建议的更改之外,他的注释看起来都正确。鉴于 OP 缺乏信息,您认为会发生什么?
    【解决方案5】:

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

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

    【讨论】:

    • 在创建引用主键的外键的典型情况下,不需要 referencedColumnName。来自文档:“默认(仅在使用单个连接列时适用):与引用表的主键列同名。”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-29
    • 2014-08-07
    • 1970-01-01
    • 2017-02-18
    • 2011-11-04
    • 2015-03-24
    相关资源
    最近更新 更多