Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 354813

Summary: ManyToMany JoinTable record is not being deleted when the mapping is inherited
Product: z_Archived Reporter: Tor-Einar Jarnbjo <tor.jarnbjo.ext>
Component: EclipselinkAssignee: Nobody - feel free to take it <nobody>
Status: RESOLVED DUPLICATE QA Contact:
Severity: critical    
Priority: P3 CC: eclipselink.foundation-inbox, guy.pelletier, tom.ware, tor.jarnbjo.ext
Version: unspecified   
Target Milestone: ---   
Hardware: PC   
OS: Windows 7   
Whiteboard:

Description Tor-Einar Jarnbjo CLA 2011-08-16 07:36:05 EDT
Build Identifier: 2.3.0

With EclipseLink 2.3.0, the exact same problem as in Bug 303514 has been reintroduced, since the inheritance of the pre-delete mappings have been moved from InheritancePolicy#initialize to InheritancePolicy#postInitialize, which is not invoked in the correct order.

The relevant line of code (added in 2.1.1 with the fix for 303514 and moved from initialize to postInitialize in 2.3.0) is:

getDescriptor().getPreDeleteMappings().addAll(getParentDescriptor().getPreDeleteMappings());

In ClassDescriptor#postInitialize, the following code invokes postInitialize on the child descriptors to ensure that for some reason, inherited classes are initialized "bottom up", as stated in the comment:

        // Make sure that child is post initialized,
        // this initialize bottom up, unlike the two other phases that to top down.
        if (hasInheritance()) {
            for (ClassDescriptor child : getInheritancePolicy().getChildDescriptors()) {
                child.postInitialize(session);
            }
        }

With the described data model, before the post initialization phase, we have the following situation:

A with a pre-delete mapping for the many-to-many-relationship to D
B without the pre-delete mapping
C without the pre-delete mapping

When A#postInitialize is invoked, it iterates over its children, invokes B#postInitialize, which again invokes C#postInitialize. C#postInitialize will now copy the pre-delete mappings from B, before they are copied from A to B. Since the initialization state is kept and further invokations of C#postInitialize are ignored, the pre-delete mapping for the D many-to-many relationship will never be copied to C.

Reproducible: Always

Steps to Reproduce:
1. Define a three-level inherited entity hierarchy, e.g. entity A (base), entity B (extends A) and entity C (extends B). Entity A has a many-to-many-mapping with a List of entity D. Map these entities to tables A, B, C, D and the many-to-many-relationship to table A_D.
2. Create and commit an instance of C with a list of Ds. Data is inserted to all tables, A, B, C, D and A_D.
3. Load and delete the C instance. EclipseLink will now delete the data from A, B, C and D, but not from A_D.
Comment 1 Guy Pelletier CLA 2011-09-22 15:56:14 EDT
Nightly builds of 2.3.1 can be picked up here:

http://www.eclipse.org/eclipselink/downloads/nightly.php

*** This bug has been marked as a duplicate of bug 351602 ***
Comment 2 Eclipse Webmaster CLA 2022-06-09 10:32:24 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink