HHH-8454 - Criteria queries sometimes lead to SQL like "... where ? in (?,?)"
This commit is contained in:
parent
0ecb76f9d5
commit
1a59e9194b
|
@ -29,14 +29,19 @@ import java.util.Arrays;
|
|||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import javax.persistence.criteria.Expression;
|
||||
import javax.persistence.criteria.ParameterExpression;
|
||||
import javax.persistence.criteria.Subquery;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.jpa.criteria.CriteriaBuilderImpl;
|
||||
import org.hibernate.jpa.criteria.ParameterRegistry;
|
||||
import org.hibernate.jpa.criteria.Renderable;
|
||||
import org.hibernate.jpa.criteria.ValueHandlerFactory;
|
||||
import org.hibernate.jpa.criteria.compile.RenderingContext;
|
||||
import org.hibernate.jpa.criteria.expression.LiteralExpression;
|
||||
import org.hibernate.jpa.criteria.expression.ParameterExpressionImpl;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* Models an <tt>[NOT] IN</tt> restriction
|
||||
|
@ -166,7 +171,22 @@ public class InPredicate<T>
|
|||
@Override
|
||||
public String render(boolean isNegated, RenderingContext renderingContext) {
|
||||
final StringBuilder buffer = new StringBuilder();
|
||||
buffer.append( ( (Renderable) getExpression() ).render( renderingContext ) );
|
||||
final Expression exp = getExpression();
|
||||
if ( ParameterExpressionImpl.class.isInstance( exp ) ) {
|
||||
// technically we only need to CAST (afaik) if expression and all values are parameters.
|
||||
// but checking for that condition could take long time on a lon value list
|
||||
final ParameterExpressionImpl parameterExpression = (ParameterExpressionImpl) exp;
|
||||
final SessionFactoryImplementor sfi = criteriaBuilder().getEntityManagerFactory().unwrap( SessionFactoryImplementor.class );
|
||||
final Type mappingType = sfi.getTypeResolver().heuristicType( parameterExpression.getParameterType().getName() );
|
||||
buffer.append( "cast(" )
|
||||
.append( parameterExpression.render( renderingContext ) )
|
||||
.append( " as " )
|
||||
.append( mappingType.getName() )
|
||||
.append( ")" );
|
||||
}
|
||||
else {
|
||||
buffer.append( ( (Renderable) getExpression() ).render( renderingContext ) );
|
||||
}
|
||||
|
||||
if ( isNegated ) {
|
||||
buffer.append( " not" );
|
||||
|
|
|
@ -94,6 +94,40 @@ public class ParameterTest extends BaseEntityManagerFunctionalTestCase {
|
|||
TypedQuery<MultiTypedBasicAttributesEntity> query = em.createQuery( criteria );
|
||||
Parameter parameter = query.getParameter( "id" );
|
||||
assertEquals( "id", parameter.getName() );
|
||||
|
||||
em.getTransaction().commit();
|
||||
em.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParameterInParameterList() {
|
||||
// Yes, this test makes no semantic sense. But the JPA TCK does it...
|
||||
// it causes a problem on Derby, which does not like the form "... where ? in (?,?)"
|
||||
// Derby wants one side or the other to be CAST (I assume so it can check typing).
|
||||
|
||||
// IMPL NOTE : currently this does not assert the format of the ultimate SQL. We'll let the matrix runs
|
||||
// verify that the generated SQL is valid for each DB
|
||||
|
||||
EntityManager em = getOrCreateEntityManager();
|
||||
em.getTransaction().begin();
|
||||
CriteriaQuery<MultiTypedBasicAttributesEntity> criteria = em.getCriteriaBuilder()
|
||||
.createQuery( MultiTypedBasicAttributesEntity.class );
|
||||
criteria.from( MultiTypedBasicAttributesEntity.class );
|
||||
|
||||
criteria.where(
|
||||
em.getCriteriaBuilder().in( em.getCriteriaBuilder().parameter( Long.class, "p1" ) )
|
||||
.value( em.getCriteriaBuilder().parameter( Long.class, "p2" ) )
|
||||
.value( em.getCriteriaBuilder().parameter( Long.class, "p3" ) )
|
||||
);
|
||||
|
||||
TypedQuery<MultiTypedBasicAttributesEntity> query = em.createQuery( criteria );
|
||||
query.setParameter( "p1", 1L );
|
||||
query.setParameter( "p2", 2L );
|
||||
query.setParameter( "p3", 3L );
|
||||
query.getResultList();
|
||||
|
||||
em.getTransaction().commit();
|
||||
em.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue