Hibernate软件包中带有CascadeType的ConstraintViolationException

时间:2019-02-01 20:38:06

标签: java hibernate jpa orm foreign-keys

在应用程序正在使用休眠3和我已经读取与JPA注释VS休眠注释的一些问题。参见Cascade common mistakes

我与遗留码工作,所以该实体是一个总的混乱。

以前,我的实体是:

    @OneToMany(mappedBy = "order", targetEntity = Investiment.class, fetch = FetchType.LAZY)
    @Cascade({org.hibernate.annotations.CascadeType.ALL,
            org.hibernate.annotations.CascadeType.DELETE_ORPHAN,
            org.hibernate.annotations.CascadeType.PERSIST,
            org.hibernate.annotations.CascadeType.MERGE,
            org.hibernate.annotations.CascadeType.REMOVE,
            org.hibernate.annotations.CascadeType.REFRESH,
            org.hibernate.annotations.CascadeType.SAVE_UPDATE})
    private List<Investment> investment;

    @ManyToMany(
            cascade = {CascadeType.PERSIST},
            targetEntity = Discount.class,
            fetch = FetchType.EAGER)
    @JoinTable(name = "cupons_campanha_pedido")
    private List<Discount> discountList;

    @Column(name = "nfeAccessKey")
    private String nfeAccessKey;

    @OneToMany(cascade = {CascadeType.ALL})
    @Cascade(value = {org.hibernate.annotations.CascadeType.ALL, org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
    @JoinColumn(name = "idOrder")
    @LazyCollection(LazyCollectionOption.FALSE)
    private List<Item> itens;

我得到了很多的对象引用一个未保存的瞬态的实例 - 保存瞬态的实例在冲洗前:com.company.entity.Investment

对于我来说是很奇怪的设定为CascadeType.ALL和所有重新设置候选条件枚举。因此,我只更改投资注释:

        @OneToMany(mappedBy = "order", targetEntity = Investment.class, fetch = FetchType.LAZY)
        @Cascade({org.hibernate.annotations.CascadeType.ALL})
        private List<Investment> investment;

第一个异常停止。但是,我知道我知道了这一点(虽然不常见,但确实发生了):

  

WARN-2019-01-31 19:25:18.470:SQL错误:0,SQL状态:23503错误-   2019年1月31日19:25:18.471:批量录入0删除从订单,其中   ID = 1096523已中止:ERROR:更新或删除表“命令”   违反表上的外键约束“ fk10e0b022beb033fc”   “ orderinvestment”详细信息:仍引用键(id)=(1096523)   从表“ orderinvestment”。调用getNextException查看其他   批次中的错误。 WARN-2019-01-31 19:25:18.471:SQL错误:0,   SQLSTATE:23503错误 - 2019年1月31日19:25:18.472:错误:更新或   在表“ order”上删除违反外键约束   表“ orderinvestment”上的“ fk10e0b022beb033fc”详细信息:键   (ID)=(1096523)仍从表 “orderinvestment” 引用。   错误 - 2019年1月31日19:25:18.472:无法同步数据库状态   与会话org.hibernate.exception.ConstraintViolationException:   无法在以下位置执行JDBC批处理更新   org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)     在   org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)

这种情况发生在通话

getHibernateTemplate().saveOrUpdate(entity);

我知道Hibernate是JPA实现,但是使用JPA批注存在一些问题。因此最好只使用Hibernate批注。在这种情况下,投资设置为org.hibernate.annotations.CascadeType.ALL。为什么会这样?

2 个答案:

答案 0 :(得分:0)

由于@OneToMany cascade option is be default none,删除操作未级联。尝试设置@OneToMany(cascade = ALL)

Hibernate是JPA的实现。可以在没有Hibernate注释的情况下使用JPA注释,但在没有JPA注释的情况下不能使用Hibernate。

尝试删除休眠注释@Cascade,并仅在@OneToMany中使用JPA级联。

答案 1 :(得分:0)

您需要同步关系的两端:

parent.getChildren().remove(child); // on the parent side
child.getParent() = null; // on the child side

另一种解决方案是删除孤儿:removeOrphans = true注释中的@OneToMany。这也可以在数据库级别完成。