Issue Details (XML | Word | Printable)

Key: OPENJPA-208
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: Marc Prud'hommeaux
Reporter: Marc Prud'hommeaux
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
OpenJPA

NoResultException and NonUniqueResultException are not thrown when expected

Created: 06/Apr/07 10:25 PM   Updated: 15/Apr/07 02:35 AM
Return to search
Component/s: jpa
Affects Version/s: 0.9.6
Fix Version/s: 0.9.7

Time Tracking:
Not Specified

Resolution Date: 09/Apr/07 05:06 PM


 Description  « Hide
When calling Query.getSingleResult() on a query that either has no result or multiple results, either a NoResultException and NonUniqueResultException (respectively) should be thrown in accordance with section 3.6.1 of the JPA spec. Instead, we appear to throw a org.apache.openjpa.persistence.InvalidStateException:

org.apache.openjpa.persistence.InvalidStateException: The query on candidate type "class com.sun.ts.tests.ejb30.persistence.query.apitests.Department" with filter "select d.name from Department d where d.id > 1" was configured to have a unique result, but more than one instance matched the query.
     at org.apache.openjpa.kernel.QueryImpl.singleResult(QueryImpl.java:1282)
     at org.apache.openjpa.kernel.QueryImpl.toResult(QueryImpl.java:1207)
     at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:982)
     at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:791)
     at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:761)
     at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:757)
     at org.apache.openjpa.kernel.DelegatingQuery.execute(DelegatingQuery.java:514)
     at org.apache.openjpa.persistence.QueryImpl.execute(QueryImpl.java:225)
     at org.apache.openjpa.persistence.QueryImpl.getSingleResult(QueryImpl.java:287)


 All   Comments   Work Log   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order

Marc Prud'hommeaux added a comment - 06/Apr/07 10:33 PM
This appears to have been introduced by the commits for the fix for OPENJPA-168.

Marc Prud'hommeaux added a comment - 06/Apr/07 10:48 PM
The change to OPENJPA-168 seems to have been done to make the validation of a single result a little cleaner by having the kernel query perform the validation that there is a single result. However, this meant that we could only do generic exception translation, and so were no longer throwing a NoResultException or NonUniqueResultException. We could fix this by introducing a could new kernel exceptions or exception types, but it might just be easier to revert to having the validation done in the persistence QueryImpl.

Any objections to fixing this the easy way?

Marc Prud'hommeaux added a comment - 06/Apr/07 11:33 PM
Went ahead and restored the previous behavior where the QueryImpl itself checks for non-uniqueness and throws the expected exception.

Marc Prud'hommeaux added a comment - 09/Apr/07 04:42 PM
From Abe on mailing list: That breaks the single result optimization that was added for OPENJPA-168 when getSingleResult() is called. There was a reason we moved the validation to the kernel. The previous code was correct. You need to use the "hard" way of creating new exception types.

Marc Prud'hommeaux added a comment - 09/Apr/07 05:06 PM
Added NoResultException and NonUniqueResultException to kernel to allow the identification of the case where a unique result was selected by either none or too many were found