Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [eclipselink-users] Weird behavior with CascadeType.REMOVE - deletes do not cascade depending on which fields are in a class

I think that EclipseLink is going to delete the Baz, but just has not done it
yet before the constraint error occurs.

My guess is that the other relationships are forming a cycle back to the
source object, so that EclipseLink gets confused as to the best way to
delete the objects, or even that there is no way to delete the objects.

There is a bug related to this log that you should vote for,

https://bugs.eclipse.org/bugs/show_bug.cgi?id=315141

As a workaround you could either,
- remove the cycle
- first remove the Baz then call flush(), then remove the Source
- remove or defer the foreign key constraint from Baz


gustafc wrote:
> 
> Hi, 
> 
> <p>
> The short version: I'm using EclipseLink (2.1.2) as my JPA provider, and
> I've run into a very weird behavior. For some reason, a
> <code>ManyToOne</code> relationship with <code>CascadeType.ALL</code> does
> not cascade deletes unless some fields (all relationship) are commented
> out. 
> 
> <p>
> Long version:
> 
> <p>
> In my app, there's a <code>Source</code> class, which owns several other
> things (getters and setters omitted):
> <pre>
> @MappedSuperclass
> public abstract class IdentifiedEntity
> {
>     @Id
>     @GeneratedValue( strategy = GenerationType.IDENTITY )
>     private long localId;
> }
> 
> @Entity
> public class PartnerSource extends IdentifiedEntity
> {
>     @Column( unique = true, nullable = false )
>     private String name;
>     
>     @OneToMany( mappedBy = "source", cascade = CascadeType.ALL,
> orphanRemoval = true )
>     private List&lt;Foo> foos = newArrayList( );
>     
>     @OneToMany( mappedBy = "source", cascade = CascadeType.ALL,
> orphanRemoval = true )
>     private List&lt;Bar> bars = newArrayList( );
>     
>     @OneToMany( mappedBy = "source", cascade = CascadeType.ALL,
> orphanRemoval = true )
>     private List&lt;Baz> bazes = newArrayList( );
> }
> 
> </pre>
> 
> Classes <code>Foo</code>, <code>Bar</code> and <code>Baz</code> all derive
> from the same class, <code>SourceOwned</code>:
> 
> <pre>
> @MappedSuperclass
> public abstract class SourceOwned extends IdentifiedEntity
> {
>     public static final String COL_SOURCE = "SOURCE";
>     public static final String COL_SOURCE_SPECIFIC_ID =
> "SOURCESPECIFICID";
> 
>     @ManyToOne( optional = false )
>     @JoinColumn( nullable = false, name = COL_SOURCE )
>     private Source source;
> 
>     @Column( name = COL_SOURCE_SPECIFIC_ID, nullable = false )
>     private long sourceSpecificId;
> }
> 
> @Entity
> @Table( uniqueConstraints = @UniqueConstraint( 
>     columnNames = { SourceOwned.COL_SOURCE,
> SourceOwned.COL_SOURCE_SPECIFIC_ID } ) )
> public class Foo extends SourceOwned {  }
> 
> @Entity
> @Table( uniqueConstraints = @UniqueConstraint( 
>     columnNames = { SourceOwned.COL_SOURCE,
> SourceOwned.COL_SOURCE_SPECIFIC_ID } ) )
> public class Bar extends SourceOwned {  }
> 
> @Entity
> @Table( uniqueConstraints = @UniqueConstraint( 
>     columnNames = { SourceOwned.COL_SOURCE,
> SourceOwned.COL_SOURCE_SPECIFIC_ID } ) )
> public class Baz extends SourceOwned {  }
> </pre>
> 
> So far, so good. If I call <code>entityManager.remove()</code> on a
> <code>Source</code> object, I can see how EclipseLink deletes from the
> dependent tables before deleting the <code>source</code>:
> <pre>
> [EL Fine]: DELETE FROM FOO WHERE (SOURCE = ?)
> 	bind => [1]
> [EL Fine]: DELETE FROM BAR WHERE (SOURCE = ?)
> 	bind => [1]
> [EL Fine]: DELETE FROM BAZ WHERE (SOURCE = ?)
> 	bind => [1]
> [EL Fine]: DELETE FROM SOURCE WHERE (LOCALID = ?)
> 	bind => [1]
> </pre>
> Unfortunately, reality isn't this simple, and <code>Foo</code>,
> <code>Bar</code> and <code>Baz</code> all need a bunch of
> <code>OneToMany</code> and <code>OneToOne</code> relationships to other
> tables. For <code>Foo</code> and <code>Bar</code>, this works fine, but
> when I add relationship fields to <code>Baz</code> and delete a
> <code>Source</code>, EclipseLink no longer attempts to delete from the
> <code>BAZ</code> table:
> <pre>
> [EL Fine]: DELETE FROM FOO WHERE (SOURCE = ?)
> 	bind => [1]
> [EL Fine]: DELETE FROM BAR WHERE (SOURCE = ?)
> 	bind => [1]
> [EL Fine]: DELETE FROM SOURCE WHERE (LOCALID = ?)
> 	bind => [1]
> </pre>
> Since there's a foreign key constraint on <code>BAZ.SOURCE</code>,
> deleting the source fails.
> <p>
> So what I'm wondering is, what on earth could it be with my relations that
> causes EclipseLink to ignore the cascades I've specified? I'm working on
> an SSCCE, but I've not yet been able to isolate this behaviour (my data
> model is quite large and highly proprietary) and wanted to check if this
> is some kind of known behavior (bug, PEBKAC indicator or whatever).
> 
> TIA,
> 
> /g
> 


-----
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 
Blog:  http://java-persistence-performance.blogspot.com/ Java Persistence
Performance 
-- 
View this message in context: http://old.nabble.com/Weird-behavior-with-CascadeType.REMOVE---deletes-do-not-cascade-depending-on-which-fields-are-in-a-class-tp30759087p30765854.html
Sent from the EclipseLink - Users mailing list archive at Nabble.com.



Back to the top