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?
Advertisement
Answer
//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