HHH-18850 fix count queries with 'distinct' and 'order by'
This commit is contained in:
parent
7cdab319fb
commit
9a219c2c30
|
@ -6,13 +6,15 @@ package org.hibernate.query.sqm.tree.select;
|
|||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.sqm.tree.SqmCopyContext;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmAliasedNodeRef;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmExpression;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.unmodifiableList;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
|
@ -69,12 +71,7 @@ public class SqmOrderByClause implements Serializable {
|
|||
}
|
||||
|
||||
public List<SqmSortSpecification> getSortSpecifications() {
|
||||
if ( sortSpecifications == null ) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
else {
|
||||
return Collections.unmodifiableList( sortSpecifications );
|
||||
}
|
||||
return sortSpecifications == null ? emptyList() : unmodifiableList( sortSpecifications );
|
||||
}
|
||||
|
||||
public void setSortSpecifications(List<SqmSortSpecification> sortSpecifications) {
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
*/
|
||||
package org.hibernate.query.sqm.tree.select;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.common.FetchClauseType;
|
||||
|
@ -16,6 +15,8 @@ import org.hibernate.query.sqm.tree.SqmCopyContext;
|
|||
import org.hibernate.query.sqm.tree.SqmVisitableNode;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmExpression;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
|
||||
/**
|
||||
* Defines the ordering and fetch/offset part of a query which is shared with query groups.
|
||||
*
|
||||
|
@ -127,11 +128,7 @@ public abstract class SqmQueryPart<T> implements SqmVisitableNode, JpaQueryPart<
|
|||
|
||||
@Override
|
||||
public List<SqmSortSpecification> getSortSpecifications() {
|
||||
if ( getOrderByClause() == null ) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return getOrderByClause().getSortSpecifications();
|
||||
return getOrderByClause() == null ? emptyList() : getOrderByClause().getSortSpecifications();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -549,6 +549,9 @@ public class SqmSelectStatement<T> extends AbstractSqmSelectQuery<T> implements
|
|||
final SqmSelectStatement<Long> query = nodeBuilder().createQuery( Long.class );
|
||||
query.from( subquery );
|
||||
query.select( nodeBuilder().count() );
|
||||
if ( subquery.getFetch() == null && subquery.getOffset() == null ) {
|
||||
subquery.getQueryPart().setOrderByClause( null );
|
||||
}
|
||||
return query;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
* Copyright Red Hat Inc. and Hibernate Authors
|
||||
*/
|
||||
package org.hibernate.orm.test.id.idClass;
|
||||
|
||||
|
@ -16,23 +14,23 @@ import org.junit.jupiter.api.Test;
|
|||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@DomainModel(
|
||||
annotatedClasses = MyEntity.class
|
||||
annotatedClasses = MyEntity.class
|
||||
)
|
||||
@SessionFactory
|
||||
public class IdClassSyntheticAttributesTest {
|
||||
|
||||
@Jira("https://hibernate.atlassian.net/browse/HHH-18841")
|
||||
@Test
|
||||
public void test(DomainModelScope scope) {
|
||||
final PersistentClass entityBinding = scope.getDomainModel().getEntityBinding(MyEntity.class.getName());
|
||||
assertThat(entityBinding.getProperties()).hasSize(2)
|
||||
.anySatisfy(p -> {
|
||||
assertThat(p.isSynthetic()).isTrue();
|
||||
assertThat(p.getName()).isEqualTo("_identifierMapper");
|
||||
})
|
||||
.anySatisfy(p -> {
|
||||
assertThat(p.isSynthetic()).isFalse();
|
||||
assertThat(p.getName()).isEqualTo("notes");
|
||||
});
|
||||
}
|
||||
@Jira("https://hibernate.atlassian.net/browse/HHH-18841")
|
||||
@Test
|
||||
public void test(DomainModelScope scope) {
|
||||
final PersistentClass entityBinding = scope.getDomainModel().getEntityBinding(MyEntity.class.getName());
|
||||
assertThat(entityBinding.getProperties()).hasSize(2)
|
||||
.anySatisfy(p -> {
|
||||
assertThat(p.isSynthetic()).isTrue();
|
||||
assertThat(p.getName()).isEqualTo("_identifierMapper");
|
||||
})
|
||||
.anySatisfy(p -> {
|
||||
assertThat(p.isSynthetic()).isFalse();
|
||||
assertThat(p.getName()).isEqualTo("notes");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,6 +84,48 @@ public class CountQueryTests {
|
|||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@JiraKey( "HHH-18850" )
|
||||
public void testForHHH18850(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
HibernateCriteriaBuilder cb = session.getCriteriaBuilder();
|
||||
JpaCriteriaQuery<Contract> cq = cb.createQuery( Contract.class );
|
||||
cq.distinct( true );
|
||||
Root<Contract> root = cq.from( Contract.class );
|
||||
cq.select( root );
|
||||
cq.orderBy( cb.asc( root.get( "customerName" ) ) );
|
||||
TypedQuery<Long> query = session.createQuery( cq.createCountQuery() );
|
||||
try {
|
||||
// Leads to NPE on pre-6.5 versions
|
||||
query.getSingleResult();
|
||||
}
|
||||
catch (Exception e) {
|
||||
fail( e );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
HibernateCriteriaBuilder cb = session.getCriteriaBuilder();
|
||||
JpaCriteriaQuery<Contract> cq = cb.createQuery( Contract.class );
|
||||
cq.distinct( false );
|
||||
Root<Contract> root = cq.from( Contract.class );
|
||||
cq.select( root );
|
||||
cq.orderBy( cb.desc( root.get( "customerName" ) ) );
|
||||
TypedQuery<Long> query = session.createQuery( cq.createCountQuery() );
|
||||
try {
|
||||
// Leads to NPE on pre-6.5 versions
|
||||
query.getSingleResult();
|
||||
}
|
||||
catch (Exception e) {
|
||||
fail( e );
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@JiraKey("HHH-17410")
|
||||
public void testBasic(SessionFactoryScope scope) {
|
||||
|
|
Loading…
Reference in New Issue