Hibernate级联保存父项和子项-未找到父项键

dfddblmv  于 2022-12-19  发布在  其他
关注(0)|答案(2)|浏览(138)

我在一个项目中使用Spring、Hibernate和oracle,数据库架构是通过运行sql脚本手动创建的,一切正常,直到我遇到了Hibernate一对多双向级联保存的问题。
在父类(Product.java)中

@OneToMany(mappedBy="product",
        fetch=FetchType.EAGER,
        cascade={CascadeType.ALL})
public Set<Picture> getPictures() {
        return pictures;
}

@Transient
public void addPicture(Picture picture) {
    picture.setProduct(this);
    pictures.add(picture);
}

在子类(Picture.java)中

@ManyToOne(cascade={CascadeType.ALL})
@JoinColumn(name="lse09lse06id")
public Product getProduct() {
        return product;
}

“lse 09 lse 06 id”是子实体表中的外键列。
在我的Controller类中:

Product product = new Product();
.... (set properties of product)
Picture newPicture = new Picture();
.... (set properties of newPicture)
product.addPicture(newPicture);
productService.addProduct(product);

在我的ProductService类中:

@Override
@Transactional
public void addProduct(Product product) {
    productDAO.addProduct(product);
}

在我的ProductDAO类中:

@Override
public void addProduct(Product product) {
    product.setDateCreated(new Date());
    sessionFactory.getCurrentSession().save(product);
}

执行控制器代码时抛出异常:
org.springframework.web.util.NestedServletException:请求处理失败;嵌套异常是org.springframework.dao.数据完整性违规异常:无法执行JDBC批更新; SQL [插入lse 09图片(lse 09内容、lse 09创建日期、lse 09删除日期、lse 09更新日期、lse 09 is删除日期、lse 09 lse 06 id、lse 09 id)值(?,?,?,?,?,?,?)];限制条件[CSSE3005GG.LSE09图片_FK];嵌套异常是组织.休眠.异常.约束违规异常:无法执行JDBC批处理更新
抛出的嵌套异常之一:
java.sql.BatchUpdateException:ORA-02291:违反了完整性约束(CSSE3005GG.LSE09PICTURES_FK)-未找到父关键字
任何帮助都将不胜感激。这个问题真的很棘手。谢谢!

aydmsdu9

aydmsdu91#

@ManyToOne(cascade={CascadeType.ALL})中删除cascade。Hibernate会被循环引用搞糊涂。
或者,在保存Picture示例之前保存Product示例(通过显式调用session.save())。

gj3fmq9x

gj3fmq9x2#

使用Hibernate级联类

  • org.hibernate.annotations.Cascade
  • org.hibernate.annotations.CascadeType

你能试着这样重写吗:

@OneToMany(fetch=FetchType.EAGER,
@Cascade(value = { CascadeType.SAVE_UPDATE, CascadeType.PERSIST,
     CascadeType.MERGE })
public Set<Picture> getPictures() {
    return pictures;
}

还有

@ManyToOne
@Cascade(value = { CascadeType.SAVE_UPDATE, CascadeType.PERSIST,
     CascadeType.MERGE })
@JoinColumn(name="lse09lse06id")
public Product getProduct() {
    return product;
}

之后,调用Hibernate。saveOrUpdate应该可以完成您想要的操作。
Cyberax是对的,循环引用可能会让Hibernate感到困惑。另外,级联删除应该小心使用-这就是为什么我只使用了保存、持久化和合并。

相关问题