HHH-4965 - Implicit parameters abusively use TypeFactory.heuristicType losing UserType and XToOneType info
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@19233 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
c47267d3bb
commit
3f92dbb9a9
|
@ -102,7 +102,7 @@ public class QueryImpl<X> extends org.hibernate.ejb.AbstractQueryImpl<X> impleme
|
|||
final NamedParameterDescriptor descriptor =
|
||||
queryImpl.getParameterMetadata().getNamedParameterDescriptor( name );
|
||||
Class javaType = namedParameterTypeRedefinition.get( name );
|
||||
if ( javaType != null ) {
|
||||
if ( javaType != null && mightNeedRedefinition( javaType ) ) {
|
||||
descriptor.resetExpectedType(
|
||||
TypeFactory.heuristicType( javaType.getName() )
|
||||
);
|
||||
|
@ -140,6 +140,11 @@ public class QueryImpl<X> extends org.hibernate.ejb.AbstractQueryImpl<X> impleme
|
|||
this.parameters = java.util.Collections.unmodifiableSet( parameters );
|
||||
}
|
||||
|
||||
private boolean mightNeedRedefinition(Class javaType) {
|
||||
// for now, only really no for dates/times/timestamps
|
||||
return java.util.Date.class.isAssignableFrom( javaType );
|
||||
}
|
||||
|
||||
private static class ParameterImpl implements Parameter {
|
||||
private final String name;
|
||||
private final Integer position;
|
||||
|
|
|
@ -60,19 +60,74 @@ import org.hibernate.util.StringHelper;
|
|||
public class CriteriaQueryCompiler implements Serializable {
|
||||
private static final Logger log = LoggerFactory.getLogger( CriteriaQueryCompiler.class );
|
||||
|
||||
/**
|
||||
* Used to describe implicit (not defined in criteria query) parameters.
|
||||
*/
|
||||
public static interface ImplicitParameterBinding {
|
||||
/**
|
||||
* Retrieve the generated name of the implicit parameter.
|
||||
*
|
||||
* @return The parameter name.
|
||||
*/
|
||||
public String getParameterName();
|
||||
|
||||
/**
|
||||
* Get the java type of the "thing" that led to the implicit parameter. Used from
|
||||
* {@link org.hibernate.ejb.HibernateEntityManagerImplementor.Options#getNamedParameterExplicitTypes()}
|
||||
* in determining "guessed type" overriding.
|
||||
*
|
||||
* @return The java type
|
||||
*/
|
||||
public Class getJavaType();
|
||||
|
||||
/**
|
||||
* Bind the implicit parameter's value to the JPA query.
|
||||
*
|
||||
* @param typedQuery The JPA query.
|
||||
*/
|
||||
public void bind(TypedQuery typedQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to provide a context and services to the rendering.
|
||||
*/
|
||||
public static interface RenderingContext {
|
||||
/**
|
||||
* Generate a correlation name.
|
||||
*
|
||||
* @return The generated correlation name
|
||||
*/
|
||||
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
|
||||
*/
|
||||
public void registerExplicitParameter(ParameterExpression<?> criteriaQueryParameter, String jpaqlParameterName);
|
||||
|
||||
/**
|
||||
* Register a parameter that was not part of the criteria query (at least not as a parameter).
|
||||
*
|
||||
* @param binding The parameter description.
|
||||
*/
|
||||
public void registerImplicitParameterBinding(ImplicitParameterBinding binding);
|
||||
|
||||
/**
|
||||
* Given a java type, determine the proper cast type name.
|
||||
*
|
||||
* @param javaType The java type.
|
||||
*
|
||||
* @return The cast type name.
|
||||
*/
|
||||
public String getCastType(Class javaType);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,9 @@
|
|||
*/
|
||||
package org.hibernate.ejb.criteria;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.TypedQuery;
|
||||
|
@ -112,6 +114,47 @@ public class QueryBuilderTest extends TestCase {
|
|||
em.close();
|
||||
}
|
||||
|
||||
public void testEqualityComparisonEntityConversion() {
|
||||
EntityManager em = getOrCreateEntityManager();
|
||||
em.getTransaction().begin();
|
||||
Address address = new Address( "Street Id", "Fake Street", "Fake City", "Fake State", "Fake Zip" );
|
||||
Phone phone1 = new Phone( "1", "555", "0001", address );
|
||||
Phone phone2 = new Phone( "2", "555", "0002", address );
|
||||
Phone phone3 = new Phone( "3", "555", "0003", address );
|
||||
Phone phone4 = new Phone( "4", "555", "0004" );
|
||||
|
||||
Collection<Phone> phones = new ArrayList<Phone>( 3 );
|
||||
phones.add( phone1 );
|
||||
phones.add( phone2 );
|
||||
phones.add( phone3 );
|
||||
|
||||
address.setPhones( phones );
|
||||
em.persist( address );
|
||||
em.persist( phone4 );
|
||||
|
||||
em.getTransaction().commit();
|
||||
|
||||
|
||||
em.getTransaction().begin();
|
||||
|
||||
CriteriaBuilderImpl cb = (CriteriaBuilderImpl) em.getCriteriaBuilder();
|
||||
MetamodelImpl mm = (MetamodelImpl) em.getMetamodel();
|
||||
EntityType<Phone> Phone_ = mm.entity( Phone.class );
|
||||
|
||||
CriteriaQuery<Phone> cquery = cb.createQuery( Phone.class );
|
||||
Root<Phone> phone = cquery.from( Phone.class );
|
||||
ComparisonPredicate predicate = (ComparisonPredicate) cb.equal(
|
||||
phone.get( Phone_.getSingularAttribute( "address", Address.class ) ),
|
||||
address
|
||||
);
|
||||
cquery.where( predicate );
|
||||
List<Phone> results = em.createQuery( cquery ).getResultList();
|
||||
|
||||
assertEquals( 3, results.size() );
|
||||
em.getTransaction().commit();
|
||||
em.close();
|
||||
}
|
||||
|
||||
public void testTypeConversion() {
|
||||
EntityManager em = getOrCreateEntityManager();
|
||||
em.getTransaction().begin();
|
||||
|
|
Loading…
Reference in New Issue