Home > Software design >  org.springframework.orm.jpa.JpaSystemException: Don't change the reference to a collection with
org.springframework.orm.jpa.JpaSystemException: Don't change the reference to a collection with

Time:06-13

i'm using spring data jpa. when i want to clone an entity with one to many relation,

    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()
    }

i set the purchaseOrder id =null, and each items id = null, but get the follw exception


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

here is purchaseOrder entity and items entity


@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)

can any one help with this?

CodePudding user response:

//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)
    }

No need to reassociate items and purchaseOrder , just clear all relationships, set id = null and save

  • Related