• 项目记事【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,问题解决!

  • 相关阅读:
    HDU 3415 Max Sum of Max-K-sub-sequence 最长K子段和
    Android Fragment 真正彻底的解决(下一个)
    【数据分析面试题】一个 面试题,我的回答
    Swift初体验(两)
    MyEclipse10.0 集成 SVN
    CFileDialog 打开文件夹文件 保存文件夹文件
    基于thinkphp的uploadify上传图功能
    近20家银行手机银行签名被非法滥用风险分析
    设计模式【6】:适配器模式【接口适配】
    【学习笔记】编译原理-有限自己主动机
  • 原文地址:https://www.cnblogs.com/jing-an-feng-shao/p/7568613.html
Copyright © 2020-2023  润新知