716 words

Issue #226 - [ObjectDB 2.5.5_03] Unexpected exception (Error 990)

BugVersion: Priority: NormalStatus: FixedReplies: 9
#1
2014-05-27 15:14

Hello!

When I run this query

SELECT t FROM Unit t
WHERE t.lastGeocodedPosition IS NULL OR
      t.lastGeocodedPosition.receiveTime < :lastGeocodedPosition.receiveTime

I get the following exception:

[ObjectDB 2.5.5_03] Unexpected exception (Error 990)
  Generated by Java HotSpot(TM) 64-Bit Server VM 1.7.0_55 (on Linux 3.13.0-27-generic).
Please report this error on http://www.objectdb.com/database/issue/new
com.objectdb.o.InternalException: null
com.objectdb.o.InternalException
at com.objectdb.o.QNF.C(QNF.java:920)
at com.objectdb.o.QNF.z(QNF.java:789)
at com.objectdb.o.QNF.k(QNF.java:258)
at com.objectdb.o.QNF.q(QNF.java:524)
at com.objectdb.o.QNF.k(QNF.java:189)
at com.objectdb.o.QNF.t(QNF.java:611)
at com.objectdb.o.QNF.t(QNF.java:605)
at com.objectdb.o.QNF.k(QNF.java:218)
at com.objectdb.o.QNF.t(QNF.java:611)
at com.objectdb.o.QNF.t(QNF.java:605)
at com.objectdb.o.QNF.k(QNF.java:224)
at com.objectdb.o.QNF.j(QNF.java:135)
at com.objectdb.o.QRC.B(QRC.java:340)
at com.objectdb.o.QRC.x(QRC.java:231)
at com.objectdb.jpa.JpaQuery.analyzeQuery(JpaQuery.java:683)
at com.objectdb.jpa.JpaQuery.getHints(JpaQuery.java:275)
at com.objectdb.o.QRP.L(QRP.java:195)
at com.objectdb.o.QRP.T(QRP.java:723)
at com.objectdb.o.QRP.actionPerformed(QRP.java:686)

Am I doing something wrong?

Regards

Ralph

mosi0815
mosi0815's picture
Joined on 2011-10-08
User Post #32
#2
2014-05-29 13:22

Maybe the type of the parameter (:lastGeocodedPosition) is unknown, so ObjectDB cannot search for field receiveTime in that object (although a better error message is required of course).

Try the following query:

SELECT t FROM Unit t
WHERE t.lastGeocodedPosition IS NULL OR
      t.lastGeocodedPosition.receiveTime < :receiveTime

and send time rather than an entity as a parameter.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
support
support's picture
Joined on 2010-05-03
User Post #1,906
#3
2014-05-30 20:23

You are absolutely right. This query works. Actually I passed a date parameter before but my WHERE clause generator simply took the filed name as parameter name. Normally some random characters are appended to the parameter name. A real world query looks like this:

SELECT t FROM Unit t WHERE (t.lastGeocodedPosition IS NULL OR t.lastGeocodedPosition.receiveTime < :lastGeocodedPosition.receiveTime1u6kopqt6zmjo)

Then a date is set on ":lastGeocodedPosition.receiveTime1u6kopqt6zmjo".

Obviously ObjectDB only takes ":lastGeocodedPosition" as parameter name and tries to get receiveTime1u6kopqt6zmjo from the not set parameter.

I'll change my WHERE clause generator to remove dots from parameter names. Then it should also work with nested fields.

Maybe you should implement a better exception for trying to retrieve a field of a not set parameter.

Thanks for your help

Ralph

mosi0815
mosi0815's picture
Joined on 2011-10-08
User Post #33
#4
2014-05-30 20:39

I now did some more tests. It's strange.

I think the two attached screenshots show it pretty well. All lastGeocodedPosition fields are null  BTW.

Should I open a forum thread or another issue for this problem or is it related to the other error?

mosi0815
mosi0815's picture
Joined on 2011-10-08
User Post #34
#5
2014-05-31 20:46

