Argument Order at DataManager#remove

Hi,

we have two entities Order and Item. As items need to have an order, it’s mandatory and has DeletePolicy.CASCADE.

    @NotNull
    @OnDeleteInverse(DeletePolicy.CASCADE)
    @JoinColumn(name = "ORDER", nullable = false)
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    private Order order;

After some update of the data model Jmix studio changed the foreign key constraint to make use of this CASCADE.

Now we had trouble as when removing both entities with DataManager.
It works if we remove items and order

    dataManager.remove(items, order);

Due to CASCADE it (now) also works if we just remove the order.

    dataManager.remove(order);

but we get the following exception, if we change the order of the arguments of the remove.

    dataManager.remove(order, items);

java.lang.IllegalArgumentException: Cannot merge an Entity that has been removed: com.example.app.entity.order.Order-1dbec669-34f5-05e1-15ec-464438727581 [detached]
at org.eclipse.persistence.internal.sessions.MergeManager.registerObjectForMergeCloneIntoWorkingCopy(MergeManager.java:1078)
at org.eclipse.persistence.internal.sessions.MergeManager.getTargetVersionOfSourceObject(MergeManager.java:239)
at org.eclipse.persistence.mappings.ObjectReferenceMapping.mergeIntoObject(ObjectReferenceMapping.java:540)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.mergeIntoObject(ObjectBuilder.java:4210)
at org.eclipse.persistence.internal.sessions.MergeManager.mergeChangesOfCloneIntoWorkingCopy(MergeManager.java:612)
at org.eclipse.persistence.internal.sessions.MergeManager.mergeChanges(MergeManager.java:324)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.mergeCloneWithReferences(UnitOfWorkImpl.java:3676)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.mergeCloneWithReferences(RepeatableWriteUnitOfWork.java:389)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.mergeCloneWithReferences(UnitOfWorkImpl.java:3636)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.mergeInternal(EntityManagerImpl.java:648)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.merge(EntityManagerImpl.java:625)
at io.jmix.eclipselink.impl.JmixEntityManager.internalMerge(JmixEntityManager.java:479)
at io.jmix.eclipselink.impl.JmixEntityManager.merge(JmixEntityManager.java:118)
at io.jmix.eclipselink.impl.JpaDataStore.deleteAll(JpaDataStore.java:315)
at io.jmix.core.datastore.AbstractDataStore.save(AbstractDataStore.java:225)
at io.jmix.eclipselink.impl.JpaDataStore.save(JpaDataStore.java:227)
at io.jmix.core.impl.UnconstrainedDataManagerImpl.saveContextToStore(UnconstrainedDataManagerImpl.java:257)
at io.jmix.core.impl.UnconstrainedDataManagerImpl.save(UnconstrainedDataManagerImpl.java:216)
at io.jmix.core.impl.UnconstrainedDataManagerImpl.remove(UnconstrainedDataManagerImpl.java:142)
at test.com.example.app.OrderServiceTest.createOrder(OrderServiceTest.java:148)
[…]

We thought that all entities given to dataManagerare removed in a transaction and that the order of adding entities to a SaveContextwouldn’t matter as it is documented for save: Using DataManager :: Jmix Documentation.

Can you explain the behavior and the best practice?

Hello Erik,

As stated in “Removing Entities” part of the documentation, the best practice is

If you remove linked entities, the order of parameters can be important. First pass the entities that depend on the others

Entity deletion occurs within a transaction. But inside of transaction entities are removed one by one using the ORM (not pure database) mechanisms in order to support all Jmix-specific features (Soft Deletion, Entity Events, Entity Log, Cross-Datastore References, Dynamic Attributes, etc.).
Thus, the order of entities is important.

Regards,
Dmitry

1 Like

Thanks for your kind RTFM, I should have read a little further :sweat_smile: