Class ComplexJoinAliasTest

  extended by org.hibernate.testing.junit4.BaseUnitTestCase
      extended by org.hibernate.testing.junit4.BaseCoreFunctionalTestCase
          extended by org.hibernate.test.criteria.ComplexJoinAliasTest

public class ComplexJoinAliasTest
extends BaseCoreFunctionalTestCase

Hibernate generates the wrong alias on a Criteria query involving a join on a composite identifier. For example, in the test below without the fix to JoinWalker, it generates this SQL: select this_.role_code as role1_0_1_, this_.is_deleted as is2_0_1_, this_.record_version as record3_0_1_, complexjoi3_.code as code1_0_, complexjoi3_.is_deleted as is2_1_0_, complexjoi3_.record_version as record3_1_0_ from list_action_roles this_ left outer join roles complexjoi3_ on this_.role_code=complexjoi3_.code where this_.is_deleted=? and complexjoi1_.is_deleted=? Which results in this error from the SQL server: Unknown column 'complexjoi1_.is_deleted' in 'where clause' Analysis of the problem: The entity persister class with the composite identifier has a fake property for it, called "_identifierMapper" (see HbmBinder.bindCompositeId() and similarly in Annotations). This property name ends up in the path used by JoinWalker.walkEntityTree() when it calls walkComponentTree(). However that path is used by CriteriaJoinWalker.generateTableAlias() to look up the correct criteria (and hence the alias) from the translator, a CriteriaQueryTranslator. The alias was created in CriteriaQueryTranslator.createCriteriaSQLAliasMap for a Criteria without this extra _identifierMapper path component. So when CriteriaJoinWalker tries to use the path with _identifierMapper to look up the criteria to find the correct alias to use, in generateTableAlias(), it doesn't find one, so it generates a new alias. That new alias no longer matches the one that will be rendered out in the WHERE clause, so the WHERE clause will refer to table names using aliases that are not used anywhere else in the query, and the SQL server will fail to parse the statement. The solution appears to be to exclude "_identifierMapper" components in the alias path when building it. I don't know what other implications that might have, but it seems like an implementation nastiness that shouldn't be exposed.

Nested Class Summary
Nested classes/interfaces inherited from class org.hibernate.testing.junit4.BaseCoreFunctionalTestCase
Field Summary
Fields inherited from class org.hibernate.testing.junit4.BaseCoreFunctionalTestCase
Constructor Summary
Method Summary
protected  Class<?>[] getAnnotatedClasses()
 void testCriteriaThroughCompositeId()
Methods inherited from class org.hibernate.testing.junit4.BaseCoreFunctionalTestCase
addMappings, addMappings, afterConfigurationBuilt, afterConfigurationBuilt, afterSessionFactoryBuilt, afterTest, applyCacheSettings, assertAllDataRemoved, beforeTest, buildConfiguration, buildServiceRegistry, cleanupCache, cleanupTest, configuration, configure, constructConfiguration, createSchema, generateBootstrapRegistry, getAnnotatedPackages, getBaseForMappings, getCacheConcurrencyStrategy, getDialect, getMappings, getXmlFiles, onFailure, openSession, openSession, overrideCacheStrategy, prepareBasicRegistryBuilder, prepareBootstrapRegistryBuilder, prepareTest, readCommittedIsolationMaintained, rebuildSessionFactory, rebuildSessionFactoryOnError, serviceRegistry, sessionFactory
Methods inherited from class org.hibernate.testing.junit4.BaseUnitTestCase
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Constructor Detail


public ComplexJoinAliasTest()
Method Detail


protected Class<?>[] getAnnotatedClasses()
getAnnotatedClasses in class BaseCoreFunctionalTestCase


public void testCriteriaThroughCompositeId()
                                    throws Exception

Copyright © 2001-2012 Red Hat, Inc. All Rights Reserved.