org.hibernate.query.criteria.internal.compile.CriteriaCompiler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hibernate-core Show documentation
Show all versions of hibernate-core Show documentation
Hibernate's core ORM functionality
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or .
*/
package org.hibernate.query.criteria.internal.compile;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.ParameterExpression;
import org.hibernate.SessionFactory;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.Stack;
import org.hibernate.internal.util.collections.StandardStack;
import org.hibernate.query.criteria.LiteralHandlingMode;
import org.hibernate.query.criteria.internal.expression.function.FunctionExpression;
import org.hibernate.query.spi.QueryImplementor;
import org.hibernate.sql.ast.Clause;
import org.hibernate.type.Type;
/**
* Compiles a JPA criteria query into an executable {@link TypedQuery}. Its single contract is the {@link #compile}
* method.
*
* NOTE : This is a temporary implementation which simply translates the criteria query into a JPAQL query string. A
* better, long-term solution is being implemented as part of refactoring the JPAQL/HQL translator.
*
* @author Steve Ebersole
*/
public class CriteriaCompiler implements Serializable {
private final SessionImplementor entityManager;
public CriteriaCompiler(SessionImplementor entityManager) {
this.entityManager = entityManager;
}
public QueryImplementor compile(CompilableCriteria criteria) {
try {
criteria.validate();
}
catch (IllegalStateException ise) {
throw new IllegalArgumentException( "Error occurred validating the Criteria", ise );
}
final Map, ExplicitParameterInfo> explicitParameterInfoMap = new HashMap<>();
final List implicitParameterBindings = new ArrayList<>();
final SessionFactoryImplementor sessionFactory = entityManager.getSessionFactory();
final LiteralHandlingMode criteriaLiteralHandlingMode = sessionFactory
.getSessionFactoryOptions()
.getCriteriaLiteralHandlingMode();
final Dialect dialect = sessionFactory.getServiceRegistry().getService( JdbcServices.class ).getDialect();
RenderingContext renderingContext = new RenderingContext() {
private int aliasCount;
private int explicitParameterCount;
private final Stack clauseStack = new StandardStack<>();
private final Stack functionContextStack = new StandardStack<>();
public String generateAlias() {
return "generatedAlias" + aliasCount++;
}
public String generateParameterName() {
return "param" + explicitParameterCount++;
}
@Override
public Stack getClauseStack() {
return clauseStack;
}
@Override
public Stack getFunctionStack() {
return functionContextStack;
}
@Override
@SuppressWarnings("unchecked")
public ExplicitParameterInfo registerExplicitParameter(ParameterExpression criteriaQueryParameter) {
ExplicitParameterInfo parameterInfo = explicitParameterInfoMap.get( criteriaQueryParameter );
if ( parameterInfo == null ) {
if ( StringHelper.isNotEmpty( criteriaQueryParameter.getName() ) ) {
parameterInfo = new ExplicitParameterInfo(
criteriaQueryParameter.getName(),
null,
criteriaQueryParameter.getJavaType()
);
}
else if ( criteriaQueryParameter.getPosition() != null ) {
parameterInfo = new ExplicitParameterInfo(
null,
criteriaQueryParameter.getPosition(),
criteriaQueryParameter.getJavaType()
);
}
else {
parameterInfo = new ExplicitParameterInfo(
generateParameterName(),
null,
criteriaQueryParameter.getJavaType()
);
}
explicitParameterInfoMap.put( criteriaQueryParameter, parameterInfo );
}
return parameterInfo;
}
public String registerLiteralParameterBinding(final Object literal, final Class javaType) {
final String parameterName = generateParameterName();
final ImplicitParameterBinding binding = new ImplicitParameterBinding() {
public String getParameterName() {
return parameterName;
}
public Class getJavaType() {
return javaType;
}
public void bind(TypedQuery typedQuery) {
typedQuery.setParameter( parameterName, literal );
}
};
implicitParameterBindings.add( binding );
return parameterName;
}
public String getCastType(Class javaType) {
SessionFactoryImplementor factory = entityManager.getFactory();
Type hibernateType = factory.getTypeResolver().heuristicType( javaType.getName() );
if ( hibernateType == null ) {
throw new IllegalArgumentException(
"Could not convert java type [" + javaType.getName() + "] to Hibernate type"
);
}
return hibernateType.getName();
}
@Override
public Dialect getDialect() {
return dialect;
}
@Override
public LiteralHandlingMode getCriteriaLiteralHandlingMode() {
return criteriaLiteralHandlingMode;
}
};
return criteria.interpret( renderingContext ).buildCompiledQuery(
entityManager,
new InterpretedParameterMetadata() {
@Override
public Map, ExplicitParameterInfo> explicitParameterInfoMap() {
return explicitParameterInfoMap;
}
@Override
public List implicitParameterBindings() {
return implicitParameterBindings;
}
}
);
}
}