【问题标题】:org.springframework.orm.jpa.JpaSystemException: Don't change the reference to a collection with delete-orphan enabledorg.springframework.orm.jpa.JpaSystemException:不要更改对启用了 delete-orphan 的集合的引用
【发布时间】:2022-06-13 14:53:46
【问题描述】:

我正在使用弹簧数据 jpa。 当我想克隆一个具有一对多关系的实体时,

    fun clonePurchaseOrder(purchaseOrder: PurchaseOrder, operator: String): PurchaseOrder {
        //prepare data
        val items = purchaseOrder.items
        //detach
        items.forEach { entityManager.detach(it) }
        purchaseOrder.costRevise?.let { entityManager.detach(it) }
        entityManager.detach(purchaseOrder)
        purchaseOrder.id = null
        //modify
        items.forEach {
            it.id = null
            it.purchaseOrder = purchaseOrder
        }     
        //modify purchaseOrder
        val now = Date()
        return purchaseOrder.apply {
            number = null
            costRevise = null
            paymentHistories = mutableListOf()
            status = PurchaseOrder.Status.DRAFT
            createTime = now
            creator = operator
            modifyTime = now
            submitTime = null
            submitOperator = null
            closeOperator = null
            closeReason = null
            closeTime = null
        }.save()
    }

我设置purchaseOrder id =null,每件商品id = null,但是得到以下异常


org.springframework.orm.jpa.JpaSystemException: Don't change the reference to a collection with delete-orphan enabled : com.hkmci.web.bms2.backend.database.entity.PurchaseOrder.items; nested exception is org.hibernate.HibernateException: Don't change the reference to a collection with delete-orphan enabled : com.hkmci.web.bms2.backend.database.entity.PurchaseOrder.items

这里是 purchaseOrder 实体和 items 实体


@Entity
class PurchaseOrder(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Long? = null,

    ...(other Column)

    @OneToMany(mappedBy = "purchaseOrder", cascade = [CascadeType.ALL], orphanRemoval = true)
    var items: MutableList<PurchaseOrderItem> = mutableListOf(),

    ...(other Column)

@Entity
class PurchaseOrderItem(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Long? = null,

    @ManyToOne(fetch = FetchType.LAZY)
    var purchaseOrder: PurchaseOrder,

    ...(other column)

有人可以帮忙吗?

【问题讨论】:

  • 您没有克隆项目。您应该为每个对象创建新实例并将字段设置为原始值(ID 除外)
  • 但是我的物品是先一个一个分离,然后设置id=null,再设置purchaseOrder指向没有id的新的。我还看到了 purchaseOrder 和 items 的控制台打印插入查询。
  • 在我的项目中,还有其他地方使用了这种方法并且克隆成功。代码逻辑看起来一样,但只有一个区别:父实体主键是String,是从头开始生成的,而不是设置为null。这是根本案例吗?

标签: java spring hibernate jpa


【解决方案1】:
//clone a purchaseOrder, new purchaseOrder will be reset to Draft
    fun clonePurchaseOrder(purchaseOrder: PurchaseOrder, operator: String): PurchaseOrder {
        //clear all relationships
        purchaseOrder.costRevise?.let { entityManager.detach(it) }
        purchaseOrder.items.forEach {
            entityManager.detach(it)
            it.id = null
        }
        purchaseOrder.paymentHistories.forEach {
            entityManager.detach(it)
        }
        entityManager.detach(purchaseOrder)
        //reset all fields
        val now = Date()
        purchaseOrder.apply {
            id = null
            number = null
            costRevise = null
            items = items.toMutableList()
            paymentHistories = mutableListOf()
            status = PurchaseOrder.Status.DRAFT
            createTime = now
            creator = operator
            modifyTime = now
            submitTime = null
            submitOperator = null
            closeOperator = null
            closeReason = null
            closeTime = null
        }
        //save
        return purchaseOrderRepository.save(purchaseOrder)
    }

无需重新关联 items 和 purchaseOrder ,只需清除所有关系,设置 id = null 并保存

【讨论】:

    猜你喜欢
    • 2013-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-11
    • 1970-01-01
    • 2018-03-06
    • 2012-03-14
    相关资源
    最近更新 更多