Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 348648 - MethodAttributeAccessor getAttributeValueFromObject() throws NPE in error handling for a null object
Summary: MethodAttributeAccessor getAttributeValueFromObject() throws NPE in error han...
Status: RESOLVED FIXED
Alias: None
Product: z_Archived
Classification: Eclipse Foundation
Component: Eclipselink (show other bugs)
Version: unspecified   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: David Minsky CLA
QA Contact: Project Inbox CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-06-07 17:12 EDT by David Minsky CLA
Modified: 2022-06-09 10:04 EDT (History)
0 users

See Also:


Attachments
Proposed fix (1.33 KB, patch)
2011-06-07 17:45 EDT, David Minsky CLA
no flags Details | Diff
Proposed fix (4.82 KB, patch)
2011-06-24 13:56 EDT, David Minsky CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
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