From 02323188c696de6ec9dc72b96ce81cc552a22070 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Tue, 8 Dec 2009 21:19:42 +0000 Subject: [PATCH] HHH-4654 - Criteria quries must support referencing parameters by name git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18169 1b8cb986-b30d-0410-93ca-fae66ebed9b2 --- .../ejb/criteria/CriteriaQueryCompiler.java | 143 +++++++++++++----- 1 file changed, 109 insertions(+), 34 deletions(-) diff --git a/entitymanager/src/main/java/org/hibernate/ejb/criteria/CriteriaQueryCompiler.java b/entitymanager/src/main/java/org/hibernate/ejb/criteria/CriteriaQueryCompiler.java index 06940e38ce..257814f3cc 100644 --- a/entitymanager/src/main/java/org/hibernate/ejb/criteria/CriteriaQueryCompiler.java +++ b/entitymanager/src/main/java/org/hibernate/ejb/criteria/CriteriaQueryCompiler.java @@ -39,6 +39,7 @@ import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.ParameterExpression; import org.hibernate.ejb.HibernateEntityManagerImplementor; +import org.hibernate.util.StringHelper; /** * Compiles a JPA criteria query into an executable {@link TypedQuery}. Its single contract is the {@link #compile} @@ -77,7 +78,9 @@ public class CriteriaQueryCompiler { criteriaQueryImpl.validate(); final Map,String> explicitParameterMapping = new HashMap,String>(); + final Map> explicitParameterNameMapping = new HashMap>(); final List implicitParameterBindings = new ArrayList(); + RenderingContext renderingContext = new RenderingContext() { private int aliasCount = 0; private int explicitParameterCount = 0; @@ -92,6 +95,12 @@ public class CriteriaQueryCompiler { public void registerExplicitParameter(ParameterExpression criteriaQueryParameter, String jpaqlParameterName) { explicitParameterMapping.put( criteriaQueryParameter, jpaqlParameterName ); + if ( StringHelper.isNotEmpty( criteriaQueryParameter.getName() ) ) { + explicitParameterNameMapping.put( + criteriaQueryParameter.getName(), + criteriaQueryParameter + ); + } } public void registerImplicitParameterBinding(ImplicitParameterBinding binding) { @@ -109,12 +118,13 @@ public class CriteriaQueryCompiler { implicitParameterBinding.bind( jpaqlQuery ); } - return wrap( jpaqlQuery, explicitParameterMapping ); + return wrap( jpaqlQuery, explicitParameterMapping, explicitParameterNameMapping ); } private TypedQuery wrap( final TypedQuery jpaqlQuery, - final Map, String> explicitParameterMapping) { + final Map, String> explicitParameterMapping, + final Map> explicitParameterNameMapping) { return new TypedQuery() { public List getResultList() { @@ -130,7 +140,8 @@ public class CriteriaQueryCompiler { } public TypedQuery setMaxResults(int i) { - return jpaqlQuery.setMaxResults( i ); + jpaqlQuery.setMaxResults( i ); + return this; } public int getFirstResult() { @@ -138,7 +149,8 @@ public class CriteriaQueryCompiler { } public TypedQuery setFirstResult(int i) { - return jpaqlQuery.setFirstResult( i ); + jpaqlQuery.setFirstResult( i ); + return this; } public Map getHints() { @@ -146,7 +158,8 @@ public class CriteriaQueryCompiler { } public TypedQuery setHint(String name, Object value) { - return jpaqlQuery.setHint( name, value); + jpaqlQuery.setHint( name, value); + return this; } public FlushModeType getFlushMode() { @@ -154,7 +167,8 @@ public class CriteriaQueryCompiler { } public TypedQuery setFlushMode(FlushModeType flushModeType) { - return jpaqlQuery.setFlushMode( flushModeType ); + jpaqlQuery.setFlushMode( flushModeType ); + return this; } public LockModeType getLockMode() { @@ -162,7 +176,8 @@ public class CriteriaQueryCompiler { } public TypedQuery setLockMode(LockModeType lockModeType) { - return jpaqlQuery.setLockMode( lockModeType ); + jpaqlQuery.setLockMode( lockModeType ); + return this; } @SuppressWarnings({ "unchecked" }) @@ -181,7 +196,8 @@ public class CriteriaQueryCompiler { @SuppressWarnings({ "unchecked" }) public TypedQuery setParameter(Parameter param, T t) { - return jpaqlQuery.setParameter( mapToNamedParameter( param ), t ); + jpaqlQuery.setParameter( mapToNamedParameter( param ), t ); + return this; } @SuppressWarnings({ "RedundantCast" }) @@ -193,18 +209,101 @@ public class CriteriaQueryCompiler { @SuppressWarnings({ "unchecked" }) public TypedQuery setParameter(Parameter param, Calendar calendar, TemporalType temporalType) { - return jpaqlQuery.setParameter( mapToNamedParameter( param ), calendar, temporalType ); + jpaqlQuery.setParameter( mapToNamedParameter( param ), calendar, temporalType ); + return this; } @SuppressWarnings({ "unchecked" }) public TypedQuery setParameter(Parameter param, Date date, TemporalType temporalType) { - return jpaqlQuery.setParameter( mapToNamedParameter( param ), date, temporalType ); + jpaqlQuery.setParameter( mapToNamedParameter( param ), date, temporalType ); + return this; } public T unwrap(Class cls) { return jpaqlQuery.unwrap( cls ); } + @SuppressWarnings({ "unchecked" }) + public Object getParameterValue(String name) { + return getParameterValue( resolveExplicitCriteriaParameterName( name ) ); + } + + private Parameter resolveExplicitCriteriaParameterName(String name) { + Parameter parameter = explicitParameterNameMapping.get( name ); + if ( parameter == null ) { + throw new IllegalArgumentException( "Named parameter [" + name + "] not encountered" ); + } + return parameter; + } + + public Parameter getParameter(String name) { + return mapToNamedParameter( resolveExplicitCriteriaParameterName( name ) ); + } + + @SuppressWarnings({ "unchecked" }) + public Parameter getParameter(String name, Class type) { + Parameter parameter = resolveExplicitCriteriaParameterName( name ); + if ( type.isAssignableFrom( parameter.getParameterType() ) ) { + return (Parameter) parameter; + } + throw new IllegalArgumentException( + "Named parameter [" + name + "] type is not assignanle to request type [" + + type.getName() + "]" + ); + } + + @SuppressWarnings({ "unchecked" }) + public TypedQuery setParameter(String name, Object value) { + setParameter( + resolveExplicitCriteriaParameterName( name, value ), + value + ); + return this; + } + + private Parameter resolveExplicitCriteriaParameterName(String name, Object value) { + Parameter parameter = resolveExplicitCriteriaParameterName( name ); + // todo : is null valid? + if ( value != null ) { + if ( ! parameter.getParameterType().isInstance( value ) ) { + throw new IllegalArgumentException( + "Named parameter [" + name + "] type mismatch; expecting [" + + parameter.getParameterType().getName() + "], found [" + + value.getClass().getName() + "]" + ); + } + } + return parameter; + } + + @SuppressWarnings({ "unchecked" }) + public TypedQuery setParameter(String name, Calendar calendar, TemporalType temporalType) { + Parameter parameter = resolveExplicitCriteriaParameterName( name ); + if ( ! Calendar.class.isAssignableFrom( parameter.getParameterType() ) ) { + throw new IllegalArgumentException( + "Named parameter [" + name + "] type mismatch; expecting [" + + Calendar.class.getName() + "], found [" + + parameter.getParameterType().getName() + "]" + ); + } + setParameter( parameter, calendar, temporalType ); + return this; + } + + @SuppressWarnings({ "unchecked" }) + public TypedQuery setParameter(String name, Date date, TemporalType temporalType) { + Parameter parameter = resolveExplicitCriteriaParameterName( name ); + if ( ! Date.class.isAssignableFrom( parameter.getParameterType() ) ) { + throw new IllegalArgumentException( + "Named parameter [" + name + "] type mismatch; expecting [" + + Date.class.getName() + "], found [" + + parameter.getParameterType().getName() + "]" + ); + } + setParameter( parameter, date, temporalType ); + return this; + } + // unsupported stuff ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -212,30 +311,6 @@ public class CriteriaQueryCompiler { throw new IllegalArgumentException( "Criteria queries do not support update queries" ); } - public TypedQuery setParameter(String s, Object o) { - throw new IllegalArgumentException( "Criteria queries do not support named parameters" ); - } - - public TypedQuery setParameter(String s, Calendar calendar, TemporalType temporalType) { - throw new IllegalArgumentException( "Criteria queries do not support named parameters" ); - } - - public TypedQuery setParameter(String s, Date date, TemporalType temporalType) { - throw new IllegalArgumentException( "Criteria queries do not support named parameters" ); - } - - public Object getParameterValue(String name) { - throw new IllegalArgumentException( "Criteria queries do not support named parameters" ); - } - - public Parameter getParameter(String name) { - throw new IllegalArgumentException( "Criteria queries do not support named parameters" ); - } - - public Parameter getParameter(String name, Class type) { - throw new IllegalArgumentException( "Criteria queries do not support named parameters" ); - } - public TypedQuery setParameter(int i, Object o) { throw new IllegalArgumentException( "Criteria queries do not support positioned parameters" ); }