Fixed failing tests and code to treat '?' parameters as 0-based ordinals and '?<position>' parameters as named 1-based parameters.
This commit is contained in:
parent
8a746b98a7
commit
a54da750ad
|
@ -484,6 +484,11 @@ public abstract class AbstractProducedQuery<R> implements QueryImplementor<R> {
|
|||
|
||||
@Override
|
||||
public Parameter<?> getParameter(int position) {
|
||||
// lookup jpa-based positional parameters first by name.
|
||||
if ( parameterMetadata.getPositionalParameterCount() == 0 ) {
|
||||
return parameterMetadata.getQueryParameter( String.valueOf( position ) );
|
||||
}
|
||||
// fallback to oridinal lookup
|
||||
return parameterMetadata.getQueryParameter( position );
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.util.stream.Collectors;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Incubating;
|
||||
import org.hibernate.QueryException;
|
||||
import org.hibernate.QueryParameterException;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.query.spi.NamedParameterDescriptor;
|
||||
|
@ -196,34 +197,34 @@ public class QueryParameterBindingsImpl implements QueryParameterBindings {
|
|||
}
|
||||
|
||||
public QueryParameterBinding getBinding(int position) {
|
||||
final boolean isJpaBootstrap = sessionFactory.getSessionFactoryOptions().isJpaBootstrap();
|
||||
|
||||
QueryParameterBinding binding = null;
|
||||
if ( parameterMetadata != null ) {
|
||||
if ( isJpaBootstrap && parameterMetadata.getPositionalParameterCount() == 0 ) {
|
||||
if ( parameterMetadata.getPositionalParameterCount() == 0 ) {
|
||||
// no positional parameters, assume jpa named.
|
||||
binding = locateBinding( String.valueOf( position ) );
|
||||
}
|
||||
else {
|
||||
final int positionIndex = ( isJpaBootstrap ? position - 1 : position );
|
||||
final int parameterIndex = ( isJpaBootstrap ? position : position + 1 );
|
||||
|
||||
if ( positionIndex < positionalParameterBindings.size() ) {
|
||||
binding = positionalParameterBindings.get( positionIndex );
|
||||
if ( binding == null ) {
|
||||
try {
|
||||
if ( position < positionalParameterBindings.size() ) {
|
||||
binding = positionalParameterBindings.get( position );
|
||||
if ( binding == null ) {
|
||||
// metadata parameters are 1-based
|
||||
binding = makeBinding( parameterMetadata.getQueryParameter( position + 1 ) );
|
||||
positionalParameterBindings.set( position, binding );
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0; i < position - positionalParameterBindings.size(); i++ ) {
|
||||
positionalParameterBindings.add( null );
|
||||
}
|
||||
// metadata parameters are 1-based
|
||||
binding = makeBinding( parameterMetadata.getQueryParameter( parameterIndex ) );
|
||||
positionalParameterBindings.set( positionIndex, binding );
|
||||
QueryParameter queryParameter = parameterMetadata.getQueryParameter( position + 1 );
|
||||
binding = makeBinding( queryParameter );
|
||||
positionalParameterBindings.add( binding );
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0; i < positionIndex - positionalParameterBindings.size(); i++ ) {
|
||||
positionalParameterBindings.add( null );
|
||||
}
|
||||
// metadata parameters are 1-based
|
||||
QueryParameter queryParameter = parameterMetadata.getQueryParameter( parameterIndex );
|
||||
binding = makeBinding( queryParameter );
|
||||
positionalParameterBindings.add( binding );
|
||||
catch ( QueryParameterException e ) {
|
||||
// treat this as null binding
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,11 +12,18 @@ import java.util.Date;
|
|||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.persistence.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import javax.persistence.CacheRetrieveMode;
|
||||
import javax.persistence.CacheStoreMode;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Parameter;
|
||||
import javax.persistence.PersistenceException;
|
||||
import javax.persistence.Query;
|
||||
import javax.persistence.TemporalType;
|
||||
import javax.persistence.Tuple;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.QueryParameterException;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.dialect.Oracle8iDialect;
|
||||
import org.hibernate.dialect.PostgreSQL9Dialect;
|
||||
|
@ -27,12 +34,10 @@ import org.hibernate.jpa.test.Distributor;
|
|||
import org.hibernate.jpa.test.Item;
|
||||
import org.hibernate.jpa.test.Wallet;
|
||||
import org.hibernate.stat.Statistics;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.hibernate.testing.SkipForDialect;
|
||||
import org.hibernate.testing.SkipForDialects;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.junit.Test;
|
||||
|
||||
import static junit.framework.Assert.assertNull;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
@ -111,16 +116,16 @@ public class QueryTest extends BaseEntityManagerFunctionalTestCase {
|
|||
Item item = new Item( "Mouse", "Micro$oft mouse" );
|
||||
em.persist( item );
|
||||
Query q = em.createQuery( "from Item i where i.intVal=?" );
|
||||
q.setParameter( 1, null );
|
||||
q.setParameter( 0, null );
|
||||
List results = q.getResultList();
|
||||
// null != null
|
||||
assertEquals( 0, results.size() );
|
||||
q = em.createQuery( "from Item i where i.intVal is null and ? is null" );
|
||||
q.setParameter( 1, null );
|
||||
q.setParameter( 0, null );
|
||||
results = q.getResultList();
|
||||
assertEquals( 1, results.size() );
|
||||
q = em.createQuery( "from Item i where i.intVal is null or i.intVal = ?" );
|
||||
q.setParameter( 1, null );
|
||||
q.setParameter( 0, null );
|
||||
results = q.getResultList();
|
||||
assertEquals( 1, results.size() );
|
||||
em.getTransaction().rollback();
|
||||
|
@ -316,16 +321,16 @@ public class QueryTest extends BaseEntityManagerFunctionalTestCase {
|
|||
// native queries don't seem to flush by default ?!?
|
||||
em.flush();
|
||||
Query q = em.createNativeQuery( "select * from Item i where i.intVal=?" );
|
||||
q.setParameter( 1, null );
|
||||
q.setParameter( 0, null );
|
||||
List results = q.getResultList();
|
||||
// null != null
|
||||
assertEquals( 0, results.size() );
|
||||
q = em.createNativeQuery( "select * from Item i where i.intVal is null and ? is null" );
|
||||
q.setParameter( 1, null );
|
||||
q.setParameter( 0, null );
|
||||
results = q.getResultList();
|
||||
assertEquals( 1, results.size() );
|
||||
q = em.createNativeQuery( "select * from Item i where i.intVal is null or i.intVal = ?" );
|
||||
q.setParameter( 1, null );
|
||||
q.setParameter( 0, null );
|
||||
results = q.getResultList();
|
||||
assertEquals( 1, results.size() );
|
||||
em.getTransaction().rollback();
|
||||
|
@ -549,8 +554,9 @@ public class QueryTest extends BaseEntityManagerFunctionalTestCase {
|
|||
Query query = em.createQuery( "from Item item where item.name =?1 or item.descr = ?1" );
|
||||
Parameter p1 = query.getParameter( 1 );
|
||||
Assert.assertNotNull( p1 );
|
||||
Assert.assertNotNull( p1.getPosition() );
|
||||
Assert.assertNull( p1.getName() );
|
||||
// in 5.2, '?<position' parameters are named while '?' are position-based.
|
||||
Assert.assertNotNull( p1.getName() );
|
||||
Assert.assertNull( p1.getPosition() );
|
||||
|
||||
em.getTransaction().commit();
|
||||
em.close();
|
||||
|
@ -802,7 +808,7 @@ public class QueryTest extends BaseEntityManagerFunctionalTestCase {
|
|||
|
||||
// finally using hql-style positional parameter
|
||||
query = em.createQuery( "select w from Wallet w where w.brand = ?" );
|
||||
query.setParameter( 1, "Lacoste" );
|
||||
query.setParameter( 0, "Lacoste" );
|
||||
w = (Wallet) query.getSingleResult();
|
||||
assertNotNull( w );
|
||||
|
||||
|
@ -822,20 +828,31 @@ public class QueryTest extends BaseEntityManagerFunctionalTestCase {
|
|||
em.persist( w );
|
||||
em.flush();
|
||||
|
||||
|
||||
Query query = em.createQuery( "select w from Wallet w where w.brand = ?1 and w.model = ?3" );
|
||||
query.setParameter( 1, "Lacoste" );
|
||||
// using jpa-style, position index should match syntax '?<position'.
|
||||
Query jpaQuery = em.createQuery( "select w from Wallet w where w.brand = ?1 and w.model = ?3" );
|
||||
jpaQuery.setParameter( 1, "Lacoste" );
|
||||
try {
|
||||
query.setParameter( 2, "Expensive" );
|
||||
jpaQuery.setParameter( 2, "Expensive" );
|
||||
fail( "Should fail due to a user error in parameters" );
|
||||
}
|
||||
catch ( IllegalArgumentException e ) {
|
||||
//success
|
||||
catch( IllegalArgumentException e ) {
|
||||
// success, expected
|
||||
}
|
||||
finally {
|
||||
em.getTransaction().rollback();
|
||||
em.close();
|
||||
|
||||
// using hql-style, should be 0-based
|
||||
Query hqlQuery = em.createQuery( "select w from Wallet w where w.brand = ? and w.model = ?" );
|
||||
try {
|
||||
hqlQuery.setParameter( 1, "Lacoste" );
|
||||
hqlQuery.setParameter( 2, "Expensive" );
|
||||
fail( "Should fail due to a user error in parameters" );
|
||||
}
|
||||
catch( QueryParameterException e ) {
|
||||
// success expected
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
em.getTransaction().rollback();
|
||||
em.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -850,7 +867,7 @@ public class QueryTest extends BaseEntityManagerFunctionalTestCase {
|
|||
em.getTransaction().commit();
|
||||
em.getTransaction().begin();
|
||||
Query query = em.createNativeQuery( "select * from Wallet w where w.brand = ?", Wallet.class );
|
||||
query.setParameter( 1, "Lacoste" );
|
||||
query.setParameter( 0, "Lacoste" );
|
||||
w = (Wallet) query.getSingleResult();
|
||||
assertNotNull( w );
|
||||
em.remove( w );
|
||||
|
@ -875,7 +892,7 @@ public class QueryTest extends BaseEntityManagerFunctionalTestCase {
|
|||
assertNotNull( item );
|
||||
assertEquals( "Micro$oft mouse", item.getDescr() );
|
||||
query = em.createNativeQuery( "select * from Item where name = ?", Item.class );
|
||||
query.setParameter( 1, "Mouse" );
|
||||
query.setParameter( 0, "Mouse" );
|
||||
item = (Item) query.getSingleResult();
|
||||
assertNotNull( item );
|
||||
assertEquals( "Micro$oft mouse", item.getDescr() );
|
||||
|
|
Loading…
Reference in New Issue