It seems that the expression in the WHERE clause fails with NPE for all the objects, and therefore no objects are returned from the query.

If it was a Java expression you wouldn't have NPE, because OR is evaluated from left to right.

I am not sure if this should be the case with queries (in JPQL or SQL) because expressions are reordered as part of the query optimization.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
support
support's picture
Joined on 2010-05-03
User Post #1,911
#6
2014-05-31 21:12

I did some research on this topic. The NULL handling of JPQL or SQL queries is well defined.

Have a look at the Persistence 2.0 specification: http://download.oracle.com/otndocs/jcp/persistence-2.0-fr-eval-oth-JSpec/
T
he chapter dealing with null handling starts on page 168. It's derived from SQL99 to which most RDBMS claim to be compatible.

Let's analyze my query:
Page 168 states: • Comparison or arithmetic operations with a NULL value always yield an unknown value.
Hence t.lastGeocodedPosition.receiveTime < :receiveTime with a NULL value evaluates to UNKNOWN.

The OR table on page 169 states that TRUE AND UNKNOWN = TRUE
t.lastGeocodedPosition IS NULL evaluates to TRUE hence the WHERE clause should be TRUE.

mosi0815
mosi0815's picture
Joined on 2011-10-08
User Post #35
#7
2014-05-31 22:07

NULL < :receiveTime is UNKNOWN, because it is comparison with NULL.

But t.lastGeocodedPosition.receiveTime is not NULL but NPE so you do not compare null.

Accessing fields through a null expression is very different from comparison and arithmetic operations.

I think that according to the JPA specification, your query is equivalent to:

SELECT t
FROM Unit t INNER JOIN t.lastGeocodedPosition l
WHERE l IS NULL OR l.receiveTime < :last

and since there is no t.lastGeocodedPosition there are no results.

Maybe you should try:

SELECT t
FROM Unit t LEFT OUTER JOIN t.lastGeocodedPosition l
WHERE l.receiveTime < :last

See also this paragraph in the manual.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
support
support's picture
Joined on 2010-05-03
User Post #1,912
#8
2014-06-01 13:39

I overlooked the NULL navigation thing. Sorry.

Your suggested query doesn't work but I modified it a little bit and now it does:

SELECT t
FROM Unit t LEFT OUTER JOIN t.lastGeocodedPosition l WHERE
l.receiveTime < :last OR l IS NULL

The question is why. l IS NULL clearly evaluates to true on every record currently in my DB  but l.receiveTime should again lead to a NPE or am I wrong?

mosi0815
mosi0815's picture
Joined on 2011-10-08
User Post #36
#9
2014-06-01 18:30

You are right, and actually NPE is not really defined in the JPA spec. I think that accessing a value field using a NULL reference is evaluated to either NULL or UNKNOWN,  Accessing an entity is a different story because it implicitly defines an INNER JOIN, i.e. an internal loop, and if the the internal loop is empty for a specific Unit, that Unit is ignored. So there is a difference between NPE as a result of accessing a value field and NPE as a result of accessing a relationship.

We implemented a better error message for the exception in your original post (will be released in a new build shortly), so this issue can be closed now.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
support
support's picture
Joined on 2010-05-03
User Post #1,913
#10
2014-06-02 09:06
ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
support
support's picture
Joined on 2010-05-03
User Post #1,920

Post Reply

Please read carefully the posting instructions - before posting to the ObjectDB website.

  • You may have to disable pop up blocking in order to use the toolbar (e.g. in Chrome).
  • Use ctrl + right click to open the browser context menu in the editing area (e.g. for using a browser spell checker).
  • To insert formatted lines (e.g. Java code, stack trace) - select a style in the toolbar and then insert the text in the new created block.
  • Avoid overflow of published source code examples by breaking long lines.
  • You may mark in paragraph code words (e.g. class names) with the code style (can be applied by ctrl + D).
  • Long stack traces (> 50 lines) and complex source examples (> 100 lines) should be posted as attachments.
Attachments:
Maximum file size: 32 MB
Cancel