我正在使用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;
}
“lse09lse06id”是子实体表中的外键列。
在我的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.DataIntegrityViolationException: 无法执行JDBC批量更新; SQL [插入lse09pictures (lse09content,lse09date_created, lse09date_deleted,lse09date_updated, lse09is_deleted,lse09lse06id, lse09id)值(?,?,?,?,?,?, ?)];约束 [CSSE3005GG.LSE09PICTURES_FK];嵌套 例外是 org.hibernate.exception.ConstraintViolationException: 无法执行JDBC批量更新
抛出一个嵌套异常:
java.sql.BatchUpdateException: ORA-02291:完整性约束 (CSSE3005GG.LSE09PICTURES_FK)违反了 - 未找到父密钥
非常感谢任何帮助。这个问题真的很讨厌。谢谢!
答案 0 :(得分:0)
从cascade
移除@ManyToOne(cascade={CascadeType.ALL})
。 Hibernate被循环引用搞糊涂了。
或者,在Product
实例之前保存Picture
实例(通过在其上显式调用session.save())。
答案 1 :(得分:0)
使用Hibernate Cascade类
您可以尝试像这样重写它吗?
@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感到困惑。另外,应谨慎使用级联删除-这就是为什么我只使用了Save,Persist和Merge。