Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [eclipselink-users] JPA: Cascade.REMOVE not working for unidirectional OneToMany-Relationship

You are executing a delete all JPQL query.  This is basically similar to
executing your own SQL, you are responsible for executing the query
correctly to maintain your constraints.

This is not the normal way to delete objects in JPA.  In JPA you normally
read the object, then call remove() on it.  When an object is removed,
EclipseLink is responsible to delete it correctly based on the database
constraints it knows about.



Pinaki Poddar wrote:
> 
> Hi,
> 
> A one-to-one, bi-direction mapping where the owner side using a simple
> derived identity fails to delete by query depending on the order of
> execution. 
>  
>> The best workaround is most likely to make the relationship @PrivateOwned
>> until the bug is fixed.
> It works if the owner side is deleted *before* the owned side.
> 
> Here are the two ends of a one-to-one bi-directional relation, Book and
> its Inventory. Inventory owns the mapping and uses derived identity from
> the corresponding Book.
> 
> ------------ Book.java -----------------------
> @Entity
> public class Book implements Serializable {
>     @Id
>     private String ISBN;
> 
>     @OneToOne(mappedBy="book",
>               fetch=FetchType.LAZY,
>               cascade=CascadeType.ALL)
>     private Inventory inventory;
> 
> ----------- Inventory.java --------------------
> @Entity
> public class Inventory implements Serializable {
>     @Id
>     @OneToOne(fetch=FetchType.LAZY)
>     private Book book;
>        
> 
> Here is the working application code to clean the tables. If the owner
> side table is deleted first, it works. If the order of two delete-by-query
> is swapped, then the runtime fails with the stacktrace mentioned below.
> 
>         em.getTransaction().begin();
>         em.createQuery("delete from Inventory i").executeUpdate();
>         em.createQuery("delete from Book b").executeUpdate();
>         em.getTransaction().commit();
> 
> 
>      [java] Caused by: Exception [EclipseLink-4002] (Eclipse Persistence
> Services - 2.0.0.v20091127-r5931):
> org.eclipse.persistence.exceptions.DatabaseException
>      [java] Internal Exception:
> com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
> Cannot delete or update a parent row: a foreign key constraint fails
> (`openbook/inventory`, CONSTRAINT `FK_INVENTORY_BOOK_ISBN` FOREIGN KEY
> (`BOOK_ISBN`) REFERENCES `book` (`ISBN`))
>      [java] Error Code: 1451
>      [java] Call: DELETE FROM BOOK
>      [java] Query: DeleteAllQuery(referenceClass=Book sql="DELETE FROM
> BOOK")
>      [java]     at
> org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:324)
>      [java]     at
> org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:800)
>      [java]     at
> org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:866)
>      [java]     at
> org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:586)
>      [java]     at
> org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:529)
>      [java]     at
> org.eclipse.persistence.internal.sessions.AbstractSession.executeCall(AbstractSession.java:914)
>      [java]     at
> org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:205)
>      [java]     at
> org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.deleteAll(DatasourceCallQueryMechanism.java:94)
>      [java]     at
> org.eclipse.persistence.queries.DeleteAllQuery.executeDatabaseQuery(DeleteAllQuery.java:174)
>      [java]     at
> org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:675)
>      [java]     at
> org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:589)
>      [java]     at
> org.eclipse.persistence.queries.ModifyAllQuery.executeInUnitOfWork(ModifyAllQuery.java:145)
>      [java]     at
> org.eclipse.persistence.queries.DeleteAllQuery.executeInUnitOfWork(DeleteAllQuery.java:100)
>      [java]     at
> org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2863)
>      [java]     at
> org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1225)
>      [java]     at
> org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1207)
>      [java]     at
> org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1181)
>      [java]     at
> org.eclipse.persistence.internal.jpa.EJBQueryImpl.executeUpdate(EJBQueryImpl.java:508)
>      [java]     at openbook.server.DataLoader.clear(Unknown Source)
> 
> James Sutherland wrote:
>> 
>> I updated the bug with the details, and workarounds.
>> 
>> The best workaround is most likely to make the relationship @PrivateOwned
>> until the bug is fixed.
>> 
>> 
>> 
>> zebhed wrote:
>>> 
>>> hmm, this seems to be related to
>>> https://bugs.eclipse.org/bugs/show_bug.cgi?id=221389
>>> 
>>> 
>> 
>> 
> 
> 


-----
http://wiki.eclipse.org/User:James.sutherland.oracle.com James Sutherland 
http://www.eclipse.org/eclipselink/
 EclipseLink ,  http://www.oracle.com/technology/products/ias/toplink/
TopLink 
Wiki:  http://wiki.eclipse.org/EclipseLink EclipseLink , 
http://wiki.oracle.com/page/TopLink TopLink 
Forums:  http://forums.oracle.com/forums/forum.jspa?forumID=48 TopLink , 
http://www.nabble.com/EclipseLink-f26430.html EclipseLink 
Book:  http://en.wikibooks.org/wiki/Java_Persistence Java Persistence 
-- 
View this message in context: http://old.nabble.com/JPA%3A-Cascade.REMOVE-not-working-for-unidirectional-OneToMany-Relationship-tp18574083p27421761.html
Sent from the EclipseLink - Users mailing list archive at Nabble.com.



Back to the top