HHH-4966 - Entity Manager bug with ParameterExpressionImpl
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@19467 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
8e76bf9648
commit
c875076103
|
@ -99,27 +99,24 @@ public class CriteriaQueryCompiler implements Serializable {
|
|||
*/
|
||||
public String generateAlias();
|
||||
|
||||
/**
|
||||
* Generate a name for a parameter into the JPAQL query.
|
||||
*
|
||||
* @return The generated para name
|
||||
*/
|
||||
public String generateParameterName();
|
||||
|
||||
/**
|
||||
* Register parameters explicitly encountered in the criteria query.
|
||||
*
|
||||
* @param criteriaQueryParameter The parameter expression
|
||||
* @param jpaqlParameterName The generated name for the parameter
|
||||
*
|
||||
* @return The JPA-QL parameter name
|
||||
*/
|
||||
public void registerExplicitParameter(ParameterExpression<?> criteriaQueryParameter, String jpaqlParameterName);
|
||||
public String registerExplicitParameter(ParameterExpression<?> criteriaQueryParameter);
|
||||
|
||||
/**
|
||||
* Register a parameter that was not part of the criteria query (at least not as a parameter).
|
||||
*
|
||||
* @param binding The parameter description.
|
||||
* @param literal The literal value
|
||||
* @param javaType The java type as whcih to handle the literal value.
|
||||
*
|
||||
* @return The JPA-QL parameter name
|
||||
*/
|
||||
public void registerImplicitParameterBinding(ImplicitParameterBinding binding);
|
||||
public String registerLiteralParameterBinding(Object literal, Class javaType);
|
||||
|
||||
/**
|
||||
* Given a java type, determine the proper cast type name.
|
||||
|
@ -164,22 +161,43 @@ public class CriteriaQueryCompiler implements Serializable {
|
|||
return "param" + explicitParameterCount++;
|
||||
}
|
||||
|
||||
public void registerExplicitParameter(ParameterExpression<?> criteriaQueryParameter, String jpaqlParameterName) {
|
||||
explicitParameterMapping.put( criteriaQueryParameter, jpaqlParameterName );
|
||||
public String registerExplicitParameter(ParameterExpression<?> criteriaQueryParameter) {
|
||||
final String jpaqlParameterName;
|
||||
if ( explicitParameterMapping.containsKey( criteriaQueryParameter ) ) {
|
||||
jpaqlParameterName = explicitParameterMapping.get( criteriaQueryParameter );
|
||||
}
|
||||
else {
|
||||
jpaqlParameterName = generateParameterName();
|
||||
explicitParameterMapping.put( criteriaQueryParameter, jpaqlParameterName );
|
||||
}
|
||||
if ( StringHelper.isNotEmpty( criteriaQueryParameter.getName() ) ) {
|
||||
explicitParameterNameMapping.put(
|
||||
criteriaQueryParameter.getName(),
|
||||
criteriaQueryParameter
|
||||
);
|
||||
}
|
||||
return jpaqlParameterName;
|
||||
}
|
||||
|
||||
public void registerImplicitParameterBinding(ImplicitParameterBinding binding) {
|
||||
public String registerLiteralParameterBinding(final Object literal, final Class javaType) {
|
||||
final String parameterName = generateParameterName();
|
||||
final ImplicitParameterBinding binding = new CriteriaQueryCompiler.ImplicitParameterBinding() {
|
||||
public String getParameterName() {
|
||||
return parameterName;
|
||||
}
|
||||
|
||||
public Class getJavaType() {
|
||||
return javaType;
|
||||
}
|
||||
|
||||
public void bind(TypedQuery typedQuery) {
|
||||
typedQuery.setParameter( parameterName, literal );
|
||||
}
|
||||
};
|
||||
|
||||
implicitParameterBindings.add( binding );
|
||||
implicitParameterTypes.put(
|
||||
binding.getParameterName(),
|
||||
binding.getJavaType()
|
||||
);
|
||||
implicitParameterTypes.put( parameterName, javaType );
|
||||
return parameterName;
|
||||
}
|
||||
|
||||
public String getCastType(Class javaType) {
|
||||
|
|
|
@ -69,22 +69,7 @@ public class LiteralExpression<T> extends ExpressionImpl<T> implements Serializa
|
|||
}
|
||||
|
||||
// else...
|
||||
final String parameterName = renderingContext.generateParameterName();
|
||||
renderingContext.registerImplicitParameterBinding(
|
||||
new CriteriaQueryCompiler.ImplicitParameterBinding() {
|
||||
public String getParameterName() {
|
||||
return parameterName;
|
||||
}
|
||||
|
||||
public Class getJavaType() {
|
||||
return LiteralExpression.this.getJavaType();
|
||||
}
|
||||
|
||||
public void bind(TypedQuery typedQuery) {
|
||||
typedQuery.setParameter( parameterName, getLiteral() );
|
||||
}
|
||||
}
|
||||
);
|
||||
final String parameterName = renderingContext.registerLiteralParameterBinding( getLiteral(), getJavaType() );
|
||||
return ':' + parameterName;
|
||||
}
|
||||
|
||||
|
|
|
@ -85,8 +85,7 @@ public class ParameterExpressionImpl<T>
|
|||
}
|
||||
|
||||
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
|
||||
final String jpaqlParamName = renderingContext.generateParameterName();
|
||||
renderingContext.registerExplicitParameter( this, jpaqlParamName );
|
||||
final String jpaqlParamName = renderingContext.registerExplicitParameter( this );
|
||||
return ':' + jpaqlParamName;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,11 +27,18 @@ import java.math.BigDecimal;
|
|||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.TypedQuery;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.ParameterExpression;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
import org.hibernate.Query;
|
||||
import org.hibernate.ejb.metamodel.AbstractMetamodelSpecificTest;
|
||||
import org.hibernate.ejb.metamodel.Product;
|
||||
import org.hibernate.ejb.metamodel.Product_;
|
||||
import org.hibernate.impl.AbstractQueryImpl;
|
||||
|
||||
/**
|
||||
* Tests that various expressions operate as expected
|
||||
|
@ -60,16 +67,6 @@ public class ExpressionsTest extends AbstractMetamodelSpecificTest {
|
|||
em.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
EntityManager em = getOrCreateEntityManager();
|
||||
em.getTransaction().begin();
|
||||
em.createQuery( "delete Product" ).executeUpdate();
|
||||
em.getTransaction().commit();
|
||||
em.close();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
public void testEmptyConjunction() {
|
||||
EntityManager em = getOrCreateEntityManager();
|
||||
em.getTransaction().begin();
|
||||
|
@ -227,4 +224,28 @@ public class ExpressionsTest extends AbstractMetamodelSpecificTest {
|
|||
em.close();
|
||||
}
|
||||
|
||||
|
||||
public void testParameterReuse() {
|
||||
EntityManager em = getOrCreateEntityManager();
|
||||
em.getTransaction().begin();
|
||||
CriteriaQuery<Product> criteria = em.getCriteriaBuilder().createQuery( Product.class );
|
||||
Root<Product> from = criteria.from( Product.class );
|
||||
ParameterExpression<String> param = em.getCriteriaBuilder().parameter( String.class );
|
||||
Predicate predicate = em.getCriteriaBuilder().equal( from.get( Product_.id ), param );
|
||||
Predicate predicate2 = em.getCriteriaBuilder().equal( from.get( Product_.name ), param );
|
||||
criteria.where( em.getCriteriaBuilder().or( predicate, predicate2 ) );
|
||||
assertEquals( 1, criteria.getParameters().size() );
|
||||
TypedQuery<Product> query = em.createQuery( criteria );
|
||||
int hqlParamCount = countGeneratedParameters( query.unwrap( Query.class ) );
|
||||
assertEquals( 1, hqlParamCount );
|
||||
query.setParameter( param, "abc" ).getResultList();
|
||||
em.getTransaction().commit();
|
||||
em.close();
|
||||
}
|
||||
|
||||
private int countGeneratedParameters(Query query) {
|
||||
AbstractQueryImpl hqlQueryImpl = (AbstractQueryImpl) query;
|
||||
return hqlQueryImpl.getParameterMetadata().getNamedParameterNames().size();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue