Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » ReadObjectQuery with setSelectionId=null has undeterministic behavior
ReadObjectQuery with setSelectionId=null has undeterministic behavior [message #783253] Wed, 25 January 2012 11:05 Go to next message
Lukas Zbinden is currently offline Lukas Zbinden
Messages: 6
Registered: January 2012
Junior Member
We have experienced a strange behavior with type ReadObjectQuery where an instance of it is executed with the selectionId (accidentially) set to null. The SQL string which is then produced by EclipseLink is the following (assuminge the table is SOME_TABLE and the primary key column SOME_TABLE_PK):

SELECT t0.* FROM SOME_TABLE t0;

So therefore the query always returns a result (which in fact is random depdending on the underlying databases' implementation of this SQL query) as opposed to null. This can have fatal consequences (major data corruptions) in an application when the result is random and never null.
Since we migrated from TopLink to EclipseLink we know that TopLink's behavior was different in that it produced a different and in our opinion more comprehensible SQL string whenever the selectionId as set to null:

SELECT t0.* FROM SOME_TABLE t0 WHERE t0.SOME_TABLE_PK = NULL;

Here's a code snippet that shows the scenario:

ReadObjectQuery query = new ReadObjectQuery(SomeClassToRead.class);
Object theSelectionId = null; // accidentially set to null
query.setSelectionId(theSelectionId);
				
Session session = ...; // some Session, in our case it was a UnitOfWork
SomeClassToRead result = (SomeClassToRead) session.executeQuery(query);
assert result != null; // -> always true with EclipseLink (with the result object being random!) but always false with TopLink i.e. result=null


So we consider this behavior of ReadObjectQuery in EclipseLink to be a defect or at least very dangerous.

This behavior also goes against the contract of the method ReadObjectQuery.executeObjectLevelReadQuery() which is being executed as part of the call session.executeQuery(query). Its contract says:

@return object - the first object found or null if none.


=> but as discussed above if the selectionId is null it will always return some random object and never null as the result.


Can anyone comment on this? Otherwise I will submit a bug report.
Re: ReadObjectQuery with setSelectionId=null has undeterministic behavior [message #783488 is a reply to message #783253] Wed, 25 January 2012 20:21 Go to previous messageGo to next message
Chris Delahunt is currently offline Chris Delahunt
Messages: 1026
Registered: July 2009
Senior Member
In EclipseLink, it is as if you are unsetting the setSelectionId to be used making it a default ReadObjectQuery on SomeClassToRead. As the documentation states, the query will return the first SomeClassToRead instance it comes across or it returns from the database.

I couldn't find a selectionId api in TopLink, but what it did have was a setSelectionKey which is deprecated in EclipseLink and took a list as an argument. It should behave the same as Eclipselink if a null list was passed to it, so it could be that you were wrapping the null value in a list and passing it to the the setSelectionKey method. A vector containing a null is different from a null collection.

If that is the case, you can duplicate the same in EclipseLink by wrapping the null selectionId in a cacheId and pass it to setSelectionId.

Best Regards,
Chris
Re: ReadObjectQuery with setSelectionId=null has undeterministic behavior [message #783692 is a reply to message #783488] Thu, 26 January 2012 08:38 Go to previous messageGo to next message
Lukas Zbinden is currently offline Lukas Zbinden
Messages: 6
Registered: January 2012
Junior Member
Thanks. Yes we used setSingletonSelectionKey with TopLink and then setSelectionId with EclipseLink. I see that with EclipseLink setSingletonSelectionKey cannot simply be replaced with setSelectionId and then have the same behavior with ReadObjectQuery. And yes setSingletonSelectionKey put its parameter (in this case null) in a Vector and used this Vector as the selectionKey.

So I tried your advice and did the following in order to get the same behavior with EclipseLink:
Long theSelectionId = null; // accidentially set to null
query.setSelectionId(new CacheId(new Object[] { theSelectionId }));


But it ended up with an conversion exception:
Exception [EclipseLink-3001] (Eclipse Persistence Services - 2.3.1.v20111018-r10243): org.eclipse.persistence.exceptions.ConversionException
Exception Description: The object [[[null]: 0]], of class [class org.eclipse.persistence.internal.identitymaps.CacheId], could not be converted to [class java.lang.Long].							

Is there another way in EclipseLink and ReadObjectQuery, respectively, to have the same behavior as there used to be with TopLink and ReadObjectQuery.setSingletonSelectionKey? That is when the selectionKey is null you get null as a result of executing that ReadObjectQuery...

Thanks,
Lukas
Re: ReadObjectQuery with setSelectionId=null has undeterministic behavior [message #783695 is a reply to message #783488] Thu, 26 January 2012 08:38 Go to previous messageGo to next message
Lukas Zbinden is currently offline Lukas Zbinden
Messages: 6
Registered: January 2012
Junior Member
No Message Body

[Updated on: Thu, 26 January 2012 08:55]

Report message to a moderator

Re: ReadObjectQuery with setSelectionId=null has undeterministic behavior [message #783854 is a reply to message #783695] Thu, 26 January 2012 15:39 Go to previous messageGo to next message
James Sutherland is currently offline James Sutherland
Messages: 1939
Registered: July 2009
Location: Ottawa, Canada
Senior Member

You could use setSelectionObject instead of setSelectionId, then if the object has an Id of null, then it will query on that. Although I'm not sure why you would want to ever query the database for a null id, why not just not execute the query in your app if the id is null?


James : Wiki : Book : Blog : Twitter
Re: ReadObjectQuery with setSelectionId=null has undeterministic behavior [message #783855 is a reply to message #783695] Thu, 26 January 2012 15:39 Go to previous messageGo to next message
James Sutherland is currently offline James Sutherland
Messages: 1939
Registered: July 2009
Location: Ottawa, Canada
Senior Member

You could use setSelectionObject instead of setSelectionId, then if the object has an Id of null, then it will query on that. Although I'm not sure why you would want to ever query the database for a null id, why not just not execute the query in your app if the id is null?

--
James : http://wiki.eclipse.org/EclipseLink : http://en.wikibooks.org/wiki/Java_Persistence : http://java-persistence-performance.blogspot.com/


James : Wiki : Book : Blog : Twitter
Re: ReadObjectQuery with setSelectionId=null has undeterministic behavior [message #784524 is a reply to message #783854] Fri, 27 January 2012 16:56 Go to previous message
Lukas Zbinden is currently offline Lukas Zbinden
Messages: 6
Registered: January 2012
Junior Member
Yes setSelectionObject works instead of setSelectionKey i.e. it has the same behavior as setSelectionKey when the id is null:

So what used to be in Toplink:
ReadObjectQuery query = new ReadObjectQuery(SomeClassToRead.class);
Object theSelectionId = null; // accidentially set to null
query.setSingletonSelectionKey(theSelectionId);
SomeClassToRead result = (SomeClassToRead) session.executeQuery(query);
if (result == null) throw ...; // Exception

must now be done in EclipseLink as follows in order to have identical behavior:
ReadObjectQuery query = new ReadObjectQuery(SomeClassToRead.class);
Object theSelectionId = null; // accidentially set to null
query.setSelectionObject(new SomeClassToRead(theSelectionId));
SomeClassToRead result = (SomeClassToRead) session.executeQuery(query);
if (result == null) throw ...; // Exception

or one checks beforehand that the selectionId is not null of course.

The reason why we passed a null id to setSelectionId is that the application was built on top of TopLink years ago and it depended on the behavior of ReadObjectQuery that if the selectionKey was null the result would also be null. Doing the migration to EclipseLink we replaced setSelectionKey with setSelectionId which turned out to be a serious mistake since ReadObjectQuery would then return a random result. Now we have the choice between checking before the query is run that the id is not null or using setSelectionObject instead.
Previous Topic:Embedded object with null values in db cause instances not to be updated
Next Topic:is it possible to create a dynamic persistent entity with composite primary key ?
Goto Forum:
  


Current Time: Thu Oct 02 06:24:45 GMT 2014

Powered by FUDForum. Page generated in 0.01794 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software