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

Bug 348648

Summary: MethodAttributeAccessor getAttributeValueFromObject() throws NPE in error handling for a null object
Product: z_Archived Reporter: David Minsky <david.minsky>
Component: EclipselinkAssignee: David Minsky <david.minsky>
Status: RESOLVED FIXED QA Contact: Project Inbox <eclipselink.foundation-inbox>
Severity: normal    
Priority: P3    
Version: unspecified   
Target Milestone: ---   
Hardware: All   
OS: All   
Whiteboard:
Attachments:
Description Flags
Proposed fix
none
Proposed fix none

Description David Minsky CLA 2011-06-07 17:12:37 EDT
org.eclipse.persistence.internal.descriptors.MethodAttributeAccessor getAttributeValueFromObject() can throw an additional NullPointerException when attempting to handle a NullPointerException upon invoking a configured method on a null object.

org.eclipse.persistence.internal.descriptors.InstanceVariableAttributeAccessor getAttributeValueFromObject() does not have this issue, as it utilizes a null check in its exception handling code.
Comment 1 David Minsky CLA 2011-06-07 17:40:06 EDT
This error may occur when two parent objects are (incorrectly) referencing the same aggregate object. Resolving this issue will contribute to how diagnosable this potential problem is in the long run.
Comment 2 David Minsky CLA 2011-06-07 17:45:38 EDT
Created attachment 197547 [details]
Proposed fix

Proposed fix.
Follows same pattern as the implementation of the same superclass method in InstanceVariableAttributeAccessor.
Comment 3 David Minsky CLA 2011-06-09 10:41:21 EDT
"reproduced" the incorrect scenario of sharing aggregate objects in EL trunk:

Local Exception Stack: 
Exception [EclipseLink-69] (Eclipse Persistence Services - @VERSION@.@QUALIFIER@): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: A NullPointerException was thrown while extracting a value from the instance variable [endDate] in the object [null].
Internal Exception: java.lang.NullPointerException
Mapping: org.eclipse.persistence.mappings.DirectToFieldMapping[endDate-->EMPLOYEE.END_DATE]
Descriptor: RelationalDescriptor(examples.sessions.threetier.model.EmploymentPeriod --> [DatabaseTable(EMPLOYEE), DatabaseTable(SALARY)])
	at org.eclipse.persistence.exceptions.DescriptorException.nullPointerWhileGettingValueThruInstanceVariableAccessor(DescriptorException.java:1263)
	at org.eclipse.persistence.internal.descriptors.InstanceVariableAttributeAccessor.getAttributeValueFromObject(InstanceVariableAttributeAccessor.java:88)
	at org.eclipse.persistence.mappings.DatabaseMapping.getAttributeValueFromObject(DatabaseMapping.java:516)
	at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.compareObjects(AbstractDirectMapping.java:455)
	at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.compareForChange(AbstractDirectMapping.java:407)
	at org.eclipse.persistence.descriptors.changetracking.DeferredChangeDetectionPolicy.createObjectChangeSetThroughComparison(DeferredChangeDetectionPolicy.java:165)
	at org.eclipse.persistence.descriptors.changetracking.DeferredChangeDetectionPolicy.createObjectChangeSet(DeferredChangeDetectionPolicy.java:137)
	at org.eclipse.persistence.descriptors.changetracking.DeferredChangeDetectionPolicy.calculateChanges(DeferredChangeDetectionPolicy.java:89)
	at org.eclipse.persistence.internal.descriptors.ObjectBuilder.compareForChange(ObjectBuilder.java:1964)
	at org.eclipse.persistence.mappings.AggregateMapping.compareForChange(AggregateMapping.java:313)
	at org.eclipse.persistence.descriptors.changetracking.DeferredChangeDetectionPolicy.createObjectChangeSetThroughComparison(DeferredChangeDetectionPolicy.java:165)
	at org.eclipse.persistence.descriptors.changetracking.DeferredChangeDetectionPolicy.createObjectChangeSet(DeferredChangeDetectionPolicy.java:137)
	at org.eclipse.persistence.descriptors.changetracking.DeferredChangeDetectionPolicy.calculateChanges(DeferredChangeDetectionPolicy.java:89)
	at org.eclipse.persistence.descriptors.changetracking.DeferredChangeDetectionPolicy.calculateChangesForExistingObject(DeferredChangeDetectionPolicy.java:54)
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.calculateChanges(UnitOfWorkImpl.java:636)
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1482)
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitRootUnitOfWork(UnitOfWorkImpl.java:1317)
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commit(UnitOfWorkImpl.java:1079)
Comment 4 David Minsky CLA 2011-06-09 10:42:54 EDT
The following Employee demo-based example was used:

UnitOfWork uow = getSession().acquireUnitOfWork();
        
Employee employee1Original = new Employee();
Employee employee2Original = new Employee();

Employee employee1Clone = (Employee) uow.registerObject(employee1Original);
Employee employee2Clone = (Employee) uow.registerObject(employee2Original);
        
employee1Clone.setMale();
employee1Clone.setFirstName("Joe");
employee1Clone.setLastName("Someone");
employee1Clone.setSalary(1234);
employee1Clone.setPeriod(new EmploymentPeriod()); // not null

employee2Clone.setFemale();
employee2Clone.setFirstName("Jill");
employee2Clone.setLastName("Someone");
employee2Clone.setSalary(1234);
employee2Clone.setPeriod(null); // deliberately null

uow.commit();
        
uow = getSession().acquireUnitOfWork();

employee1Clone = (Employee)uow.registerObject(employee1Original);
// UoW backup clone's 'period' attribute is null
employee2Clone = (Employee)uow.registerObject(employee2Original);
        
employee2Clone.setPeriod(employee1Clone.getPeriod()); // 1. share the aggregate

uow.commit();
Comment 5 David Minsky CLA 2011-06-24 13:56:35 EDT
Created attachment 198561 [details]
Proposed fix
Comment 6 David Minsky CLA 2011-06-24 14:06:07 EDT
Aggregate sharing testcase no longer reproduces with the changes from:

Revision: 9610
Author: gyorke
Date: 2:47:23 PM, June 22, 2011
Message: Bug 300108 - Any changes that reference detached object will cause detached to be inserted

I've attached the exception fix I was working on, for brevity. This exception would be thrown, instead of an NPE when the attribute accessor attempted to invoke on a null object.
Comment 7 Eclipse Webmaster CLA 2022-06-09 10:04:24 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink