diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/predicate/InPredicate.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/predicate/InPredicate.java
index 8e698a0d8f..dc132b9db2 100755
--- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/predicate/InPredicate.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/predicate/InPredicate.java
@@ -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 [NOT] IN restriction
@@ -166,7 +171,22 @@ public class InPredicate
@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" );
diff --git a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/criteria/ParameterTest.java b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/criteria/ParameterTest.java
index 164dc6f8ac..b9e887a85c 100644
--- a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/criteria/ParameterTest.java
+++ b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/criteria/ParameterTest.java
@@ -94,6 +94,40 @@ public class ParameterTest extends BaseEntityManagerFunctionalTestCase {
TypedQuery 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 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 query = em.createQuery( criteria );
+ query.setParameter( "p1", 1L );
+ query.setParameter( "p2", 2L );
+ query.setParameter( "p3", 3L );
+ query.getResultList();
+
+ em.getTransaction().commit();
+ em.close();
}
@Override