alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Hibernate example source code file (HQLTest.java)

This example Hibernate source code file (HQLTest.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Hibernate tags/keywords

animal, animal, exception, exception, foo, human, human, io, pettingzoo, querysyntaxexception, simple, test, test, util, wrong, zoo

The Hibernate HQLTest.java source code

/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * Copyright (c) 2007-2011, Red Hat Inc. or third-party contributors as
 * indicated by the @author tags or express copyright attribution
 * statements applied by the authors.  All third-party contributions are
 * distributed under license by Red Hat Inc.
 *
 * This copyrighted material is made available to anyone wishing to use, modify,
 * copy, or redistribute it subject to the terms and conditions of the GNU
 * Lesser General Public License, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution; if not, write to:
 * Free Software Foundation, Inc.
 * 51 Franklin Street, Fifth Floor
 * Boston, MA  02110-1301  USA
 */
package org.hibernate.test.hql;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import antlr.RecognitionException;
import antlr.collections.AST;

import org.hibernate.QueryException;
import org.hibernate.dialect.DB2Dialect;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.dialect.HSQLDialect;
import org.hibernate.dialect.IngresDialect;
import org.hibernate.dialect.MySQLDialect;
import org.hibernate.dialect.Oracle8iDialect;
import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.dialect.Sybase11Dialect;
import org.hibernate.dialect.SybaseASE15Dialect;
import org.hibernate.dialect.SybaseAnywhereDialect;
import org.hibernate.dialect.SybaseDialect;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.engine.query.spi.HQLQueryPlan;
import org.hibernate.engine.query.spi.ReturnMetadata;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.hql.spi.QueryTranslator;
import org.hibernate.hql.spi.QueryTranslatorFactory;
import org.hibernate.hql.internal.antlr.HqlTokenTypes;
import org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory;
import org.hibernate.hql.internal.ast.DetailedSemanticException;
import org.hibernate.hql.internal.ast.QuerySyntaxException;
import org.hibernate.hql.internal.ast.QueryTranslatorImpl;
import org.hibernate.hql.internal.ast.SqlGenerator;
import org.hibernate.hql.internal.ast.tree.ConstructorNode;
import org.hibernate.hql.internal.ast.tree.DotNode;
import org.hibernate.hql.internal.ast.tree.FromReferenceNode;
import org.hibernate.hql.internal.ast.tree.IndexNode;
import org.hibernate.hql.internal.ast.tree.QueryNode;
import org.hibernate.hql.internal.ast.tree.SelectClause;
import org.hibernate.hql.internal.ast.util.ASTUtil;
import org.hibernate.type.CalendarDateType;
import org.hibernate.type.DoubleType;
import org.hibernate.type.StringType;

import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.FailureExpected;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.SkipForDialect;
import org.hibernate.testing.TestForIssue;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import org.junit.Test;

/**
 * Tests cases where the AST based query translator and the 'classic' query translator generate identical SQL.
 *
 * @author Gavin King
 */
public class HQLTest extends QueryTranslatorTestCase {
	@Override
	public boolean createSchema() {
		return false;
	}

	@Override
	public boolean rebuildSessionFactoryOnError() {
		return false;
	}

	@Override
	protected void prepareTest() throws Exception {
		super.prepareTest();
		SelectClause.VERSION2_SQL = true;
		DotNode.REGRESSION_STYLE_JOIN_SUPPRESSION = true;
		DotNode.ILLEGAL_COLL_DEREF_EXCP_BUILDER = new DotNode.IllegalCollectionDereferenceExceptionBuilder() {
			public QueryException buildIllegalCollectionDereferenceException(String propertyName, FromReferenceNode lhs) {
				throw new QueryException( "illegal syntax near collection: " + propertyName );
			}
		};
		SqlGenerator.REGRESSION_STYLE_CROSS_JOINS = true;
	}

	@Override
	protected void cleanupTest() throws Exception {
		SelectClause.VERSION2_SQL = false;
		DotNode.REGRESSION_STYLE_JOIN_SUPPRESSION = false;
		DotNode.ILLEGAL_COLL_DEREF_EXCP_BUILDER = DotNode.DEF_ILLEGAL_COLL_DEREF_EXCP_BUILDER;
		SqlGenerator.REGRESSION_STYLE_CROSS_JOINS = false;
		super.cleanupTest();
	}

	@Test
	public void testModulo() {
		assertTranslation( "from Animal a where a.bodyWeight % 2 = 0" );
	}

	@Test
	public void testInvalidCollectionDereferencesFail() {
		// should fail with the same exceptions (because of the DotNode.ILLEGAL_COLL_DEREF_EXCP_BUILDER injection)
		assertTranslation( "from Animal a where a.offspring.description = 'xyz'" );
		assertTranslation( "from Animal a where a.offspring.father.description = 'xyz'" );
	}
	
	@Test
	@FailureExpected( jiraKey = "N/A", message = "Lacking ClassicQueryTranslatorFactory support" )
    public void testRowValueConstructorSyntaxInInList2() {
        assertTranslation( "from LineItem l where l.id in (:idList)" );
		assertTranslation( "from LineItem l where l.id in :idList" );
    }

	@Test
	@RequiresDialectFeature( DialectChecks.SupportsRowValueConstructorSyntaxInInListCheck .class )
    public void testRowValueConstructorSyntaxInInList() {
		QueryTranslatorImpl translator = createNewQueryTranslator("from LineItem l where l.id in (?)");
		assertInExist("'in' should be translated to 'and'", false, translator);
		translator = createNewQueryTranslator("from LineItem l where l.id in ?");
		assertInExist("'in' should be translated to 'and'", false, translator);
		translator = createNewQueryTranslator("from LineItem l where l.id in (('a1',1,'b1'),('a2',2,'b2'))");
		assertInExist("'in' should be translated to 'and'", false, translator);
		translator = createNewQueryTranslator("from Animal a where a.id in (?)");
		assertInExist("only translate tuple with 'in' syntax", true, translator);
		translator = createNewQueryTranslator("from Animal a where a.id in ?");
		assertInExist("only translate tuple with 'in' syntax", true, translator);
		translator = createNewQueryTranslator("from LineItem l where l.id in (select a1 from Animal a1 left join a1.offspring o where a1.id = 1)");
		assertInExist("do not translate subqueries", true, translator);

    }

	private void assertInExist( String message, boolean expected, QueryTranslatorImpl translator ) {
		AST ast = translator.getSqlAST().getWalker().getAST();
		QueryNode queryNode = (QueryNode) ast;
		AST inNode = ASTUtil.findTypeInChildren( queryNode, HqlTokenTypes.IN );
		assertEquals( message, expected, inNode != null );
	}
    
	@Test
	public void testSubComponentReferences() {
		assertTranslation( "select c.address.zip.code from ComponentContainer c" );
		assertTranslation( "select c.address.zip from ComponentContainer c" );
		assertTranslation( "select c.address from ComponentContainer c" );
	}

	@Test
	public void testManyToAnyReferences() {
		assertTranslation( "from PropertySet p where p.someSpecificProperty.id is not null" );
		assertTranslation( "from PropertySet p join p.generalProperties gp where gp.id is not null" );
	}

	@Test
	public void testJoinFetchCollectionOfValues() {
		assertTranslation( "select h from Human as h join fetch h.nickNames" );
	}
	
	@Test
	public void testCollectionMemberDeclarations2() {
		assertTranslation( "from Customer c, in(c.orders) o" );
		assertTranslation( "from Customer c, in(c.orders) as o" );
		assertTranslation( "select c.name from Customer c, in(c.orders) as o where c.id = o.id.customerId" );
	}

	@Test
	@FailureExpected( jiraKey = "N/A", message = "Lacking ClassicQueryTranslatorFactory support" )
	public void testCollectionMemberDeclarations(){
		// both these two query translators throw exeptions for this HQL since
		// IN asks an alias, but the difference is that the error message from AST
		// contains the error token location (by lines and columns), which is hardly 
		// to get from Classic query translator --stliu
		assertTranslation( "from Customer c, in(c.orders)" ); 
	}

	@Test
	public void testCollectionJoinsInSubselect() {
		// caused by some goofiness in FromElementFactory that tries to
		// handle correlated subqueries (but fails miserably) even though this
		// is not a correlated subquery.  HHH-1248
		assertTranslation(
				"select a.id, a.description" +
				" from Animal a" +
				"       left join a.offspring" +
				" where a in (" +
				"       select a1 from Animal a1" +
				"           left join a1.offspring o" +
				"       where a1.id=1" +
		        ")"
		);
		assertTranslation(
				"select h.id, h.description" +
		        " from Human h" +
				"      left join h.friends" +
				" where h in (" +
				"      select h1" +
				"      from Human h1" +
				"          left join h1.friends f" +
				"      where h1.id=1" +
				")"
		);
	}

	@Test
	@FailureExpected( jiraKey = "N/A" )
	public void testEmptyInList() {
		assertTranslation( "select a from Animal a where a.description in ()" );
	}

	@Test
	public void testDateTimeArithmeticReturnTypesAndParameterGuessing() {
		QueryTranslatorImpl translator = createNewQueryTranslator( "select o.orderDate - o.orderDate from Order o" );
		assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length );
		assertEquals( "incorrect return type", DoubleType.INSTANCE, translator.getReturnTypes()[0] );
		translator = createNewQueryTranslator( "select o.orderDate + 2 from Order o" );
		assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length );
		assertEquals( "incorrect return type", CalendarDateType.INSTANCE, translator.getReturnTypes()[0] );
		translator = createNewQueryTranslator( "select o.orderDate -2 from Order o" );
		assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length );
		assertEquals( "incorrect return type", CalendarDateType.INSTANCE, translator.getReturnTypes()[0] );

		translator = createNewQueryTranslator( "from Order o where o.orderDate > ?" );
		assertEquals( "incorrect expected param type", CalendarDateType.INSTANCE, translator.getParameterTranslations().getOrdinalParameterExpectedType( 1 ) );

		translator = createNewQueryTranslator( "select o.orderDate + ? from Order o" );
		assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length );
		assertEquals( "incorrect return type", CalendarDateType.INSTANCE, translator.getReturnTypes()[0] );
		assertEquals( "incorrect expected param type", DoubleType.INSTANCE, translator.getParameterTranslations().getOrdinalParameterExpectedType( 1 ) );

	}

	@Test
	public void testReturnMetadata() {
		HQLQueryPlan plan = createQueryPlan( "from Animal a" );
		check( plan.getReturnMetadata(), false, true );

		plan = createQueryPlan( "select a as animal from Animal a" );
		check( plan.getReturnMetadata(), false, false );

		plan = createQueryPlan( "from java.lang.Object" );
		check( plan.getReturnMetadata(), true, true );

		plan = createQueryPlan( "select o as entity from java.lang.Object o" );
		check( plan.getReturnMetadata(), true, false );
	}

	private void check(
			ReturnMetadata returnMetadata,
	        boolean expectingEmptyTypes,
	        boolean expectingEmptyAliases) {
		assertNotNull( "null return metadata", returnMetadata );
		assertNotNull( "null return metadata - types", returnMetadata );
		assertEquals( "unexpected return size", 1, returnMetadata.getReturnTypes().length );
		if ( expectingEmptyTypes ) {
			assertNull( "non-empty types", returnMetadata.getReturnTypes()[0] );
		}
		else {
			assertNotNull( "empty types", returnMetadata.getReturnTypes()[0] );
		}
		if ( expectingEmptyAliases ) {
			assertNull( "non-empty aliases", returnMetadata.getReturnAliases() );
		}
		else {
			assertNotNull( "empty aliases", returnMetadata.getReturnAliases() );
			assertNotNull( "empty aliases", returnMetadata.getReturnAliases()[0] );
		}
	}

	@Test
	public void testImplicitJoinsAlongWithCartesianProduct() {
		DotNode.useThetaStyleImplicitJoins = true;
		assertTranslation( "select foo.foo from Foo foo, Foo foo2" );
		assertTranslation( "select foo.foo.foo from Foo foo, Foo foo2" );
		DotNode.useThetaStyleImplicitJoins = false;
	}

	@Test
	public void testSubselectBetween() {
		assertTranslation("from Animal x where (select max(a.bodyWeight) from Animal a) between :min and :max");
		assertTranslation("from Animal x where (select max(a.description) from Animal a) like 'big%'");
		assertTranslation("from Animal x where (select max(a.bodyWeight) from Animal a) is not null");
		assertTranslation("from Animal x where exists (select max(a.bodyWeight) from Animal a)");
		assertTranslation("from Animal x where (select max(a.bodyWeight) from Animal a) in (1,2,3)");
	}

	@Test
	public void testFetchOrderBy() {
		assertTranslation("from Animal a left outer join fetch a.offspring where a.mother.id = :mid order by a.description");
	}

	@Test
	public void testCollectionOrderBy() {
		assertTranslation("from Animal a join a.offspring o order by a.description");
		assertTranslation("from Animal a join fetch a.offspring order by a.description");
		assertTranslation("from Animal a join fetch a.offspring o order by o.description");
		assertTranslation("from Animal a join a.offspring o order by a.description, o.description");
	}

	@Test
	public void testExpressionWithParamInFunction() {
		assertTranslation("from Animal a where abs(a.bodyWeight-:param) < 2.0");
		assertTranslation("from Animal a where abs(:param - a.bodyWeight) < 2.0");
		assertTranslation("from Animal where abs(:x - :y) < 2.0");
		assertTranslation("from Animal where lower(upper(:foo)) like 'f%'");
		if ( ! ( getDialect() instanceof SybaseDialect ) &&  ! ( getDialect() instanceof Sybase11Dialect ) &&  ! ( getDialect() instanceof SybaseASE15Dialect ) && ! ( getDialect() instanceof SQLServerDialect ) ) {
			// Transact-SQL dialects (except SybaseAnywhereDialect) map the length function -> len; 
			// classic translator does not consider that *when nested*;
			// SybaseAnywhereDialect supports the length function

			assertTranslation("from Animal a where abs(abs(a.bodyWeight - 1.0 + :param) * abs(length('ffobar')-3)) = 3.0");
		}
		if ( !( getDialect() instanceof MySQLDialect ) && ! ( getDialect() instanceof SybaseDialect ) && ! ( getDialect() instanceof Sybase11Dialect ) && !( getDialect() instanceof SybaseASE15Dialect ) && ! ( getDialect() instanceof SybaseAnywhereDialect ) && ! ( getDialect() instanceof SQLServerDialect ) ) {
			assertTranslation("from Animal where lower(upper('foo') || upper(:bar)) like 'f%'");
		}
		if ( getDialect() instanceof PostgreSQLDialect ) {
			return;
		}
		assertTranslation("from Animal where abs(cast(1 as float) - cast(:param as float)) = 1.0");
	}

	@Test
	public void testCompositeKeysWithPropertyNamedId() {
		assertTranslation( "select e.id.id from EntityWithCrazyCompositeKey e" );
		assertTranslation( "select max(e.id.id) from EntityWithCrazyCompositeKey e" );
	}

	@Test
	@FailureExpected( jiraKey = "N/A", message = "Lacking ClassicQueryTranslatorFactory support" )
	public void testMaxindexHqlFunctionInElementAccessor() {
		//TODO: broken SQL
		//      steve (2005.10.06) - this is perfect SQL, but fairly different from the old parser
		//              tested : HSQLDB (1.8), Oracle8i
		assertTranslation( "select c from ContainerX c where c.manyToMany[ maxindex(c.manyToMany) ].count = 2" );
		assertTranslation( "select c from Container c where c.manyToMany[ maxIndex(c.manyToMany) ].count = 2" );
	}

	@Test
	@FailureExpected( jiraKey = "N/A", message = "Lacking ClassicQueryTranslatorFactory support" )
	public void testMultipleElementAccessorOperators() throws Exception {
		//TODO: broken SQL
		//      steve (2005.10.06) - Yes, this is all hosed ;)
		assertTranslation( "select c from ContainerX c where c.oneToMany[ c.manyToMany[0].count ].name = 's'" );
		assertTranslation( "select c from ContainerX c where c.manyToMany[ c.oneToMany[0].count ].name = 's'" );
	}

	@Test
	@FailureExpected( jiraKey = "N/A", message = "Parser output mismatch" )
	public void testKeyManyToOneJoin() {
		//TODO: new parser generates unnecessary joins (though the query results are correct)
		assertTranslation( "from Order o left join fetch o.lineItems li left join fetch li.product p" );
		assertTranslation( "from Outer o where o.id.master.id.sup.dudu is not null" );
		assertTranslation( "from Outer o where o.id.master.id.sup.dudu is not null" );
	}

	@Test
	@FailureExpected( jiraKey = "N/A", message = "Parser output mismatch" )
	public void testDuplicateExplicitJoin() throws Exception {
		//very minor issue with select clause:
		assertTranslation( "from Animal a join a.mother m1 join a.mother m2" );
		assertTranslation( "from Zoo zoo join zoo.animals an join zoo.mammals m" );
		assertTranslation( "from Zoo zoo join zoo.mammals an join zoo.mammals m" );
	}

	@Test
	public void testIndexWithExplicitJoin() throws Exception {
		//TODO: broken on dialects with theta-style outerjoins:
		//      steve (2005.10.06) - this works perfectly for me on Oracle8i
		assertTranslation( "from Zoo zoo join zoo.animals an where zoo.mammals[ index(an) ] = an" );
		assertTranslation( "from Zoo zoo join zoo.mammals dog where zoo.mammals[ index(dog) ] = dog" );
		assertTranslation( "from Zoo zoo join zoo.mammals dog where dog = zoo.mammals[ index(dog) ]" );
	}

	@Test
	public void testOneToManyMapIndex() throws Exception {
		//TODO: this breaks on dialects with theta-style outerjoins:
		//      steve (2005.10.06) - this works perfectly for me on Oracle8i
		assertTranslation( "from Zoo zoo where zoo.mammals['dog'].description like '%black%'" );
		assertTranslation( "from Zoo zoo where zoo.mammals['dog'].father.description like '%black%'" );
		assertTranslation( "from Zoo zoo where zoo.mammals['dog'].father.id = 1234" );
		assertTranslation( "from Zoo zoo where zoo.animals['1234'].description like '%black%'" );
	}

	@Test
	public void testExplicitJoinMapIndex() throws Exception {
		//TODO: this breaks on dialects with theta-style outerjoins:
		//      steve (2005.10.06) - this works perfectly for me on Oracle8i
		assertTranslation( "from Zoo zoo, Dog dog where zoo.mammals['dog'] = dog" );
		assertTranslation( "from Zoo zoo join zoo.mammals dog where zoo.mammals['dog'] = dog" );
	}

	@Test
	public void testIndexFunction() throws Exception {
		// Instead of doing the pre-processor trick like the existing QueryTranslator, this
		// is handled by MethodNode.
		//      steve (2005.10.06) - this works perfectly for me on Oracle8i
		//TODO: broken on dialects with theta-style outerjoins:
		assertTranslation( "from Zoo zoo join zoo.mammals dog where index(dog) = 'dog'" );
		assertTranslation( "from Zoo zoo join zoo.animals an where index(an) = '1234'" );
	}

	@Test
	public void testSelectCollectionOfValues() throws Exception {
		//TODO: broken on dialects with theta-style joins
		///old parser had a bug where the collection element was not included in return types!
		//      steve (2005.10.06) - this works perfectly for me on Oracle8i
		assertTranslation( "select baz, date from Baz baz join baz.stringDateMap date where index(date) = 'foo'" );
	}

	@Test
	public void testCollectionOfValues() throws Exception {
		//old parser had a bug where the collection element was not returned!
		//TODO: broken on dialects with theta-style joins
		//      steve (2005.10.06) - this works perfectly for me on Oracle8i
		assertTranslation( "from Baz baz join baz.stringDateMap date where index(date) = 'foo'" );
	}

	@Test
	@TestForIssue( jiraKey = "HHH-719" )
    public void testHHH719() throws Exception {
        assertTranslation("from Baz b order by org.bazco.SpecialFunction(b.id)");
        assertTranslation("from Baz b order by anypackage.anyFunction(b.id)");
    }

	@Test
	public void testParameterListExpansion() {
		assertTranslation( "from Animal as animal where animal.id in (:idList_1, :idList_2)" );
	}

	@Test
	public void testComponentManyToOneDereferenceShortcut() {
		assertTranslation( "from Zoo z where z.address.stateProvince.id is null" );
	}

	@Test
	@TestForIssue( jiraKey = "HHH-770" )
	public void testNestedCollectionImplicitJoins() {
		assertTranslation( "select h.friends.offspring from Human h" );
	}

	@Test
	@TestForIssue( jiraKey = "HHH-557" )
	public void testExplicitJoinsInSubquery() {
		assertTranslation(
		        "from org.hibernate.test.hql.Animal as animal " +
		        "where animal.id in (" +
		        "        select a.id " +
		        "        from org.hibernate.test.hql.Animal as a " +
		        "               left join a.mother as mo" +
		        ")"
		);
	}

	@Test
	public void testImplicitJoinsInGroupBy() {
		assertTranslation(
		        "select o.mother.bodyWeight, count(distinct o) " +
		        "from Animal an " +
		        "   join an.offspring as o " +
		        "group by o.mother.bodyWeight"
		);
	}

	@Test
	public void testCrazyIdFieldNames() {
		DotNode.useThetaStyleImplicitJoins = true;
		// only regress against non-scalar forms as there appears to be a bug in the classic translator
		// in regards to this issue also.  Specifically, it interprets the wrong return type, though it gets
		// the sql "correct" :/

		String hql = "select e.heresAnotherCrazyIdFieldName from MoreCrazyIdFieldNameStuffEntity e where e.heresAnotherCrazyIdFieldName is not null";
		assertTranslation( hql, new HashMap(), false, null );

	    hql = "select e.heresAnotherCrazyIdFieldName.heresAnotherCrazyIdFieldName from MoreCrazyIdFieldNameStuffEntity e where e.heresAnotherCrazyIdFieldName is not null";
		assertTranslation( hql, new HashMap(), false, null );

		DotNode.useThetaStyleImplicitJoins = false;
	}

	@Test
	public void testSizeFunctionAndProperty() {
		assertTranslation("from Animal a where a.offspring.size > 0");
		assertTranslation("from Animal a join a.offspring where a.offspring.size > 1");
		assertTranslation("from Animal a where size(a.offspring) > 0");
		assertTranslation("from Animal a join a.offspring o where size(a.offspring) > 1");
		assertTranslation("from Animal a where size(a.offspring) > 1 and size(a.offspring) < 100");

		assertTranslation("from Human a where a.family.size > 0");
		assertTranslation("from Human a join a.family where a.family.size > 1");
		assertTranslation("from Human a where size(a.family) > 0");
		assertTranslation("from Human a join a.family o where size(a.family) > 1");
		assertTranslation("from Human a where a.family.size > 0 and a.family.size < 100");
	}

	@Test
	public void testFromOnly() throws Exception {
		// 2004-06-21 [jsd] This test now works with the new AST based QueryTranslatorImpl.
		assertTranslation( "from Animal" );
		assertTranslation( "from Model" );
	}

	@Test
	public void testJoinPathEndingInValueCollection() {
		assertTranslation( "select h from Human as h join h.nickNames as nn where h.nickName=:nn1 and (nn=:nn2 or nn=:nn3)" );
	}

	@Test
	@TestForIssue( jiraKey = "HHH-242" )
	public void testSerialJoinPathEndingInValueCollection() {
		assertTranslation( "select h from Human as h join h.friends as f join f.nickNames as nn where h.nickName=:nn1 and (nn=:nn2 or nn=:nn3)" );
	}

	@Test
	@TestForIssue( jiraKey = "HHH-281" )
	public void testImplicitJoinContainedByCollectionFunction() {
		assertTranslation( "from Human as h where 'shipping' in indices(h.father.addresses)" );
		assertTranslation( "from Human as h where 'shipping' in indices(h.father.father.addresses)" );
		assertTranslation( "from Human as h where 'sparky' in elements(h.father.nickNames)" );
		assertTranslation( "from Human as h where 'sparky' in elements(h.father.father.nickNames)" );
	}

	@Test
	@TestForIssue( jiraKey = "HHH-276" )
	public void testImpliedJoinInSubselectFrom() {
		assertTranslation( "from Animal a where exists( from a.mother.offspring )" );
	}

	@Test
	@TestForIssue( jiraKey = "HHH-276" )
	public void testSubselectImplicitJoins() {
		assertTranslation( "from Simple s where s = some( select sim from Simple sim where sim.other.count=s.other.count )" );
	}

	@Test
	public void testCollectionOfValuesSize() throws Exception {
		//SQL *was* missing a comma
		assertTranslation( "select size(baz.stringDateMap) from org.hibernate.test.legacy.Baz baz" );
	}

	@Test
	public void testCollectionFunctions() throws Exception {
		//these are both broken, a join that belongs in the subselect finds its way into the main query
		assertTranslation( "from Zoo zoo where size(zoo.animals) > 100" );
		assertTranslation( "from Zoo zoo where maxindex(zoo.mammals) = 'dog'" );
	}

	@Test
	public void testImplicitJoinInExplicitJoin() throws Exception {
		assertTranslation( "from Animal an inner join an.mother.mother gm" );
		assertTranslation( "from Animal an inner join an.mother.mother.mother ggm" );
		assertTranslation( "from Animal an inner join an.mother.mother.mother.mother gggm" );
	}

	@Test
	public void testImpliedManyToManyProperty() throws Exception {
		//missing a table join (SQL correct for a one-to-many, not for a many-to-many)
		assertTranslation( "select c from ContainerX c where c.manyToMany[0].name = 's'" );
	}

	@Test
	public void testCollectionSize() throws Exception {
		assertTranslation( "select size(zoo.animals) from Zoo zoo" );
	}

	@Test
	public void testFetchCollectionOfValues() throws Exception {
		assertTranslation( "from Baz baz left join fetch baz.stringSet" );
	}

	@Test
	public void testFetchList() throws Exception {
		assertTranslation( "from User u join fetch u.permissions" );
	}

	@Test
	public void testCollectionFetchWithExplicitThetaJoin() {
		assertTranslation( "select m from Master m1, Master m left join fetch m.details where m.name=m1.name" );
	}

	@Test
	public void testListElementFunctionInWhere() throws Exception {
		assertTranslation( "from User u where 'read' in elements(u.permissions)" );
		assertTranslation( "from User u where 'write' <> all elements(u.permissions)" );
	}

	@Test
	public void testManyToManyMaxElementFunctionInWhere() throws Exception {
		assertTranslation( "from Human human where 5 = maxelement(human.friends)" );
	}

	@Test
	public void testCollectionIndexFunctionsInWhere() throws Exception {
		assertTranslation( "from Zoo zoo where 4 = maxindex(zoo.animals)" );
		assertTranslation( "from Zoo zoo where 2 = minindex(zoo.animals)" );
	}

	@Test
	public void testCollectionIndicesInWhere() throws Exception {
		assertTranslation( "from Zoo zoo where 4 > some indices(zoo.animals)" );
		assertTranslation( "from Zoo zoo where 4 > all indices(zoo.animals)" );
	}

	@Test
	public void testIndicesInWhere() throws Exception {
		assertTranslation( "from Zoo zoo where 4 in indices(zoo.animals)" );
		assertTranslation( "from Zoo zoo where exists indices(zoo.animals)" );
	}

	@Test
	public void testCollectionElementInWhere() throws Exception {
		assertTranslation( "from Zoo zoo where 4 > some elements(zoo.animals)" );
		assertTranslation( "from Zoo zoo where 4 > all elements(zoo.animals)" );
	}

	@Test
	public void testElementsInWhere() throws Exception {
		assertTranslation( "from Zoo zoo where 4 in elements(zoo.animals)" );
		assertTranslation( "from Zoo zoo where exists elements(zoo.animals)" );
	}

	@Test
	public void testNull() throws Exception {
		assertTranslation( "from Human h where h.nickName is null" );
		assertTranslation( "from Human h where h.nickName is not null" );
	}

	@Test
	@SuppressWarnings( {"unchecked"})
	public void testSubstitutions() throws Exception {
		Map replacements = buildTrueFalseReplacementMapForDialect();
		replacements.put("yes", "'Y'");
		assertTranslation( "from Human h where h.pregnant = true", replacements );
		assertTranslation( "from Human h where h.pregnant = yes", replacements );
		assertTranslation( "from Human h where h.pregnant = foo", replacements );
	}

	@Test
	public void testWhere() throws Exception {
		assertTranslation( "from Animal an where an.bodyWeight > 10" );
		// 2004-06-26 [jsd] This one requires NOT GT => LE transform.
		assertTranslation( "from Animal an where not an.bodyWeight > 10" );
		assertTranslation( "from Animal an where an.bodyWeight between 0 and 10" );
		assertTranslation( "from Animal an where an.bodyWeight not between 0 and 10" );
		assertTranslation( "from Animal an where sqrt(an.bodyWeight)/2 > 10" );
		// 2004-06-27 [jsd] Recognize 'is null' properly.  Generate 'and' and 'or' as well.
		assertTranslation( "from Animal an where (an.bodyWeight > 10 and an.bodyWeight < 100) or an.bodyWeight is null" );
	}

	@Test
	public void testEscapedQuote() throws Exception {
		assertTranslation( "from Human h where h.nickName='1 ov''tha''few'");
	}

	@Test
	public void testCaseWhenElse() {
		assertTranslation(
				"from Human h where case when h.nickName='1ovthafew' then 'Gavin' when h.nickName='turin' then 'Christian' else h.nickName end = h.name.first"
		);
	}

	@Test
	public void testCaseExprWhenElse() {
		assertTranslation( "from Human h where case h.nickName when '1ovthafew' then 'Gavin' when 'turin' then 'Christian' else h.nickName end = h.name.first" );
	}

	@Test
	@SuppressWarnings( {"ThrowableResultOfMethodCallIgnored"})
	public void testInvalidHql() throws Exception {
		Exception newException = compileBadHql( "from Animal foo where an.bodyWeight > 10", false );
		assertTrue( "Wrong exception type!", newException instanceof QuerySyntaxException );
		newException = compileBadHql( "select an.name from Animal foo", false );
		assertTrue( "Wrong exception type!", newException instanceof QuerySyntaxException );
		newException = compileBadHql( "from Animal foo where an.verybogus > 10", false );
		assertTrue( "Wrong exception type!", newException instanceof QuerySyntaxException );
		newException = compileBadHql( "select an.boguspropertyname from Animal foo", false );
		assertTrue( "Wrong exception type!", newException instanceof QuerySyntaxException );
		newException = compileBadHql( "select an.name", false );
		assertTrue( "Wrong exception type!", newException instanceof QuerySyntaxException );
		newException = compileBadHql( "from Animal an where (((an.bodyWeight > 10 and an.bodyWeight < 100)) or an.bodyWeight is null", false );
		assertTrue( "Wrong exception type!", newException instanceof QuerySyntaxException );
		newException = compileBadHql( "from Animal an where an.bodyWeight is null where an.bodyWeight is null", false );
		assertTrue( "Wrong exception type!", newException instanceof QuerySyntaxException );
		newException = compileBadHql( "from where name='foo'", false );
		assertTrue( "Wrong exception type!", newException instanceof QuerySyntaxException );
		newException = compileBadHql( "from NonexistentClass where name='foo'", false );
		assertTrue( "Wrong exception type!", newException instanceof QuerySyntaxException );
		newException = compileBadHql( "select new FOO_BOGUS_Animal(an.description, an.bodyWeight) from Animal an", false );
		assertTrue( "Wrong exception type!", newException instanceof QuerySyntaxException );
		newException = compileBadHql( "select new Animal(an.description, an.bodyWeight, 666) from Animal an", false );
		assertTrue( "Wrong exception type!", newException instanceof QuerySyntaxException );

	}

	@Test
	public void testWhereBetween() throws Exception {
		assertTranslation( "from Animal an where an.bodyWeight between 1 and 10" );
	}

	@Test
	public void testConcatenation() {
		if ( getDialect() instanceof MySQLDialect || getDialect() instanceof SybaseDialect
				|| getDialect() instanceof Sybase11Dialect
				|| getDialect() instanceof SybaseASE15Dialect
				|| getDialect() instanceof SybaseAnywhereDialect
				|| getDialect() instanceof SQLServerDialect 
				|| getDialect() instanceof IngresDialect) {
			// SybaseASE15Dialect and SybaseAnywhereDialect support '||'
			// MySQL uses concat(x, y, z)
			// SQL Server replaces '||' with '+'
			//
			// this is syntax checked in {@link ASTParserLoadingTest#testConcatenation} 
			// Ingres supports both "||" and '+' but IngresDialect originally
			// uses '+' operator; updated Ingres9Dialect to use "||".
			return;
		}
		assertTranslation("from Human h where h.nickName = '1' || 'ov' || 'tha' || 'few'");
	}

	@Test
	public void testWhereLike() throws Exception {
		assertTranslation( "from Animal a where a.description like '%black%'" );
		assertTranslation( "from Animal an where an.description like '%fat%'" );
		assertTranslation( "from Animal an where lower(an.description) like '%fat%'" );
	}

	@Test
	public void testWhereIn() throws Exception {
		assertTranslation( "from Animal an where an.description in ('fat', 'skinny')" );
	}

	@Test
	public void testLiteralInFunction() throws Exception {
		assertTranslation( "from Animal an where an.bodyWeight > abs(5)" );
		assertTranslation( "from Animal an where an.bodyWeight > abs(-5)" );
	}

	@SuppressWarnings( {"unchecked"})
	@Test
	public void testExpressionInFunction() throws Exception {
		assertTranslation( "from Animal an where an.bodyWeight > abs(3-5)" );
		assertTranslation( "from Animal an where an.bodyWeight > abs(3/5)" );
		assertTranslation( "from Animal an where an.bodyWeight > abs(3+5)" );
		assertTranslation( "from Animal an where an.bodyWeight > abs(3*5)" );
		SQLFunction concat = sessionFactory().getSqlFunctionRegistry().findSQLFunction( "concat");
		List list = new ArrayList();
		list.add("'fat'");
		list.add("'skinny'");
		assertTranslation(
				"from Animal an where an.description = " +
						concat.render( StringType.INSTANCE, list, sessionFactory() )
		);
	}

	@Test
	public void testNotOrWhereClause() {
		assertTranslation( "from Simple s where 'foo'='bar' or not 'foo'='foo'" );
		assertTranslation( "from Simple s where 'foo'='bar' or not ('foo'='foo')" );
		assertTranslation( "from Simple s where not ( 'foo'='bar' or 'foo'='foo' )" );
		assertTranslation( "from Simple s where not ( 'foo'='bar' and 'foo'='foo' )" );
		assertTranslation( "from Simple s where not ( 'foo'='bar' and 'foo'='foo' ) or not ('x'='y')" );
		assertTranslation( "from Simple s where not ( 'foo'='bar' or 'foo'='foo' ) and not ('x'='y')" );
		assertTranslation( "from Simple s where not ( 'foo'='bar' or 'foo'='foo' ) and 'x'='y'" );
		assertTranslation( "from Simple s where not ( 'foo'='bar' and 'foo'='foo' ) or 'x'='y'" );
		assertTranslation( "from Simple s where 'foo'='bar' and 'foo'='foo' or not 'x'='y'" );
		assertTranslation( "from Simple s where 'foo'='bar' or 'foo'='foo' and not 'x'='y'" );
		assertTranslation( "from Simple s where ('foo'='bar' and 'foo'='foo') or 'x'='y'" );
		assertTranslation( "from Simple s where ('foo'='bar' or 'foo'='foo') and 'x'='y'" );
		assertTranslation( "from Simple s where not( upper( s.name ) ='yada' or 1=2 or 'foo'='bar' or not('foo'='foo') or 'foo' like 'bar' )" );
	}

	@Test
	public void testComplexExpressionInFunction() throws Exception {
		assertTranslation( "from Animal an where an.bodyWeight > abs((3-5)/4)" );
	}

	@Test
	public void testStandardFunctions() throws Exception {
		assertTranslation( "from Animal where current_date = current_time" );
		assertTranslation( "from Animal a where upper(a.description) = 'FAT'" );
		assertTranslation( "select lower(a.description) from Animal a" );
	}

	@Test
	public void testOrderBy() throws Exception {
		assertTranslation( "from Animal an order by an.bodyWeight" );
		assertTranslation( "from Animal an order by an.bodyWeight asc" );
		assertTranslation( "from Animal an order by an.bodyWeight desc" );
		assertTranslation( "from Animal an order by sqrt(an.bodyWeight*4)/2" );
		assertTranslation( "from Animal an order by an.mother.bodyWeight" );
		assertTranslation( "from Animal an order by an.bodyWeight, an.description" );
		assertTranslation( "from Animal an order by an.bodyWeight asc, an.description desc" );
		if ( getDialect() instanceof HSQLDialect || getDialect() instanceof DB2Dialect ) {
			assertTranslation( "from Human h order by sqrt(h.bodyWeight), year(h.birthdate)" );
		}
	}

	@Test
	public void testGroupByFunction() {
		if ( getDialect() instanceof Oracle8iDialect ) return; // the new hiearchy...
		if ( getDialect() instanceof PostgreSQLDialect ) return;
		if ( ! H2Dialect.class.isInstance( getDialect() ) ) {
			// H2 has no year function
			assertTranslation( "select count(*) from Human h group by year(h.birthdate)" );
			assertTranslation( "select count(*) from Human h group by year(sysdate)" );
		}
		assertTranslation( "select count(*) from Human h group by trunc( sqrt(h.bodyWeight*4)/2 )" );
	}

	@Test
	public void testPolymorphism() throws Exception {
		Map replacements = buildTrueFalseReplacementMapForDialect();
		assertTranslation( "from Mammal" );
		assertTranslation( "from Dog" );
		assertTranslation( "from Mammal m where m.pregnant = false and m.bodyWeight > 10", replacements );
		assertTranslation( "from Dog d where d.pregnant = false and d.bodyWeight > 10", replacements );
	}

	private Map buildTrueFalseReplacementMapForDialect() {
		HashMap replacements = new HashMap();
		try {
			String dialectTrueRepresentation = getDialect().toBooleanValueString( true );
			// if this call succeeds, then the dialect is saying to represent true/false as int values...
			Integer.parseInt( dialectTrueRepresentation );
			replacements.put( "true", "1" );
			replacements.put( "false", "0" );
		}
		catch( NumberFormatException nfe ) {
			// the Integer#parseInt call failed...
		}
		return replacements;
	}

	@Test
	public void testTokenReplacement() throws Exception {
		Map replacements = buildTrueFalseReplacementMapForDialect();
		assertTranslation( "from Mammal m where m.pregnant = false and m.bodyWeight > 10", replacements );
	}

	@Test
	public void testProduct() throws Exception {
		Map replacements = buildTrueFalseReplacementMapForDialect();
		assertTranslation( "from Animal, Animal" );
		assertTranslation( "from Animal x, Animal y where x.bodyWeight = y.bodyWeight" );
		assertTranslation( "from Animal x, Mammal y where x.bodyWeight = y.bodyWeight and not y.pregnant = true", replacements );
		assertTranslation( "from Mammal, Mammal" );
	}

	@Test
	public void testJoinedSubclassProduct() throws Exception {
		assertTranslation( "from PettingZoo, PettingZoo" ); //product of two subclasses
	}

	@Test
	public void testProjectProduct() throws Exception {
		assertTranslation( "select x from Human x, Human y where x.nickName = y.nickName" );
		assertTranslation( "select x, y from Human x, Human y where x.nickName = y.nickName" );
	}

	@Test
	public void testExplicitEntityJoins() throws Exception {
		assertTranslation( "from Animal an inner join an.mother mo" );
		assertTranslation( "from Animal an left outer join an.mother mo" );
		assertTranslation( "from Animal an left outer join fetch an.mother" );
	}

	@Test
	public void testMultipleExplicitEntityJoins() throws Exception {
		assertTranslation( "from Animal an inner join an.mother mo inner join mo.mother gm" );
		assertTranslation( "from Animal an left outer join an.mother mo left outer join mo.mother gm" );
		assertTranslation( "from Animal an inner join an.mother m inner join an.father f" );
		assertTranslation( "from Animal an left join fetch an.mother m left join fetch an.father f" );
	}

	@Test
	public void testMultipleExplicitJoins() throws Exception {
		assertTranslation( "from Animal an inner join an.mother mo inner join an.offspring os" );
		assertTranslation( "from Animal an left outer join an.mother mo left outer join an.offspring os" );
	}

	@Test
	public void testExplicitEntityJoinsWithRestriction() throws Exception {
		assertTranslation( "from Animal an inner join an.mother mo where an.bodyWeight < mo.bodyWeight" );
	}

	@Test
	public void testIdProperty() throws Exception {
		assertTranslation( "from Animal a where a.mother.id = 12" );
	}

	@Test
	public void testSubclassAssociation() throws Exception {
		assertTranslation( "from DomesticAnimal da join da.owner o where o.nickName = 'Gavin'" );
		assertTranslation( "from DomesticAnimal da left join fetch da.owner" );
		assertTranslation( "from Human h join h.pets p where p.pregnant = 1" );
		assertTranslation( "from Human h join h.pets p where p.bodyWeight > 100" );
		assertTranslation( "from Human h left join fetch h.pets" );
	}

	@Test
	public void testExplicitCollectionJoins() throws Exception {
		assertTranslation( "from Animal an inner join an.offspring os" );
		assertTranslation( "from Animal an left outer join an.offspring os" );
	}

	@Test
	public void testExplicitOuterJoinFetch() throws Exception {
		assertTranslation( "from Animal an left outer join fetch an.offspring" );
	}

	@Test
	public void testExplicitOuterJoinFetchWithSelect() throws Exception {
		assertTranslation( "select an from Animal an left outer join fetch an.offspring" );
	}

	@Test
	public void testExplicitJoins() throws Exception {
		Map replacements = buildTrueFalseReplacementMapForDialect();
		assertTranslation( "from Zoo zoo join zoo.mammals mam where mam.pregnant = true and mam.description like '%white%'", replacements );
		assertTranslation( "from Zoo zoo join zoo.animals an where an.description like '%white%'" );
	}

	@Test
	@TestForIssue( jiraKey = "HHH-559" )
    public void testMultibyteCharacterConstant() throws Exception {
        assertTranslation( "from Zoo zoo join zoo.animals an where an.description like '%\u4e2d%'" );
    }

	@Test
	public void testImplicitJoins() throws Exception {
		// Two dots...
		assertTranslation( "from Animal an where an.mother.bodyWeight > ?" );
		assertTranslation( "from Animal an where an.mother.bodyWeight > 10" );
		assertTranslation( "from Dog dog where dog.mother.bodyWeight > 10" );
		// Three dots...
		assertTranslation( "from Animal an where an.mother.mother.bodyWeight > 10" );
		// The new QT doesn't throw an exception here, so this belongs in ASTQueryTranslator test. [jsd]
//		assertTranslation( "from Animal an where an.offspring.mother.bodyWeight > 10" );
		// Is not null (unary postfix operator)
		assertTranslation( "from Animal an where an.mother is not null" );
		// ID property shortut (no implicit join)
		assertTranslation( "from Animal an where an.mother.id = 123" );
	}

	@Test
	public void testImplicitJoinInSelect() {
		assertTranslation( "select foo, foo.long from Foo foo" );
		DotNode.useThetaStyleImplicitJoins = true;
		assertTranslation( "select foo.foo from Foo foo" );
		assertTranslation( "select foo, foo.foo from Foo foo" );
		assertTranslation( "select foo.foo from Foo foo where foo.foo is not null" );
		DotNode.useThetaStyleImplicitJoins = false;
	}

	@Test
	public void testSelectExpressions() {
		DotNode.useThetaStyleImplicitJoins = true;
		assertTranslation( "select an.mother.mother from Animal an" );
		assertTranslation( "select an.mother.mother.mother from Animal an" );
		assertTranslation( "select an.mother.mother.bodyWeight from Animal an" );
		assertTranslation( "select an.mother.zoo.id from Animal an" );
		assertTranslation( "select user.human.zoo.id from User user" );
		assertTranslation( "select u.userName, u.human.name.first from User u" );
		assertTranslation( "select u.human.name.last, u.human.name.first from User u" );
		assertTranslation( "select bar.baz.name from Bar bar" );
		assertTranslation( "select bar.baz.name, bar.baz.count from Bar bar" );
		DotNode.useThetaStyleImplicitJoins = false;
	}

	@Test
	public void testSelectStandardFunctionsNoParens() throws Exception {
		assertTranslation( "select current_date, current_time, current_timestamp from Animal" );
	}

	@Test
	public void testMapIndex() throws Exception {
		assertTranslation( "from User u where u.permissions['hibernate']='read'" );
	}

	@Test
	public void testNamedParameters() throws Exception {
		assertTranslation( "from Animal an where an.mother.bodyWeight > :weight" );
	}

	@Test
	@SkipForDialect( Oracle8iDialect.class )
	public void testClassProperty() throws Exception {
		assertTranslation( "from Animal a where a.mother.class = Reptile" );
	}

	@Test
	public void testComponent() throws Exception {
		assertTranslation( "from Human h where h.name.first = 'Gavin'" );
	}

	@Test
	public void testSelectEntity() throws Exception {
		assertTranslation( "select an from Animal an inner join an.mother mo where an.bodyWeight < mo.bodyWeight" );
		assertTranslation( "select mo, an from Animal an inner join an.mother mo where an.bodyWeight < mo.bodyWeight" );
	}

	@Test
	public void testValueAggregate() {
		assertTranslation( "select max(p), min(p) from User u join u.permissions p" );
	}

	@Test
	public void testAggregation() throws Exception {
		assertTranslation( "select count(an) from Animal an" );
		assertTranslation( "select count(*) from Animal an" );
		assertTranslation( "select count(distinct an) from Animal an" );
		assertTranslation( "select count(distinct an.id) from Animal an" );
		assertTranslation( "select count(all an.id) from Animal an" );
	}

	@Test
	public void testSelectProperty() throws Exception {
		assertTranslation( "select an.bodyWeight, mo.bodyWeight from Animal an inner join an.mother mo where an.bodyWeight < mo.bodyWeight" );
	}

	@Test
	public void testSelectEntityProperty() throws Exception {
		DotNode.useThetaStyleImplicitJoins = true;
		assertTranslation( "select an.mother from Animal an" );
		assertTranslation( "select an, an.mother from Animal an" );
		DotNode.useThetaStyleImplicitJoins = false;
	}

	@Test
	public void testSelectDistinctAll() throws Exception {
		assertTranslation( "select distinct an.description, an.bodyWeight from Animal an" );
		assertTranslation( "select all an from Animal an" );
	}

	@Test
	public void testSelectAssociatedEntityId() throws Exception {
		assertTranslation( "select an.mother.id from Animal an" );
	}

	@Test
	public void testGroupBy() throws Exception {
		assertTranslation( "select an.mother.id, max(an.bodyWeight) from Animal an group by an.mother.id" );
		assertTranslation( "select an.mother.id, max(an.bodyWeight) from Animal an group by an.mother.id having max(an.bodyWeight)>1.0" );
	}

	@Test
	public void testGroupByMultiple() throws Exception {
		assertTranslation( "select s.id, s.count, count(t), max(t.date) from org.hibernate.test.legacy.Simple s, org.hibernate.test.legacy.Simple t where s.count = t.count group by s.id, s.count order by s.count" );
	}

	@Test
	public void testManyToMany() throws Exception {
		assertTranslation( "from Human h join h.friends f where f.nickName = 'Gavin'" );
		assertTranslation( "from Human h join h.friends f where f.bodyWeight > 100" );
	}

	@Test
	public void testManyToManyElementFunctionInWhere() throws Exception {
		assertTranslation( "from Human human where human in elements(human.friends)" );
		assertTranslation( "from Human human where human = some elements(human.friends)" );
	}

	@Test
	public void testManyToManyElementFunctionInWhere2() throws Exception {
		assertTranslation( "from Human h1, Human h2 where h2 in elements(h1.family)" );
		assertTranslation( "from Human h1, Human h2 where 'father' in indices(h1.family)" );
	}

	@Test
	public void testManyToManyFetch() throws Exception {
		assertTranslation( "from Human h left join fetch h.friends" );
	}

	@Test
	public void testManyToManyIndexAccessor() throws Exception {
		assertTranslation( "select c from ContainerX c, Simple s where c.manyToMany[2] = s" );
		assertTranslation( "select s from ContainerX c, Simple s where c.manyToMany[2] = s" );
		assertTranslation( "from ContainerX c, Simple s where c.manyToMany[2] = s" );
	}

	@Test
	public void testSelectNew() throws Exception {
		assertTranslation( "select new Animal(an.description, an.bodyWeight) from Animal an" );
		assertTranslation( "select new org.hibernate.test.hql.Animal(an.description, an.bodyWeight) from Animal an" );
	}

	@Test
	public void testSimpleCorrelatedSubselect() throws Exception {
		assertTranslation( "from Animal a where a.bodyWeight = (select o.bodyWeight from a.offspring o)" );
		assertTranslation( "from Animal a where a = (from a.offspring o)" );
	}

	@Test
	public void testSimpleUncorrelatedSubselect() throws Exception {
		assertTranslation( "from Animal a where a.bodyWeight = (select an.bodyWeight from Animal an)" );
		assertTranslation( "from Animal a where a = (from Animal an)" );
	}

	@Test
	public void testSimpleCorrelatedSubselect2() throws Exception {
		assertTranslation( "from Animal a where a = (select o from a.offspring o)" );
		assertTranslation( "from Animal a where a in (select o from a.offspring o)" );
	}

	@Test
	public void testSimpleUncorrelatedSubselect2() throws Exception {
		assertTranslation( "from Animal a where a = (select an from Animal an)" );
		assertTranslation( "from Animal a where a in (select an from Animal an)" );
	}

	@Test
	public void testUncorrelatedSubselect2() throws Exception {
		assertTranslation( "from Animal a where a.bodyWeight = (select max(an.bodyWeight) from Animal an)" );
	}

	@Test
	public void testCorrelatedSubselect2() throws Exception {
		assertTranslation( "from Animal a where a.bodyWeight > (select max(o.bodyWeight) from a.offspring o)" );
	}

	@Test
	public void testManyToManyJoinInSubselect() throws Exception {
		DotNode.useThetaStyleImplicitJoins = true;
		assertTranslation( "select foo from Foo foo where foo in (select elt from Baz baz join baz.fooArray elt)" );
		DotNode.useThetaStyleImplicitJoins = false;
	}

	@Test
	public void testImplicitJoinInSubselect() throws Exception {
		assertTranslation( "from Animal a where a = (select an.mother from Animal an)" );
		assertTranslation( "from Animal a where a.id = (select an.mother.id from Animal an)" );
	}

	@Test
	public void testManyToOneSubselect() {
		//TODO: the join in the subselect also shows up in the outer query!
		assertTranslation( "from Animal a where 'foo' in (select m.description from a.mother m)" );
	}

	@Test
	public void testPositionalParameters() throws Exception {
		assertTranslation( "from Animal an where an.bodyWeight > ?" );
	}

	@Test
	public void testKeywordPropertyName() throws Exception {
		assertTranslation( "from Glarch g order by g.order asc" );
		assertTranslation( "select g.order from Glarch g where g.order = 3" );
	}

	@Test
	public void testJavaConstant() throws Exception {
		assertTranslation( "from org.hibernate.test.legacy.Category c where c.name = org.hibernate.test.legacy.Category.ROOT_CATEGORY" );
		assertTranslation( "from org.hibernate.test.legacy.Category c where c.id = org.hibernate.test.legacy.Category.ROOT_ID" );
		// todo : additional desired functionality
		//assertTranslation( "from Category c where c.name = Category.ROOT_CATEGORY" );
		//assertTranslation( "select c.name, Category.ROOT_ID from Category as c");
	}

	@Test
	public void testClassName() throws Exception {
		// The Zoo reference is OK; Zoo is discriminator-based;
		// the old parser could handle these correctly
		//
		// However, the Animal one ares not; Animal is joined subclassing;
		// the old parser does not handle thee correctly.  The new parser
		// previously did not handle them correctly in that same way.  So they
		// used to pass regression even though the output was bogus SQL...
		//
		// I have moved the Animal ones (plus duplicating the Zoo one)
		// to ASTParserLoadingTest for syntax checking.
		assertTranslation( "from Zoo zoo where zoo.class = PettingZoo" );
//		assertTranslation( "from DomesticAnimal an where an.class = Dog" );
//		assertTranslation( "from Animal an where an.class = Dog" );
	}

	@Test
	public void testSelectDialectFunction() throws Exception {
		// From SQLFunctionsTest.testDialectSQLFunctions...
		if ( getDialect() instanceof HSQLDialect ) {
			assertTranslation( "select mod(s.count, 2) from org.hibernate.test.legacy.Simple as s where s.id = 10" );
			//assertTranslation( "from org.hibernate.test.legacy.Simple as s where mod(s.count, 2) = 0" );
		}
		assertTranslation( "select upper(human.name.first) from Human human" );
		assertTranslation( "from Human human where lower(human.name.first) like 'gav%'" );
		assertTranslation( "select upper(a.description) from Animal a" );
		assertTranslation( "select max(a.bodyWeight) from Animal a" );
	}

	@Test
	public void testTwoJoins() throws Exception {
		assertTranslation( "from Human human join human.friends, Human h join h.mother" );
		assertTranslation( "from Human human join human.friends f, Animal an join an.mother m where f=m" );
		assertTranslation( "from Baz baz left join baz.fooToGlarch, Bar bar join bar.foo" );
	}

	@Test
	public void testToOneToManyManyJoinSequence() throws Exception {
		assertTranslation( "from Dog d join d.owner h join h.friends f where f.name.first like 'joe%'" );
	}

	@Test
	public void testToOneToManyJoinSequence() throws Exception {
		assertTranslation( "from Animal a join a.mother m join m.offspring" );
		assertTranslation( "from Dog d join d.owner m join m.offspring" );
		assertTranslation( "from Animal a join a.mother m join m.offspring o where o.bodyWeight > a.bodyWeight" );
	}

	@Test
	public void testSubclassExplicitJoin() throws Exception {
		assertTranslation( "from DomesticAnimal da join da.owner o where o.nickName = 'gavin'" );
		assertTranslation( "from DomesticAnimal da join da.owner o where o.bodyWeight > 0" );
	}

	@Test
	public void testMultipleExplicitCollectionJoins() throws Exception {
		assertTranslation( "from Animal an inner join an.offspring os join os.offspring gc" );
		assertTranslation( "from Animal an left outer join an.offspring os left outer join os.offspring gc" );
	}

	@Test
	public void testSelectDistinctComposite() throws Exception {
		// This is from CompositeElementTest.testHandSQL.
		assertTranslation( "select distinct p from org.hibernate.test.compositeelement.Parent p join p.children c where c.name like 'Child%'" );
	}

	@Test
	public void testDotComponent() throws Exception {
		// from FumTest.testListIdentifiers()
		assertTranslation( "select fum.id from org.hibernate.test.legacy.Fum as fum where not fum.fum='FRIEND'" );
	}

	@Test
	public void testOrderByCount() throws Exception {
		assertTranslation( "from Animal an group by an.zoo.id order by an.zoo.id, count(*)" );
	}

	@Test
	public void testHavingCount() throws Exception {
		assertTranslation( "from Animal an group by an.zoo.id having count(an.zoo.id) > 1" );
	}

	@Test
	public void selectWhereElements() throws Exception {
		assertTranslation( "select foo from Foo foo, Baz baz where foo in elements(baz.fooArray)" );
	}

	@Test
	public void testCollectionOfComponents() throws Exception {
		assertTranslation( "from Baz baz inner join baz.components comp where comp.name='foo'" );
	}

	@Test
	public void testNestedComponentIsNull() {
		// From MapTest...
		assertTranslation( "from Commento c where c.marelo.commento.mcompr is null" );
	}

	@Test
	public void testOneToOneJoinedFetch() throws Exception {
		// From OneToOneTest.testOneToOneOnSubclass
		assertTranslation( "from org.hibernate.test.onetoone.joined.Person p join fetch p.address left join fetch p.mailingAddress" );
	}

	@Test
	public void testSubclassImplicitJoin() throws Exception {
		assertTranslation( "from DomesticAnimal da where da.owner.nickName like 'Gavin%'" );
		assertTranslation( "from DomesticAnimal da where da.owner.nickName = 'gavin'" );
		assertTranslation( "from DomesticAnimal da where da.owner.bodyWeight > 0" );
	}

	@Test
	public void testComponent2() throws Exception {
		assertTranslation( "from Dog dog where dog.owner.name.first = 'Gavin'" );
	}

	@Test
	public void testOneToOne() throws Exception {
		assertTranslation( "from User u where u.human.nickName='Steve'" );
		assertTranslation( "from User u where u.human.name.first='Steve'" );
	}

	@Test
	public void testSelectClauseImplicitJoin() throws Exception {
		//assertTranslation( "select d.owner.mother from Dog d" ); //bug in old qt
		assertTranslation( "select d.owner.mother.description from Dog d" );
		//assertTranslation( "select d.owner.mother from Dog d, Dog h" );
	}

	@Test
	public void testFromClauseImplicitJoin() throws Exception {
		assertTranslation( "from DomesticAnimal da join da.owner.mother m where m.bodyWeight > 10" );
	}

	@Test
	public void testJoinedSubclassWithOrCondition() {
		assertTranslation( "from Animal an where (an.bodyWeight > 10 and an.bodyWeight < 100) or an.bodyWeight is null" );
	}

	@Test
	public void testImplicitJoinInFrom() {
		assertTranslation( "from Human h join h.mother.mother.offspring o" );
	}

	@Test
	@SkipForDialect( Oracle8iDialect.class )
	public void testDuplicateImplicitJoinInSelect() {
		// This test causes failures on theta-join dialects because the SQL is different.  The old parser
		// duplicates the condition, whereas the new parser does not.  The queries are semantically the
		// same however.

// the classic translator handles this incorrectly; the explicit join and the implicit ones should create separate physical SQL joins...
//		assertTranslation( "select an.mother.bodyWeight from Animal an join an.mother m where an.mother.bodyWeight > 10" );
		assertTranslation( "select an.mother.bodyWeight from Animal an where an.mother.bodyWeight > 10" );
		//assertTranslation("select an.mother from Animal an where an.mother.bodyWeight is not null");
		assertTranslation( "select an.mother.bodyWeight from Animal an order by an.mother.bodyWeight" );
	}

	@Test
	public void testConstructorNode() throws Exception {
		ConstructorNode n = new ConstructorNode();
		assertNull( n.getFromElement() );
		assertFalse( n.isReturnableEntity() );
	}

	@Test
	public void testIndexNode() throws Exception {
		IndexNode n = new IndexNode();
		Exception ex = null;
		try {
			n.setScalarColumn( 0 );
		}
		catch ( UnsupportedOperationException e ) {
			ex = e;
		}
		assertNotNull( ex );
	}

	@Test
	public void testExceptions() throws Exception {
		DetailedSemanticException dse = new DetailedSemanticException( "test" );
		dse.printStackTrace();
		dse.printStackTrace( new PrintWriter( new StringWriter() ) );
		QuerySyntaxException qse = QuerySyntaxException.convert( new RecognitionException( "test" ), "from bozo b where b.clown = true" );
		assertNotNull( qse.getMessage() );
	}

	@Test
	public void testSelectProperty2() throws Exception {
		assertTranslation( "select an, mo.bodyWeight from Animal an inner join an.mother mo where an.bodyWeight < mo.bodyWeight" );
		assertTranslation( "select an, mo, an.bodyWeight, mo.bodyWeight from Animal an inner join an.mother mo where an.bodyWeight < mo.bodyWeight" );
	}

	@Test
	public void testSubclassWhere() throws Exception {
		// TODO: The classic QT generates lots of extra parens, etc.
		assertTranslation( "from PettingZoo pz1, PettingZoo pz2 where pz1.id = pz2.id" );
		assertTranslation( "from PettingZoo pz1, PettingZoo pz2 where pz1.id = pz2" );
		assertTranslation( "from PettingZoo pz where pz.id > 0 " );
	}

	@Test
	public void testNestedImplicitJoinsInSelect() throws Exception {
		// NOTE: This test is not likely to generate the exact SQL because of the where clause.  The synthetic
		// theta style joins come out differently in the new QT.
		// From FooBarTest.testQuery()
		// Missing the foo2_ join, and foo3_ should include subclasses, but it doesn't.
//		assertTranslation("select foo.foo.foo.foo.string from org.hibernate.test.legacy.Foo foo where foo.foo.foo = 'bar'");
		assertTranslation( "select foo.foo.foo.foo.string from org.hibernate.test.legacy.Foo foo" );
	}

	@Test
	public void testNestedComponent() throws Exception {
		// From FooBarTest.testQuery()
		//an extra set of parens in new SQL
		assertTranslation( "from org.hibernate.test.legacy.Foo foo where foo.component.subcomponent.name='bar'" );
	}

	@Test
	public void testNull2() throws Exception {
		//old parser generates useless extra parens
		assertTranslation( "from Human h where not( h.nickName is null )" );
		assertTranslation( "from Human h where not( h.nickName is not null )" );
	}

	@Test
	public void testUnknownFailureFromMultiTableTest() {
		assertTranslation( "from Lower s where s.yetanother.name='name'" );
	}

	@Test
	public void testJoinInSubselect() throws Exception {
		//new parser uses ANSI-style inner join syntax
		DotNode.useThetaStyleImplicitJoins = true;
		assertTranslation( "from Animal a where a in (select m from Animal an join an.mother m)" );
		assertTranslation( "from Animal a where a in (select o from Animal an join an.offspring o)" );
		DotNode.useThetaStyleImplicitJoins = false;
	}

	@Test
	public void testJoinedSubclassImplicitJoin() throws Exception {
		// From MultiTableTest.testQueries()
		// TODO: This produces the proper from clause now, but the parens in the where clause are different.
		assertTranslation( "from org.hibernate.test.legacy.Lower s where s.yetanother.name='name'" );
	}

	@Test
	public void testProjectProductJoinedSubclass() throws Exception {
		// TODO: The old QT generates the discriminator and the theta join in a strange order, and with two extra sets of parens, this is okay, right?
		assertTranslation( "select zoo from Zoo zoo, PettingZoo pz where zoo=pz" );
		assertTranslation( "select zoo, pz from Zoo zoo, PettingZoo pz where zoo=pz" );
	}

	@Test
	public void testCorrelatedSubselect1() throws Exception {
		// The old translator generates the theta join before the condition in the sub query.
		// TODO: Decide if we want to bother generating the theta join in the same order (non simple).
		assertTranslation( "from Animal a where exists (from a.offspring o where o.bodyWeight>10)" );
	}

	@Test
	public void testOuterAliasInSubselect() {
		assertTranslation( "from Human h where h = (from Animal an where an = h)" );
	}

	@Test
	public void testFetch() throws Exception {
		assertTranslation( "from Zoo zoo left join zoo.mammals" );
		assertTranslation( "from Zoo zoo left join fetch zoo.mammals" );
	}

	@Test
	public void testOneToManyElementFunctionInWhere() throws Exception {
		assertTranslation( "from Zoo zoo where 'dog' in indices(zoo.mammals)" );
		assertTranslation( "from Zoo zoo, Dog dog where dog in elements(zoo.mammals)" );
	}

	@Test
	public void testManyToManyInJoin() throws Exception {
		assertTranslation( "select x.id from Human h1 join h1.family x" );
		//assertTranslation("select index(h2) from Human h1 join h1.family h2");
	}

	@Test
	public void testManyToManyInSubselect() throws Exception {
		assertTranslation( "from Human h1, Human h2 where h2 in (select x.id from h1.family x)" );
		assertTranslation( "from Human h1, Human h2 where 'father' in indices(h1.family)" );
	}

	@Test
	public void testOneToManyIndexAccess() throws Exception {
		assertTranslation( "from Zoo zoo where zoo.mammals['dog'] is not null" );
	}

	@Test
	public void testImpliedSelect() throws Exception {
		assertTranslation( "select zoo from Zoo zoo" );
		assertTranslation( "from Zoo zoo" );
		assertTranslation( "from Zoo zoo join zoo.mammals m" );
		assertTranslation( "from Zoo" );
		assertTranslation( "from Zoo zoo join zoo.mammals" );
	}

	@Test
	public void testVectorSubselect() {
		assertTranslation( "from Animal a where ('foo', 'bar') in (select m.description, m.bodyWeight from a.mother m)" );
	}

	@Test
	public void testWierdSubselectImplicitJoinStuff() {
		//note that the new qt used to eliminate unnecessary join, but no more
		assertTranslation("from Simple s where s = some( select sim from Simple sim where sim.other.count=s.other.count ) and s.other.count > 0");
	}

	@Test
	public void testCollectionsInSelect2() throws Exception {
		// This one looks okay now, it just generates extra parens in the where clause.
		assertTranslation( "select foo.string from Bar bar left join bar.baz.fooArray foo where bar.string = foo.string" );
	}

	@Test
	public void testAssociationPropertyWithoutAlias() throws Exception {
		// The classic translator doesn't do this right, so don't bother asserting.
		compileWithAstQueryTranslator("from Animal where zoo is null", false);
	}

	private void compileWithAstQueryTranslator(String hql, boolean scalar) {
		Map replacements = new HashMap();
		QueryTranslatorFactory ast = new ASTQueryTranslatorFactory();
		SessionFactoryImplementor factory = getSessionFactoryImplementor();
		QueryTranslator newQueryTranslator = ast.createQueryTranslator( hql, hql, Collections.EMPTY_MAP, factory );
		newQueryTranslator.compile( replacements, scalar );
	}

	@Test
	public void testComponentNoAlias() throws Exception {
		// The classic translator doesn't do this right, so don't bother asserting.
		compileWithAstQueryTranslator( "from Human where name.first = 'Gavin'", false);
	}

}

Other Hibernate examples (source code examples)

Here is a short list of links related to this Hibernate HQLTest.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.