I have run into a bug in 3.6.10.Final that I can replicate and
describe, but I'm not sure how to generate a useful automated test
case (the application I'm working on is using Spring/JPA/Hibernate,
and I don't know how to set up the test sessions and such by hand).
I've traced the bug to DotNode#dereferenceEntity, and I may be able to
debug it further after I garbage-collect my head.
Our use case: We have a class of JPA entity that contains some basic
data. A handful of these entities have some extended data, and so we
have a separate class with a FK reference back to the basic class
(since most of the entities don't have extended data) and a mapped
Java field from the basic to the extended. The classes look like this
(plus Roo ITDs):
@Entity public class BasicData {
@Id private long id;
@Embedded private String basicInfo;
@OneToOne(mappedBy="basic") private ExtendedData extended;
}
@Entity public class ExtendedData {
@Id private long id;
@Embedded private String extendedInfo
@OneToOne private BasicData basic;
}
Standard JPA field navigation works fine; we can look up either class
by PK using EntityManager#find and can navigate back and forth. The
generated DDL is what we expect.
However, the JPQL query "SELECT b from BasicData WHERE b.extended IS
NULL" is compiled incorrectly: The correct SQL is something like
"SELECT * FROM BasicData LEFT JOIN Extended ON BasicData.ID =
Extended.BASIC WHERE Extended.BASIC IS NULL", but Hibernate generates
"SELECT * FROM BasicData WHERE BasicData.ID IS NULL", which of course
returns no records.
When I turn up AST logging, I get this line:
'15:32:26.242 DEBUG org.hibernate.hql.ast.tree.DotNode -
dereferenceShortcut() : property extended in BasicData does not
require a join.'
It appears that the AST is trying to optimize away the join and is
incorrectly believing that it's okay. I am happy to help create a
test case and to debug the AST analyzer on my end if that will help,
but I'm not sure where to start (since I'm using JPA and not direct
Hibernate).
--
Christopher Smith, CCNP, CCDP, MCP, LPIC-1
Sphere Systems
Show replies by date
An update: If I manually set "joinIsNeeded=true" in the debugger to
force it to generate a join, the generated join is a cross join, which
I believe is incorrect for this "IS NULL" query. I think what's
tripping up the parser is that "IS NULL" on a mapped field means
something different from "IS NULL" on any column field--or does
JPQL/HQL not permit the sort of query I'm trying to run?
--
Christopher Smith, CCNP, CCDP, MCP, LPIC-1
Sphere Systems