Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 298322 - NPE for ElementCollection mapping with Map type in MapContainerPolicy.compareKeys
Summary: NPE for ElementCollection mapping with Map type in MapContainerPolicy.compare...
Status: RESOLVED FIXED
Alias: None
Product: z_Archived
Classification: Eclipse Foundation
Component: Eclipselink (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows XP
: P3 blocker with 1 vote (vote)
Target Milestone: ---   Edit
Assignee: Nobody - feel free to take it CLA
QA Contact:
URL:
Whiteboard: submitted_patch
Keywords:
Depends on:
Blocks:
 
Reported: 2009-12-21 12:38 EST by J H CLA
Modified: 2022-06-09 10:24 EDT (History)
6 users (show)

See Also:
tom.ware: iplog+


Attachments
Entity definition and test case (5.59 KB, application/octet-stream)
2009-12-21 12:40 EST, J H CLA
no flags Details
Stacktrace (3.56 KB, text/plain)
2009-12-21 12:40 EST, J H CLA
no flags Details
Fix described above + testing (8.32 KB, patch)
2010-06-10 10:32 EDT, Tom Ware CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description J H CLA 2009-12-21 12:38:56 EST
Build Identifier: 2.0.0

I have an entity (EntityA) that maps an embeddable type (EmbeddableType) using ElementCollection with CollectionTable into a Map, where the property 'language' of EmbeddableType is defined as map key (see enclosed test case for details).

Simply creating instances of EntityA and persisting it, works fine (see test testSimplePersist)

When modifying the mapped association by adding or removing a Map entry, EL throws a NullPointerException in MapContainerPolicy.compareKeys(MapContainerPolicy.java:234) (see enclosed stack trace for details) when the transaction is committed. 


Reproducible: Always

Steps to Reproduce:
1. Apply test case (TestNG) in attached file
Comment 1 J H CLA 2009-12-21 12:40:13 EST
Created attachment 154886 [details]
Entity definition and test case
Comment 2 J H CLA 2009-12-21 12:40:51 EST
Created attachment 154887 [details]
Stacktrace
Comment 3 Rafal Swierzynski CLA 2009-12-22 06:12:28 EST
The problem seems to be that the MapContainerPolicy.compareKeys() method is not null-safe. It creates a key from an object that was not in the session before, and all its values are nulls, and then it extracts the map key field from this object, which is null.
Possible solution to this problem is a slight change to the compareKeys() method:

public boolean compareKeys(Object sourceValue, AbstractSession session) {
        if (((UnitOfWorkImpl)session).isClassReadOnly(sourceValue.getClass())) {
            return true;
        }
        Object backUpVersion = ((UnitOfWorkImpl)session).getBackupClone(sourceValue, getElementDescriptor());
        Object backUpVersionKey = keyFrom(backUpVersion, session);
        Object sourceValueKey = keyFrom(sourceValue, session);
        if (backUpVersionKey == sourceValueKey) {
            // this conditional captures the same instances, as well as both being nulls
            // not sure if this semantics is correct
            return true;
        }
        if (backUpVersionKey == null && sourceValueKey != null) {
            return false;
        }
        // if sourceValueKey is null, and backUpVersionKey is not, it's probably OK since most equals()

Regards.
        // implementations deal with it correctly
        return backUpVersionKey.equals(sourceValueKey);
    }
Comment 4 Tom Ware CLA 2010-01-14 15:36:41 EST
2_1_community Setting target and priority.  See
http://wiki.eclipse.org/EclipseLink/Development/Bugs/Guidelines for details of
what these values mean.
Comment 5 J H CLA 2010-03-11 10:03:34 EST
Rising priority to major since this bug prevents us from using standard Glassfish server distribution.
Comment 6 J H CLA 2010-05-28 10:22:53 EDT
Hi again, 
I am raising the priority of this bug again after checking 2.1.0 RC1 from May 17, 2010 and does not contain the fix. 

Using map keys for this kind of mapping comes really natural in my opinion and it's an important addition to the spec. It's one of the reasons we are using JPA 2. 
Further on, the spec has been finalized 8 month ago. I think it's about time that the new features will work now. 

Szczyp has provided a fix for the problem which has shown to be working and the fix seems to be kind of simple (and obvious).
However, fixing the problem ourselves prevents us from using standard EL integration in Glassfish, which blocks us from using standard Glassfish distribution. 

I would really appreciate if the fix makes it into 2.1. Even better if a backport to 2.0 is made.

Thanks!
Comment 7 Tom Ware CLA 2010-06-08 14:24:19 EDT
Proposed fix looks good.  2.1 is closed, but fix will be checked into 2.1.1.
Comment 8 Tom Ware CLA 2010-06-08 15:36:02 EDT
changing target unti
Comment 9 Tom Ware CLA 2010-06-10 10:32:55 EDT
Created attachment 171638 [details]
Fix described above + testing
Comment 10 Tom Ware CLA 2010-06-10 10:34:34 EDT
Checked in suggested fix into trunk.

Setting bug to P1 for 2.1.1, so it will be included in 2.1.1 when the stream opens.

Reviewed by: Tom Ware - reviewed community-submitted fix

Add mapping and test to Inherited model and tested with JPA and Core LRG
Comment 11 Guy Pelletier CLA 2010-07-26 14:09:09 EDT
Changes have been submitted to the 2.1.1 stream.
Comment 12 Eclipse Webmaster CLA 2022-06-09 10:24:27 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink