Having the following entities:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class TestClassSuper implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String text;
private Date date;
private BigDecimal number;
....
}
@Entity
public class TestClassA extends TestClassSuper {
private static final long serialVersionUID = 1L;
private Long id;
....
}
@Entity
public class TestClassB extends TestClassSuper {
private static final long serialVersionUID = 1L;
private Long id;
....
}
The following HQL:
SELECT a.id
FROM org.hibernate.bugs.testclassa a
LEFT JOIN org.hibernate.bugs.testclassa c
ON a.id = c.id AND c.date = :date
LEFT JOIN org.hibernate.bugs.testclassb b
ON a.id = b.id AND a.text = :text
Produces the SQL:
SELECT testclassa0_.id AS col_0_0_
FROM testclassa testclassa0_
INNER JOIN testclasssuper testclassa0_1_
ON testclassa0_.id = testclassa0_1_.id
LEFT OUTER JOIN ( testclassa testclassa1_
INNER JOIN testclasssuper testclassa1_1_
ON testclassa1_.id = testclassa1_1_.id )
ON ( testclassa0_.id = testclassa1_.id
AND testclassa1_1_.date = ? )
LEFT OUTER JOIN ( testclassb testclassb2_
INNER JOIN testclasssuper testclassb2_1_
ON testclassb2_.id = testclassb2_1_.id )
ON ( testclassa0_.id = testclassb2_.id
AND testclassa0_1_.text = ? )
However, by changing the first LEFT JOIN to INNER JOIN in the HQL:
SELECT a.id
FROM org.hibernate.bugs.testclassa a
INNER JOIN org.hibernate.bugs.testclassa c
ON a.id = c.id AND c.date = :date
LEFT JOIN org.hibernate.bugs.testclassb b
ON a.id = b.id AND a.text = :text
Produces the SQL:
SELECT testclassa0_.id AS col_0_0_
FROM testclassa testclassa0_
INNER JOIN testclasssuper testclassa0_1_
ON testclassa0_.id = testclassa0_1_.id
INNER JOIN testclassa testclassa1_
ON 1 = 1
INNER JOIN testclasssuper testclassa1_1_
ON testclassa1_.id = testclassa1_1_.id
LEFT OUTER JOIN ( testclassb testclassb2_
INNER JOIN testclasssuper testclassb2_1_
ON testclassb2_.id = testclassb2_1_.id )
ON ( testclassa0_.id = testclassb2_.id
AND testclassa0_1_.text = ? )
WHERE ( testclassa0_.id = testclassa1_.id
AND testclassa1_1_.date = ? )
The parameter sequence has changed! In the first query the parameter sequence in the query is: date, text. In the second query the parameter sequence in the query is: text, date. But the binding order for the second query is the same as the first query, thus the cast exception on SQL Server:
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Conversion failed when converting date and/or time from character string.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:265)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet$FetchBuffer.nextRow(SQLServerResultSet.java:5479)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet.fetchBufferNext(SQLServerResultSet.java:1798)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet.next(SQLServerResultSet.java:1056)
at org.hibernate.loader.Loader.getRowsFromResultSet(Loader.java:1043)
at org.hibernate.loader.Loader.processResultSet(Loader.java:998)
at org.hibernate.loader.Loader.doQuery(Loader.java:967)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:357)
at org.hibernate.loader.Loader.doList(Loader.java:2868)
Hibernate is binding the parameter of type ‘date’ into the binding position ‘0', but the ‘date’ parameter position has changed to the binding position '1’. Attached is a test case, however I couldn’t reproduce with H2 database. My guess is that H2 doesn’t care, because the generated SQL is identical. |