I traced this into org.hibernate.hql.ast.tree.FromElementType.toColumns() where it is deciding whether to qualify the column reference with the tableAlias. In my case, where I'm doing update and delete statements with a joined subclass, I believe it incorrectly chooses not to qualify the column reference. It seems to me that when the FromElementType class is dealing with the WHERE clause of an UPDATE or DELETE statement and is dealing with a joined subclass entity, it should qualify the column reference.
I made the following modifications to FromElementType locally to try it out:
Code:
~/src/hibernate-trunk> svn diff src/org/hibernate/hql/ast/tree/FromElementType.java
Index: src/org/hibernate/hql/ast/tree/FromElementType.java
===================================================================
--- src/org/hibernate/hql/ast/tree/FromElementType.java (revision 11097)
+++ src/org/hibernate/hql/ast/tree/FromElementType.java (working copy)
@@ -343,6 +343,16 @@
return propertyMapping.toColumns( tableAlias, path );
}
}
+ else if ( fromElement.getWalker().getStatementType() == HqlSqlTokenTypes.UPDATE &&
+ fromElement.getEntityPersister() instanceof JoinedSubclassEntityPersister &&
+ fromElement.getWalker().getCurrentClauseType() == HqlSqlTokenTypes.WHERE) {
+ return propertyMapping.toColumns( tableAlias, path );
+ }
+ else if ( fromElement.getWalker().getStatementType() == HqlSqlTokenTypes.DELETE &&
+ fromElement.getEntityPersister() instanceof JoinedSubclassEntityPersister &&
+ fromElement.getWalker().getCurrentClauseType() == HqlSqlTokenTypes.WHERE) {
+ return propertyMapping.toColumns( tableAlias, path );
+ }
else {
String[] columns = propertyMapping.toColumns( path );
log.trace( "Using non-qualified column reference [" + path + " -> (" + ArrayHelper.toString( columns ) + ")]" );
This fixes the problem I am seeing and as a bonus, it hasn't broken anything else in my application (at least not that I've found yet). I've run it against SQL Server 2005 and Sybase ASA 9.0.2/10.. The generated SQL is now:
Code:
insert into #B select b0_.id as id from B b0_ inner join A b0_1_ on b0_.id=b0_1_.id where b0_.id=1
update B set myValue=10 where (id) IN (select id from #B)
which SQL Server accepts.
This is my first foray into the inner workings of Hibernate. Can anyone give me any feedback about whether or not I'm on the right track? I don't pretend to know if this change is complete and correct in all cases, or even if it's in keeping with the intent of the method. I would really appreciate if an expert would look at it and see if I'm on to something. I'd be happy to provide simple working code that causes the exception I'm getting from SQL Server.