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

Bug 329185

Summary: SessionBroker: ClassCastException in Cursor.buildAndRegisterObject between ServerSession and UnitOfWorkImpl
Product: z_Archived Reporter: Lukas <lz8268>
Component: EclipselinkAssignee: Nobody - feel free to take it <nobody>
Status: CLOSED FIXED QA Contact:
Severity: normal    
Priority: P2 CC: andrei.ilitchev, tom.ware
Version: unspecifiedFlags: andrei.ilitchev: iplog+
Target Milestone: ---   
Hardware: PC   
OS: Windows XP   
Whiteboard: submitted_patch
Attachments:
Description Flags
proposed patch for Cursor.java (line 300) none

Description Lukas CLA 2010-11-01 08:30:10 EDT
Build Identifier: eclipselink-2.1.0

The ClassCastException happens when executing a ReadAllQuery using a SessionBroker:

// (Some client code)
Session session = ...; //a ServerSession
ReadAllQuery raq : ...;
ScrollableCursor sc = (ScrollableCursor) session.executeQuery(raq);
while (sc.hasNext()) {
...

The query returns a ScrollableCursor on which hasNext() is called. That is when the ClassCastException happens in Cursor.buildAndRegisterObject 
where a ServerSession object is being cast into type UnitOfWorkImpl:

//Cursor:buildAndRegisterObject:
if (this.session.isUnitOfWork() && (!query.isReportQuery()) && query.shouldMaintainCache()
		&& objectQuery.shouldConformResultsInUnitOfWork() || objectQuery.getDescriptor().shouldAlwaysConformResultsInUnitOfWork()) {
		Object object = objectQuery.conformIndividualResult(
			objectQuery.buildObject(row), (UnitOfWorkImpl)this.session, this.translationRow, this.selectionCriteriaClone, this.initiallyConformingIndex);
						
						
The if condition evaluates to true because objectQuery.getDescriptor().shouldAlwaysConformResultsInUnitOfWork() returns so (the mapping class sets the flag to true). Even though session.isUnitOfWork() returned false 
(it is a ServerSession) the if-body is entered nonetheless and the session object castet into typ UnitOfWorkImpl:

java.lang.ClassCastException: org.eclipse.persistence.sessions.server.ServerSession incompatible with org.eclipse.persistence.internal.sessions.UnitOfWorkImpl
	at org.eclipse.persistence.queries.Cursor.buildAndRegisterObject(Cursor.java:301)
	at org.eclipse.persistence.queries.ScrollableCursor.retrieveNextObject(ScrollableCursor.java:566)
	at org.eclipse.persistence.queries.ScrollableCursor.loadNext(ScrollableCursor.java:397)
	at org.eclipse.persistence.queries.ScrollableCursor.hasNext(ScrollableCursor.java:263)
	
	
I suggest that in the if-condition of method Cursor.buildAndRegisterObject the shouldAlwaysConformResultsInUnitOfWork() should not be ORed with isUnitOfWork() 
but rather in AND relation.

Reproducible: Always

Steps to Reproduce:
1. the mapping class has so set the flag alwaysConformResultsInUnitOfWork on the RelationalDescriptor
2. the client code has to run a query which returns a result in the form of a ScrollableCursor.
3. the client code has to run the query using a SessionBroker type session
4. call hasNext on the ScrollableCursor instance.
5. the ClassCastException should then occur
Comment 1 Lukas CLA 2010-11-02 03:44:32 EDT
Created attachment 182189 [details]
proposed patch for Cursor.java (line 300)

Line 300 of Cursor.java contains the patch according to the former TopLink version of class Cursor.
Comment 2 Tom Ware CLA 2010-11-18 08:24:28 EST
Setting target and priority.  See the following page for the meanings of these fields:

http://wiki.eclipse.org/EclipseLink/Development/Bugs/Guidelines
Comment 3 Andrei Ilitchev CLA 2011-05-02 14:25:39 EDT
Checked in the patch suggested by Lukas:
in Cursor.buildAndRegisterObject method 
substituted:
if (this.session.isUnitOfWork() && (!query.isReportQuery()) && query.shouldMaintainCache()
                    && objectQuery.shouldConformResultsInUnitOfWork() || objectQuery.getDescriptor().shouldAlwaysConformResultsInUnitOfWork()) {

with:
if (this.session.isUnitOfWork() && (!query.isReportQuery()) && query.shouldMaintainCache()
                    && (objectQuery.shouldConformResultsInUnitOfWork() || objectQuery.getDescriptor().shouldAlwaysConformResultsInUnitOfWork())) {
Comment 4 Eclipse Webmaster CLA 2022-06-09 10:27:01 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink