zoukankan      html  css  js  c++  java
  • 项目记事【Hibernate-1】:调用 saveOrUpdate() 方法出错

    Hibernate 版本:3.3.1

    背景:

    后端编辑一个对象,该对象(ProductDO)下,有一个另一个自定义对象(ProductLiabilityDO)的 OneToMany 关系,如下:

    @OneToMany(targetEntity = ProductLiabilityDO.class, mappedBy = "product", cascade = CascadeType.ALL)
    private List<ProductLiabilityDO> liabilities = ListUtil.newArrayList();

    而在 ProductLiabilityDO 对象中,又持有对 ProductDO 对象的 ManyToOne 关系,如下:

    @ManyToOne(targetEntity = ProductDO.class, fetch = FetchType.LAZY)
    @JoinColumn(name = "productId")
    private ProductDO product;

    在对 ProductDO 对象进行 update 操作的时候(ProductLiabilityDO 的列表有增有减)报错,信息如下:

    deleted object would be re-saved by cascade (remove deleted object from associations)

    错误分析1:

    如提示所说的,被删除的内容,由于级联关系的配置,会被重新保存。

    解决方案1:

    在 OneToMany 的一方,增加 Hiberbate 的 @Cascade 注解,这个注解有一个孤儿属性,可以保证被删除的内容,不会由于级联关系,被重新保存。

    @OneToMany(targetEntity = ProductLiabilityDO.class, mappedBy = "product", cascade = CascadeType.ALL)
    @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
    private List<ProductLiabilityDO> liabilities = ListUtil.newArrayList();

    新的问题:

    在执行完成以上步骤之后,发现了新的问题:

    org.hibernate.HibernateException:
    ]A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: com.XXXX.pms.actual.model.ProductDO.liabilities

    出错代码位置:

    productDO.setLiabilities(transferLiabilities(vo.getLiabilities(), productDO, productLiabilityAssignments));

    错误分析2:

    原来 ProductDO 的此属性,已经持有对于一个 ProductLiabilityDO 列表的引用,直接用另外一个列表的引用,替代这个引用,在最后调用 saveOrUpdate() 方法时报错。

    解决方案2:

    将原来的列表清空,然后将入参给予的列表加入空列表,规避问题。

    由于调用的地方过多,在所有增加 @Cascade 注解的属性的 set() 方法全部重写,防止以后再次误操作。

    public void setLiabilities(List<ProductLiabilityDO> liabilities) {
        if (this.liabilities == liabilities) {
            return;
        }
        this.liabilities.clear();
        this.liabilities.addAll(liabilities);
    }

    Over,问题解决!

  • 相关阅读:
    SessionFactory Cache 的配置
    乱码处理问题
    格式化当前日期
    JDK的安装
    内存和对象内存池技术在网游开发中的注意点和应用
    Head First设计模式C++实现Strategy模式
    介绍三种将二进制字节字符转换为ASCII方法
    C++风格的类型转换的用法
    i++循环与i循环的执行效率
    系统程序员成长计划组合的威力(一)
  • 原文地址:https://www.cnblogs.com/jing-an-feng-shao/p/7568613.html
Copyright © 2011-2022 走看看