Hi, I believe I have found a bug in the JPQLParser class, but I'm not entirely sure.
Considering a User class, with a nullable 1-1 link to a UserAccount class, and a collection of Contract objects in the UserAccount class, and a JPQL query with the following form:
SELECT u FROM package.to.my.class.User u LEFT JOIN u.userAccount ua WHERE ua.contracts IS EMPTY
The code that parses the "IS EMPTY" clause is as follows (JPQLParser.processRelationalExpression()):
else if (lexer.parseStringIgnoreCase("EMPTY"))
Debugging through this code, I find that there is a variable "inputRootNode" which essentially contains ua.contracts, and the variable "inputNode" only contains the last part of this chain, in this case "contracts". However, in the else if statement to handle "EMPTY", the isEmptyNode appends inputNode as a child, instead of inputRootNode, which causes the node structure to end up like this:
[OPERATOR : ==.
[IDENTIFIER : contracts.
[INVOKE : size]],
[LITERAL : 0]]
Notice how we lost the "ua." prefix for contracts. Then, at the end of the query compilation, we get a NucleusUserException, with the message "Class name contracts could not be resolved".