I had the same problem and I think this is a sleep mode problem (not an error because the code does not fail). However, I have to dig deeper to make sure this is a problem.
Hibernate (at least in version 4, the version of which I am working on my project, in particular, 4.3.11) uses the concept of SPI, a long story: as an API that extends or changes the structure.
I took this opportunity to replace the org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory classes (this class is called by Hibernate and delegates the task of generating the SQL query) and org.hibernate.hql.internal.ast.QueryTranslatorImpl (This is a kind of inner class which is called by org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory and generates the actual SQL query). I did it as follows:
Replacement for org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory :
package org.hibernate.hql.internal.ast; import java.util.Map; import org.hibernate.engine.query.spi.EntityGraphQueryHint; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.hql.spi.QueryTranslator; public class NoDistinctInSQLASTQueryTranslatorFactory extends ASTQueryTranslatorFactory { @Override public QueryTranslator createQueryTranslator(String queryIdentifier, String queryString, Map filters, SessionFactoryImplementor factory, EntityGraphQueryHint entityGraphQueryHint) { return new NoDistinctInSQLQueryTranslatorImpl(queryIdentifier, queryString, filters, factory, entityGraphQueryHint); } }
Replacement for org.hibernate.hql.internal.ast.QueryTranslatorImpl :
package org.hibernate.hql.internal.ast; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.hibernate.HibernateException; import org.hibernate.MappingException; import org.hibernate.QueryException; import org.hibernate.ScrollableResults; import org.hibernate.engine.query.spi.EntityGraphQueryHint; import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.RowSelection; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.event.spi.EventSource; import org.hibernate.hql.internal.QueryExecutionRequestException; import org.hibernate.hql.internal.antlr.HqlSqlTokenTypes; import org.hibernate.hql.internal.antlr.HqlTokenTypes; import org.hibernate.hql.internal.antlr.SqlTokenTypes; import org.hibernate.hql.internal.ast.exec.BasicExecutor; import org.hibernate.hql.internal.ast.exec.DeleteExecutor; import org.hibernate.hql.internal.ast.exec.MultiTableDeleteExecutor; import org.hibernate.hql.internal.ast.exec.MultiTableUpdateExecutor; import org.hibernate.hql.internal.ast.exec.StatementExecutor; import org.hibernate.hql.internal.ast.tree.AggregatedSelectExpression; import org.hibernate.hql.internal.ast.tree.FromElement; import org.hibernate.hql.internal.ast.tree.InsertStatement; import org.hibernate.hql.internal.ast.tree.QueryNode; import org.hibernate.hql.internal.ast.tree.Statement; import org.hibernate.hql.internal.ast.util.ASTPrinter; import org.hibernate.hql.internal.ast.util.ASTUtil; import org.hibernate.hql.internal.ast.util.NodeTraverser; import org.hibernate.hql.spi.FilterTranslator; import org.hibernate.hql.spi.ParameterTranslations; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.collections.IdentitySet; import org.hibernate.loader.hql.QueryLoader; import org.hibernate.param.ParameterSpecification; import org.hibernate.persister.entity.Queryable; import org.hibernate.type.Type; import org.jboss.logging.Logger; import antlr.ANTLRException; import antlr.RecognitionException; import antlr.TokenStreamException; import antlr.collections.AST; public class NoDistinctInSQLQueryTranslatorImpl extends QueryTranslatorImpl implements FilterTranslator { private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, QueryTranslatorImpl.class.getName() ); private SessionFactoryImplementor factory; private final String queryIdentifier; private String hql; private boolean shallowQuery; private Map tokenReplacements;
If you follow the flow of code, you will notice that I just changed the private void generate(AST sqlAst) throws QueryException, RecognitionException and added the following lines:
//Hack: The distinct keywordis removed from the sql string to //avoid executing a distinct query in the DBMS when the distinct //is used in hql. sql = sql.replace("distinct", "");
What I am doing with this code is to remove the keyword from the generated SQL query.
After creating the classes above, I added the following line in the hibernate configuration file:
<property name="hibernate.query.factory_class">org.hibernate.hql.internal.ast.NoDistinctInSQLASTQueryTranslatorFactory</property>
This line tells hibernate to use my custom class to parse HQL queries and generate SQL queries without a separate keyword. Notice that I created my own classes in the same package as the original HQL parser.