HHH-12290 Add jpa compliance check for parameters mixture

This commit is contained in:
Dmitrii Bocharov 2018-02-19 17:13:28 +01:00 committed by Steve Ebersole
parent 2a0b8f24a9
commit 7e77a6032b
3 changed files with 84 additions and 37 deletions

View File

@ -1089,9 +1089,9 @@ public class HqlSqlWalker extends HqlSqlBaseWalker implements ErrorReporter, Par
@Override
protected AST generatePositionalParameter(AST delimiterNode, AST numberNode) throws SemanticException {
// todo : we check this multiple times
if ( namedParameters != null ) {
if ( getSessionFactoryHelper().isStrictJPAQLComplianceEnabled() && namedParameters != null ) {
throw new SemanticException(
"Cannot define positional and named parameterSpecs : " + queryTranslatorImpl.getQueryString()
"Cannot mix positional and named parameters: " + queryTranslatorImpl.getQueryString()
);
}
@ -1151,6 +1151,11 @@ public class HqlSqlWalker extends HqlSqlBaseWalker implements ErrorReporter, Par
@Override
protected AST generateNamedParameter(AST delimiterNode, AST nameNode) throws SemanticException {
if ( getSessionFactoryHelper().isStrictJPAQLComplianceEnabled() && positionalParameters != null ) {
throw new SemanticException(
"Cannot mix positional and named parameters: " + queryTranslatorImpl.getQueryString()
);
}
final String name = nameNode.getText();
trackNamedParameterPositions( name );

View File

@ -705,14 +705,10 @@ public class QueryTest extends BaseEntityManagerFunctionalTestCase {
}
}
/**
* Collection parameters are internally rewritten to named parameters (one named parameter by
* collection item) and HQL parser rejects mixed positional and named parameters queries.
*/
@Test
@TestForIssue(jiraKey = "HHH-12290")
public void testParameterCollectionAndPositional() {
final Item item = new Item( "Mouse", "Micro$oft mouse" );
final Item item = new Item( "Mouse", "Microsoft mouse" );
final Item item2 = new Item( "Computer", "Dell computer" );
EntityManager em = getOrCreateEntityManager();
@ -724,10 +720,7 @@ public class QueryTest extends BaseEntityManagerFunctionalTestCase {
em.getTransaction().commit();
em.getTransaction().begin();
Query q = em.createQuery( "select item from Item item where item.name in ?1 and descr = ?2" );
//test hint in value and string
q.setHint( "org.hibernate.fetchSize", 10 );
q.setHint( "org.hibernate.fetchSize", "10" );
Query q = em.createQuery( "select item from Item item where item.name in ?1 and item.descr = ?2" );
List params = new ArrayList();
params.add( item.getName() );
params.add( item2.getName() );
@ -748,14 +741,10 @@ public class QueryTest extends BaseEntityManagerFunctionalTestCase {
}
}
/**
* Collection parameters are internally rewritten to named parameters (one named parameter by
* collection item) and HQL parser rejects mixed positional and named parameters queries.
*/
@Test
@TestForIssue(jiraKey = "HHH-12290")
public void testParameterCollectionParenthesesAndPositional() {
final Item item = new Item( "Mouse", "Micro$oft mouse" );
final Item item = new Item( "Mouse", "Microsoft mouse" );
final Item item2 = new Item( "Computer", "Dell computer" );
EntityManager em = getOrCreateEntityManager();
@ -767,13 +756,8 @@ public class QueryTest extends BaseEntityManagerFunctionalTestCase {
em.getTransaction().commit();
em.getTransaction().begin();
Query q = em.createQuery( "select item from Item item where item.name in (?1) and descr = ?2" );
//test hint in value and string
q.setHint( "org.hibernate.fetchSize", 10 );
q.setHint( "org.hibernate.fetchSize", "10" );
Query q = em.createQuery( "select item from Item item where item.name in (?1) and item.descr = ?2" );
List params = new ArrayList();
// for this case, 1-item collection is OK, but 2 or more is broken
// as 1-item collection are not "rewritten"
params.add( item.getName() );
params.add( item2.getName() );
q.setParameter( 1, params );
@ -793,14 +777,10 @@ public class QueryTest extends BaseEntityManagerFunctionalTestCase {
}
}
/**
* Collection parameters are internally rewritten to named parameters (one named parameter by
* collection item) and HQL parser rejects mixed positional and named parameters queries.
*/
@Test
@TestForIssue(jiraKey = "HHH-12290")
public void testParameterCollectionSingletonParenthesesAndPositional() {
final Item item = new Item( "Mouse", "Micro$oft mouse" );
final Item item = new Item( "Mouse", "Microsoft mouse" );
final Item item2 = new Item( "Computer", "Dell computer" );
EntityManager em = getOrCreateEntityManager();
@ -812,13 +792,8 @@ public class QueryTest extends BaseEntityManagerFunctionalTestCase {
em.getTransaction().commit();
em.getTransaction().begin();
Query q = em.createQuery( "select item from Item item where item.name in (?1) and descr = ?2" );
//test hint in value and string
q.setHint( "org.hibernate.fetchSize", 10 );
q.setHint( "org.hibernate.fetchSize", "10" );
Query q = em.createQuery( "select item from Item item where item.name in (?1) and item.descr = ?2" );
List params = new ArrayList();
// for this case, 1-item collection is OK, but 2 or more is broken
// as 1-item collection are not "rewritten"
params.add( item2.getName() );
q.setParameter( 1, params );
q.setParameter( 2, item2.getDescr() );

View File

@ -6,11 +6,21 @@
*/
package org.hibernate.test.jpa.ql;
import org.hibernate.hql.internal.ast.QuerySyntaxException;
import org.hibernate.query.Query;
import org.hibernate.testing.TestForIssue;
import org.junit.Test;
import org.hibernate.Session;
import org.hibernate.test.jpa.AbstractJPATest;
import java.util.ArrayList;
import java.util.List;
import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
/**
* Tests for various JPAQL compliance issues
*
@ -61,4 +71,61 @@ public class JPAQLComplianceTest extends AbstractJPATest {
s.createQuery( "select p.name as name, p.stockNumber as stockNo, p.unitPrice as uPrice FROM Part p ORDER BY name, abs( p.unitPrice ), stockNo" ).list();
s.close();
}
@Test
@TestForIssue(jiraKey = "HHH-12290")
public void testParametersMixturePositionalAndNamed() {
Session s = openSession();
try {
s.createQuery( "select item from Item item where item.id = ?1 and item.name = :name" ).list();
fail( "Expecting QuerySyntaxException because of named and positional parameters mixture" );
} catch ( IllegalArgumentException e ) {
assertNotNull( e.getCause() );
assertTyping( QuerySyntaxException.class, e.getCause() );
} finally {
s.close();
}
}
@Test
@TestForIssue(jiraKey = "HHH-12290")
public void testParametersMixtureNamedAndPositional() {
Session s = openSession();
try {
s.createQuery( "select item from Item item where item.id = :id and item.name = ?1" ).list();
fail( "Expecting QuerySyntaxException because of named and positional parameters mixture" );
} catch ( IllegalArgumentException e ) {
assertNotNull( e.getCause() );
assertTyping( QuerySyntaxException.class, e.getCause() );
} finally {
s.close();
}
}
/**
* Positional collection parameter is expanded to the list of named parameters. In spite of this fact, initial query
* query is wrong in terms of JPA and exception must be thrown
*/
@Test
@TestForIssue(jiraKey = "HHH-12290")
public void testParametersMixtureNamedCollectionAndPositional() {
Session s = openSession();
try {
Query q = s.createQuery( "select item from Item item where item.id in (?1) and item.name = :name" );
List<Integer> params = new ArrayList();
params.add( 0 );
params.add( 1 );
q.setParameter( 1, params );
q.setParameter( "name", "name" );
q.list();
fail( "Expecting QuerySyntaxException because of named and positional parameters mixture" );
}
catch (IllegalArgumentException e) {
assertNotNull( e.getCause() );
assertTyping( QuerySyntaxException.class, e.getCause() );
}
finally {
s.close();
}
}
}