Having the following entities:
{code:java}@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;
....
}{code}
The following HQL:
{code:sql}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{code}
Produces the SQL:
{code: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 = ? ){code}
However, by changing the first LEFT JOIN to INNER JOIN in the HQL:
{code:sql}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{code}
Produces the SQL:
{code: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 = ? ){code}
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:
{code:java}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){code}
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-.
Attached a new test case (TestCase-ParametersOutOfOrder-2.tar.gz), much simpler and works with H2 database.
This new test case may increase the severity of the bug, because it can silently return the wrong results in query. |
|