Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ buildscript {
plugins {
id 'me.champeau.buildscan-recipes' version '0.2.3'
id 'io.github.gradle-nexus.publish-plugin' version '1.1.0'
id 'nu.studer.credentials' version '2.1'
id 'nu.studer.credentials' version '2.2'
id 'org.hibernate.build.xjc' version '2.0.1' apply false
id 'org.hibernate.build.maven-repo-auth' version '3.0.3' apply false
id 'biz.aQute.bnd' version '5.1.1' apply false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
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;
Expand Down Expand Up @@ -116,7 +115,7 @@ public ParseErrorHandler getParseErrorHandler() {
* @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.
Expand Down Expand Up @@ -159,7 +158,7 @@ public AST handleIdentifierError(Token token, RecognitionException ex)
*
* @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) {
Expand Down Expand Up @@ -286,7 +285,7 @@ public AST negateNode(AST x) {
*
* @param x The equality expression.
*
* @return AST - The clean sub-tree.
* @return The clean sub-tree.
*/
@Override
public AST processEqualityExpression(AST x) {
Expand Down Expand Up @@ -348,6 +347,10 @@ private AST processIsEmpty(AST node, boolean negated) {
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;
Expand Down Expand Up @@ -489,12 +492,12 @@ protected void registerTreat(AST pathToTreat, AST treatAs) {
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 );
Expand All @@ -512,11 +515,11 @@ private String toPathText(AST node) {
}

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" );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ public void testCollectionIsEmptyCriteria() {

@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();
Expand All @@ -81,7 +80,6 @@ public void testElementMapIsEmptyHql() {

@Test
@TestForIssue( jiraKey = "HHH-11225" )
@FailureExpected( jiraKey = "HHH-6686")
public void testElementMapIsEmptyCriteria() {
doInJPA( this::entityManagerFactory, entityManager -> {
final HibernateCriteriaBuilder cb = (HibernateCriteriaBuilder) entityManager.getCriteriaBuilder();
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
}
}