HHH-10803 - Fix getParameter methods to be JPA compliant with thrown exception types.

This commit is contained in:
Chris Cranford 2016-06-06 09:01:27 -05:00
parent 42f3028dca
commit 131127a498
2 changed files with 102 additions and 21 deletions

View File

@ -620,21 +620,31 @@ public abstract class AbstractProducedQuery<R> implements QueryImplementor<R> {
@Override
public Parameter<?> getParameter(String name) {
return parameterMetadata.getQueryParameter( name );
try {
return parameterMetadata.getQueryParameter( name );
}
catch ( HibernateException e ) {
throw getExceptionConverter().convert( e );
}
}
@Override
@SuppressWarnings("unchecked")
public <T> Parameter<T> getParameter(String name, Class<T> type) {
final QueryParameter parameter = parameterMetadata.getQueryParameter( name );
if ( !parameter.getParameterType().isAssignableFrom( type ) ) {
throw new IllegalArgumentException(
"The type [" + parameter.getParameterType().getName() +
"] associated with the parameter corresponding to name [" + name +
"] is not assignable to requested Java type [" + type.getName() + "]"
);
try {
final QueryParameter parameter = parameterMetadata.getQueryParameter( name );
if ( !parameter.getParameterType().isAssignableFrom( type ) ) {
throw new IllegalArgumentException(
"The type [" + parameter.getParameterType().getName() +
"] associated with the parameter corresponding to name [" + name +
"] is not assignable to requested Java type [" + type.getName() + "]"
);
}
return parameter;
}
catch ( HibernateException e ) {
throw getExceptionConverter().convert( e );
}
return parameter;
}
@Override
@ -651,25 +661,35 @@ public abstract class AbstractProducedQuery<R> implements QueryImplementor<R> {
// if ParameterMetadata reports that it has any positional-parameters it is talking about the
// legacy Hibernate concept.
// lookup jpa-based positional parameters first by name.
if ( parameterMetadata.getPositionalParameterCount() == 0 ) {
return parameterMetadata.getQueryParameter( Integer.toString( position ) );
try {
if ( parameterMetadata.getPositionalParameterCount() == 0 ) {
return parameterMetadata.getQueryParameter( Integer.toString( position ) );
}
// fallback to oridinal lookup
return parameterMetadata.getQueryParameter( position );
}
catch ( HibernateException e ) {
throw getExceptionConverter().convert( e );
}
// fallback to oridinal lookup
return parameterMetadata.getQueryParameter( position );
}
@Override
@SuppressWarnings("unchecked")
public <T> Parameter<T> getParameter(int position, Class<T> type) {
final QueryParameter parameter = parameterMetadata.getQueryParameter( position );
if ( !parameter.getParameterType().isAssignableFrom( type ) ) {
throw new IllegalArgumentException(
"The type [" + parameter.getParameterType().getName() +
"] associated with the parameter corresponding to position [" + position +
"] is not assignable to requested Java type [" + type.getName() + "]"
);
try {
final QueryParameter parameter = parameterMetadata.getQueryParameter( position );
if ( !parameter.getParameterType().isAssignableFrom( type ) ) {
throw new IllegalArgumentException(
"The type [" + parameter.getParameterType().getName() +
"] associated with the parameter corresponding to position [" + position +
"] is not assignable to requested Java type [" + type.getName() + "]"
);
}
return parameter;
}
catch ( HibernateException e ) {
throw getExceptionConverter().convert( e );
}
return parameter;
}
@Override

View File

@ -51,6 +51,7 @@ import static org.junit.Assert.fail;
/**
* @author Emmanuel Bernard
* @author Steve Ebersole
* @author Chris Cranford
*/
public class QueryTest extends BaseEntityManagerFunctionalTestCase {
@Override
@ -1064,6 +1065,26 @@ public class QueryTest extends BaseEntityManagerFunctionalTestCase {
// success, expected
}
// using jpa-style, position index specified not in query - test exception type
jpaQuery = em.createQuery( "select w from Wallet w " );
try {
String parameterName = jpaQuery.getParameter( 1 ).getName();
fail( "Should fail due to a user error in parameters" );
}
catch ( IllegalArgumentException e ) {
// success, expected.
}
// using jpa-style, position index specified not in query - test exception type
jpaQuery = em.createQuery( "select w from Wallet w" );
try {
Parameter<Integer> parameter = jpaQuery.getParameter( 1, Integer.class );
fail( "Should fail due to user error in parameters" );
}
catch ( IllegalArgumentException e ) {
// success, expected.
}
// using hql-style, should be 0-based
Query hqlQuery = em.createQuery( "select w from Wallet w where w.brand = ? and w.model = ?" );
try {
@ -1084,6 +1105,46 @@ public class QueryTest extends BaseEntityManagerFunctionalTestCase {
}
}
@Test
@TestForIssue(jiraKey = "HHH-10803")
public void testNamedParameterWithUserError() throws Exception {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
try {
Wallet w = new Wallet();
w.setBrand( "Lacoste" );
w.setModel( "Minimic" );
w.setSerial( "0100202002" );
em.persist( w );
em.flush();
Query jpaQuery = em.createQuery( "select w from Wallet w" );
try {
Parameter<?> parameter = jpaQuery.getParameter( "brand" );
fail( "Should fail due to user error in parameters" );
}
catch ( IllegalArgumentException e ) {
// success, expected
}
jpaQuery = em.createQuery( "select w from Wallet w" );
try {
Parameter<String> parameter = jpaQuery.getParameter( "brand", String.class );
fail( "Should fail due to user error in parameters" );
}
catch ( IllegalArgumentException e ) {
// success, expected
}
}
finally {
if ( em.getTransaction() != null && em.getTransaction().isActive() ) {
em.getTransaction().rollback();
}
em.close();
}
}
@Test
public void testNativeQuestionMarkParameter() throws Exception {
EntityManager em = getOrCreateEntityManager();