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

Bug 323147

Summary: Concurrency issue in ObjectBuilder.getPrimaryKeyClassifications
Product: z_Archived Reporter: Andrei Ilitchev <andrei.ilitchev>
Component: EclipselinkAssignee: Nobody - feel free to take it <nobody>
Status: CLOSED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: eclipselink.foundation-inbox
Version: unspecified   
Target Milestone: ---   
Hardware: PC   
OS: Windows XP   
Whiteboard:

Description Andrei Ilitchev CLA 2010-08-19 10:12:39 EDT
Caused by an obvious oversight (really a typo):

public List<Class> getPrimaryKeyClassifications() {
    if (primaryKeyClassifications == null) {
        List primaryKeyFields = this.descriptor.getPrimaryKeyFields();
        List<Class> classifications = new ArrayList(primaryKeyFields.size());

        for (int index = 0; index < primaryKeyFields.size(); index++) {
            DatabaseMapping mapping = getPrimaryKeyMappings().get(index);
            DatabaseField field = (DatabaseField)primaryKeyFields.get(index);
            if (mapping != null) {
                classifications.add(Helper.getObjectClass(mapping.getFieldClassification(field)));
            } else {
                classifications.add(null);
            }
            primaryKeyClassifications = classifications;
        }
    }
    return primaryKeyClassifications;
}

Assignment to primaryKeyClassifications done inside the loop causes it to be possibly altered by thread 2 while thread 1 is working on it - that causes IndexOutOfBounds exception.
Of course the assignment should be done outside of the loop:

public List<Class> getPrimaryKeyClassifications() {
    if (primaryKeyClassifications == null) {
        List primaryKeyFields = this.descriptor.getPrimaryKeyFields();
        List<Class> classifications = new ArrayList(primaryKeyFields.size());

        for (int index = 0; index < primaryKeyFields.size(); index++) {
            DatabaseMapping mapping = getPrimaryKeyMappings().get(index);
            DatabaseField field = (DatabaseField)primaryKeyFields.get(index);
            if (mapping != null) {
                classifications.add(Helper.getObjectClass(mapping.getFieldClassification(field)));
            } else {
                classifications.add(null);
            }
        }
        primaryKeyClassifications = classifications;
    }
    return primaryKeyClassifications;
}
Comment 1 Andrei Ilitchev CLA 2010-08-19 11:45:10 EDT
Checked the patch into trunk, 2.1.2 is pending.
Comment 2 Andrei Ilitchev CLA 2010-08-31 15:31:05 EDT
Checked the patch into 2.1.2.
Comment 3 Eclipse Webmaster CLA 2022-06-09 10:29:44 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink