Cannot delete object that is an object of @OneToOne relationship

I have the following entities with @OneToOne relation:

@Entity public static class EntityChild extends BaseEntity { //Id from superclass } @Entity public static class EntityParent extends BaseEntity { //Id from superclass @OneToOne(cascade = ALL) private EntityChild child; //child getter/setter } 

Now the following test fails:

 EntityParent parent = new EntityParent(); em.persist(parent); em.flush(); EntityChild child = new EntityChild(); parent.setChild(child); em.persist(parent); em.flush(); em.remove(parent.getChild()); em.flush(); 

It throws an exception on the last line using flush (). An exception is javax.persistence.EntityNotFoundException: deleted entity passed to persist: [my.package.EntityChild#<null>]

Why can't I delete this object?

+4
source share
1 answer

First you need to remove the connection between the parent and the child, otherwise Hibernate will try to save the child again due to cascade = ALL :

 EntityChild c = parent.getChild(); parent.setChild(null); em.remove(c); em.flush(); 

Update:

Here are excerpts from the JPA specification related to this behavior. The exception was thrown due to a conflict between [1] and [2] during flush() (although I cannot find where it is listed):

The semantics of the flash operation applied to object X are as follows:

  • If X is a managed entity, it synchronizes with the database.

    • For all objects Y referenced by a link from X, if the relation to Y was annotated with the value of the cascade element cascade=PERSIST or cascade=ALL , the save operation is applied to Y.

    • For any object Y referenced by a link from X, where the relation to Y has not been annotated with the value of the element cascade cascade=PERSIST or cascade= ALL :

      • If Y is new or remote, an IllegalStateException will be thrown by a IllegalStateException operation (and a transaction marked for rollback) or a commit transaction will fail.

      • If Y separates, the semantics depend on communication ownership. If X is related, any changes to the relationship are synchronized with the database; otherwise, if Y owns the relationship, the behavior is undefined.

  • If X is a remote object, it is deleted from the database. There are no cascading options. <--------------- [1]


The semantics of persist operations applied to an X object are as follows:

  • If X is a new object, it becomes manageable. Entity X will be entered into the database before or before the transaction or as a result of a flash operation.

  • If X is an existing managed entity, this is ignored by the persist operation. However, a persistent operation is cascaded to objects referenced by X if relations from X to these other objects are annotated using the cascade=PERSIST or cascade=ALL value of the annotation element or the specified value with an equivalent XML element descriptor.

  • If X is a remote object, it becomes manageable. <--------------- [2]

  • If X is a single object, an EntityExistsException may be thrown when the persist operation is called, or an EntityExistsException or another PersistenceException may be thrown during a flush or commit.

  • For all objects of Y referenced by relations from X, if the relation to Y was annotated with the value of the cascade element cascade=PERSIST or cascade=ALL , the save operation is applied to Y.

+4
source

Source: https://habr.com/ru/post/1336321/


All Articles