HHH-6686 fix JQL exception in face of 'empty'
This commit is contained in:
parent
f1d1e62478
commit
a6934467f7
|
@ -18,7 +18,6 @@ import java.util.Set;
|
|||
import org.hibernate.QueryException;
|
||||
import org.hibernate.hql.internal.antlr.HqlBaseParser;
|
||||
import org.hibernate.hql.internal.antlr.HqlTokenTypes;
|
||||
import org.hibernate.hql.internal.ast.util.ASTPrinter;
|
||||
import org.hibernate.hql.internal.ast.util.ASTUtil;
|
||||
import org.hibernate.hql.internal.ast.util.TokenPrinters;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
|
@ -116,7 +115,7 @@ public final class HqlParser extends HqlBaseParser {
|
|||
* @param token The token.
|
||||
* @param ex The recognition exception.
|
||||
*
|
||||
* @return AST - The new AST.
|
||||
* @return The new AST.
|
||||
*
|
||||
* @throws antlr.RecognitionException if the substitution was not possible.
|
||||
* @throws antlr.TokenStreamException if the substitution was not possible.
|
||||
|
@ -159,7 +158,7 @@ public final class HqlParser extends HqlBaseParser {
|
|||
*
|
||||
* @param x The sub tree to transform, the parent is assumed to be NOT.
|
||||
*
|
||||
* @return AST - The equivalent sub-tree.
|
||||
* @return The equivalent sub-tree.
|
||||
*/
|
||||
@Override
|
||||
public AST negateNode(AST x) {
|
||||
|
@ -286,7 +285,7 @@ public final class HqlParser extends HqlBaseParser {
|
|||
*
|
||||
* @param x The equality expression.
|
||||
*
|
||||
* @return AST - The clean sub-tree.
|
||||
* @return The clean sub-tree.
|
||||
*/
|
||||
@Override
|
||||
public AST processEqualityExpression(AST x) {
|
||||
|
@ -348,6 +347,10 @@ public final class HqlParser extends HqlBaseParser {
|
|||
private AST createSubquery(AST node) {
|
||||
AST ast = ASTUtil.createParent( astFactory, RANGE, "RANGE", node );
|
||||
ast = ASTUtil.createParent( astFactory, FROM, "from", ast );
|
||||
|
||||
AST alias = ASTUtil.createSibling( astFactory, ALIAS, "_", node );
|
||||
ASTUtil.insertChild( ASTUtil.createSibling( astFactory, SELECT, "select", ast ), astFactory.create(IDENT, alias.getText() ) );
|
||||
|
||||
ast = ASTUtil.createParent( astFactory, SELECT_FROM, "SELECT_FROM", ast );
|
||||
ast = ASTUtil.createParent( astFactory, QUERY, "QUERY", ast );
|
||||
return ast;
|
||||
|
@ -489,12 +492,12 @@ public final class HqlParser extends HqlBaseParser {
|
|||
LOG.debugf( "Registering discovered request to treat(%s as %s)", path, subclassName );
|
||||
|
||||
if ( treatMap == null ) {
|
||||
treatMap = new HashMap<String, Set<String>>();
|
||||
treatMap = new HashMap<>();
|
||||
}
|
||||
|
||||
Set<String> subclassNames = treatMap.get( path );
|
||||
if ( subclassNames == null ) {
|
||||
subclassNames = new HashSet<String>();
|
||||
subclassNames = new HashSet<>();
|
||||
treatMap.put( path, subclassNames );
|
||||
}
|
||||
subclassNames.add( subclassName );
|
||||
|
@ -512,11 +515,11 @@ public final class HqlParser extends HqlBaseParser {
|
|||
}
|
||||
|
||||
public Map<String, Set<String>> getTreatMap() {
|
||||
return treatMap == null ? Collections.<String, Set<String>>emptyMap() : treatMap;
|
||||
return treatMap == null ? Collections.emptyMap() : treatMap;
|
||||
}
|
||||
|
||||
public static void panic() {
|
||||
//overriden to avoid System.exit
|
||||
//overridden to avoid System.exit
|
||||
throw new QueryException( "Parser: panic" );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,7 +72,6 @@ public class PluralAttributeExpressionsTest extends AbstractMetamodelSpecificTes
|
|||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-11225" )
|
||||
@FailureExpected( jiraKey = "HHH-6686")
|
||||
public void testElementMapIsEmptyHql() {
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
entityManager.createQuery( "select m from MapEntity m where m.localized is empty" ).getResultList();
|
||||
|
@ -81,7 +80,6 @@ public class PluralAttributeExpressionsTest extends AbstractMetamodelSpecificTes
|
|||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-11225" )
|
||||
@FailureExpected( jiraKey = "HHH-6686")
|
||||
public void testElementMapIsEmptyCriteria() {
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
final HibernateCriteriaBuilder cb = (HibernateCriteriaBuilder) entityManager.getCriteriaBuilder();
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
package org.hibernate.query;
|
||||
|
||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Nathan Xu
|
||||
*/
|
||||
@TestForIssue(jiraKey = "HHH-6686")
|
||||
public class IsEmptyJQLTest extends BaseEntityManagerFunctionalTestCase {
|
||||
|
||||
private Long personWithoutNicknameId = 1L;
|
||||
private Long personaWithSingleNicknameId = 2L;
|
||||
private Long personWithMultipleNicknamesId = 3L;
|
||||
|
||||
@Override
|
||||
public Class<?>[] getAnnotatedClasses() {
|
||||
return new Class[] { Person.class };
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJQLContainingEmpty() {
|
||||
List<Person> personWithNicknames = doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
return entityManager.createQuery(
|
||||
"select p from Person p where p.nicknames is not empty", Person.class )
|
||||
.getResultList();
|
||||
});
|
||||
|
||||
assertEquals( new HashSet<>( Arrays.asList(personaWithSingleNicknameId, personWithMultipleNicknamesId)),
|
||||
personWithNicknames.stream().map( Person::getId ).collect( Collectors.toSet() ));
|
||||
|
||||
List<Person> personWithOutNickname = doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
return entityManager.createQuery(
|
||||
"select p from Person p where p.nicknames is empty", Person.class )
|
||||
.getResultList();
|
||||
});
|
||||
|
||||
assertEquals( Collections.singleton(personWithoutNicknameId),
|
||||
personWithOutNickname.stream().map( Person::getId ).collect( Collectors.toSet() ));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterEntityManagerFactoryBuilt() {
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
Person personaWithoutNickname = new Person();
|
||||
personaWithoutNickname.setId(personWithoutNicknameId);
|
||||
|
||||
Person personaWithSingleNickname = new Person();
|
||||
personaWithSingleNickname.getNicknames().add( "nickname" );
|
||||
personaWithSingleNickname.setId(personaWithSingleNicknameId);
|
||||
|
||||
Person personWithMultipleNicknames = new Person();
|
||||
personWithMultipleNicknames.getNicknames().addAll( Arrays.asList( "nickName1", "nickName2" ) );
|
||||
personWithMultipleNicknames.setId(personWithMultipleNicknamesId);
|
||||
|
||||
entityManager.persist( personaWithoutNickname );
|
||||
entityManager.persist( personaWithSingleNickname );
|
||||
entityManager.persist( personWithMultipleNicknames );
|
||||
} );
|
||||
}
|
||||
|
||||
@Entity(name = "Person")
|
||||
public static class Person {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
@ElementCollection
|
||||
private List<String> nicknames = new ArrayList<>();
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public List<String> getNicknames() {
|
||||
return nicknames;
|
||||
}
|
||||
|
||||
public void setNicknames(List<String> nicknames) {
|
||||
this.nicknames = nicknames;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue