Fix native named query max results
This commit is contained in:
parent
74e1e6caad
commit
07f3d6727f
|
@ -27,6 +27,8 @@ public class NamedNativeQueryDefinitionImpl extends AbstractNamedQueryDefinition
|
|||
private final String resultSetMappingName;
|
||||
private final String resultSetMappingClassName;
|
||||
private final Set<String> querySpaces;
|
||||
private Integer firstResult;
|
||||
private Integer maxResults;
|
||||
|
||||
public NamedNativeQueryDefinitionImpl(
|
||||
String name,
|
||||
|
@ -42,6 +44,8 @@ public class NamedNativeQueryDefinitionImpl extends AbstractNamedQueryDefinition
|
|||
Integer timeout,
|
||||
Integer fetchSize,
|
||||
String comment,
|
||||
Integer firstResult,
|
||||
Integer maxResults,
|
||||
Map<String,Object> hints) {
|
||||
super(
|
||||
name,
|
||||
|
@ -60,6 +64,8 @@ public class NamedNativeQueryDefinitionImpl extends AbstractNamedQueryDefinition
|
|||
this.resultSetMappingName = resultSetMappingName;
|
||||
this.resultSetMappingClassName = resultSetMappingClassName;
|
||||
this.querySpaces = querySpaces;
|
||||
this.firstResult = firstResult;
|
||||
this.maxResults = maxResults;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -97,6 +103,8 @@ public class NamedNativeQueryDefinitionImpl extends AbstractNamedQueryDefinition
|
|||
getTimeout(),
|
||||
getFetchSize(),
|
||||
getComment(),
|
||||
firstResult,
|
||||
maxResults,
|
||||
getHints()
|
||||
);
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@ public class NamedNativeQueryDefinitionBuilder extends AbstractNamedQueryBuilder
|
|||
private Set<String> querySpaces;
|
||||
|
||||
private Map<String, String> parameterTypes;
|
||||
private Integer firstResult;
|
||||
private Integer maxResults;
|
||||
|
||||
public NamedNativeQueryDefinitionBuilder(String name) {
|
||||
super( name );
|
||||
|
@ -38,6 +40,16 @@ public class NamedNativeQueryDefinitionBuilder extends AbstractNamedQueryBuilder
|
|||
return getThis();
|
||||
}
|
||||
|
||||
public NamedNativeQueryDefinitionBuilder setFirstResult(Integer firstResult) {
|
||||
this.firstResult = firstResult;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
public NamedNativeQueryDefinitionBuilder setMaxResults(Integer maxResults) {
|
||||
this.maxResults = maxResults;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
public NamedNativeQueryDefinition build() {
|
||||
return new NamedNativeQueryDefinitionImpl(
|
||||
getName(),
|
||||
|
@ -53,6 +65,8 @@ public class NamedNativeQueryDefinitionBuilder extends AbstractNamedQueryBuilder
|
|||
getTimeout(),
|
||||
getFetchSize(),
|
||||
getComment(),
|
||||
firstResult,
|
||||
maxResults,
|
||||
getHints()
|
||||
);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ import org.hibernate.FlushMode;
|
|||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.query.named.AbstractNamedQueryMemento;
|
||||
import org.hibernate.query.spi.QueryEngine;
|
||||
import org.hibernate.query.spi.QueryImplementor;
|
||||
import org.hibernate.query.sql.spi.NamedNativeQueryMemento;
|
||||
import org.hibernate.query.sql.spi.NativeQueryImplementor;
|
||||
|
||||
|
@ -32,6 +31,10 @@ public class NamedNativeQueryMementoImpl extends AbstractNamedQueryMemento imple
|
|||
|
||||
private final Set<String> querySpaces;
|
||||
|
||||
private final Integer firstResult;
|
||||
|
||||
private final Integer maxResults;
|
||||
|
||||
public NamedNativeQueryMementoImpl(
|
||||
String name,
|
||||
String sqlString,
|
||||
|
@ -46,6 +49,8 @@ public class NamedNativeQueryMementoImpl extends AbstractNamedQueryMemento imple
|
|||
Integer timeout,
|
||||
Integer fetchSize,
|
||||
String comment,
|
||||
Integer firstResult,
|
||||
Integer maxResults,
|
||||
Map<String,Object> hints) {
|
||||
super(
|
||||
name,
|
||||
|
@ -65,6 +70,8 @@ public class NamedNativeQueryMementoImpl extends AbstractNamedQueryMemento imple
|
|||
: resultSetMappingName;
|
||||
this.resultSetMappingClass = resultSetMappingClass;
|
||||
this.querySpaces = querySpaces;
|
||||
this.firstResult = firstResult;
|
||||
this.maxResults = maxResults;
|
||||
}
|
||||
|
||||
public String getResultSetMappingName() {
|
||||
|
@ -94,6 +101,16 @@ public class NamedNativeQueryMementoImpl extends AbstractNamedQueryMemento imple
|
|||
return resultSetMappingClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getFirstResult() {
|
||||
return firstResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getMaxResults() {
|
||||
return maxResults;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NamedNativeQueryMemento makeCopy(String name) {
|
||||
return new NamedNativeQueryMementoImpl(
|
||||
|
@ -110,6 +127,8 @@ public class NamedNativeQueryMementoImpl extends AbstractNamedQueryMemento imple
|
|||
getTimeout(),
|
||||
getFetchSize(),
|
||||
getComment(),
|
||||
getFirstResult(),
|
||||
getMaxResults(),
|
||||
getHints()
|
||||
);
|
||||
}
|
||||
|
|
|
@ -360,6 +360,13 @@ public class NativeQueryImpl<R>
|
|||
protected void applyOptions(NamedNativeQueryMemento memento) {
|
||||
super.applyOptions( memento );
|
||||
|
||||
if ( memento.getMaxResults() != null ) {
|
||||
setMaxResults( memento.getMaxResults() );
|
||||
}
|
||||
if ( memento.getFirstResult() != null ) {
|
||||
setFirstResult( memento.getFirstResult() );
|
||||
}
|
||||
|
||||
final Set<String> copy = CollectionHelper.makeCopy( memento.getQuerySpaces() );
|
||||
if ( copy != null ) {
|
||||
this.querySpaces = copy;
|
||||
|
@ -457,8 +464,9 @@ public class NativeQueryImpl<R>
|
|||
getTimeout(),
|
||||
getFetchSize(),
|
||||
getComment(),
|
||||
getFirstResult(),
|
||||
getMaxResults(),
|
||||
getHints()
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,10 @@ public interface NamedNativeQueryMemento extends NamedQueryMemento {
|
|||
*/
|
||||
Class<?> getResultMappingClass();
|
||||
|
||||
Integer getFirstResult();
|
||||
|
||||
Integer getMaxResults();
|
||||
|
||||
/**
|
||||
* Convert the memento into an untyped executable query
|
||||
*/
|
||||
|
@ -142,6 +146,8 @@ public interface NamedNativeQueryMemento extends NamedQueryMemento {
|
|||
timeout,
|
||||
fetchSize,
|
||||
comment,
|
||||
firstResult,
|
||||
maxResults,
|
||||
hints
|
||||
);
|
||||
}
|
||||
|
|
|
@ -9,42 +9,55 @@ package org.hibernate.orm.test.jpa.compliance;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
|
||||
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.Jpa;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EntityManagerFactory;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Query;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.persistence.TypedQuery;
|
||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.CriteriaQuery;
|
||||
import jakarta.persistence.criteria.Root;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.hasItems;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@Jpa(
|
||||
annotatedClasses = NamedQueryTest.Person.class
|
||||
annotatedClasses = NamedQueryTest.Person.class,
|
||||
properties = @Setting(name = AvailableSettings.JPA_CRITERIA_COPY_COMPLIANCE, value = "true")
|
||||
)
|
||||
public class NamedQueryTest {
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup(EntityManagerFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
entityManager -> {
|
||||
Person person1 = new Person( 1, "Andrea" );
|
||||
Person person2 = new Person( 2, "Alberto" );
|
||||
|
||||
entityManager.persist( person1 );
|
||||
entityManager.persist( person2 );
|
||||
entityManager.persist( new Person( 1, "Andrea" ) );
|
||||
entityManager.persist( new Person( 2, "Alberto" ) );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearDown(EntityManagerFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
entityManager ->
|
||||
entityManager.createQuery( "delete from Person" ).executeUpdate()
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNameQueryCreationFromCritera(EntityManagerFactoryScope scope) {
|
||||
public void testNameQueryCreationFromCriteria(EntityManagerFactoryScope scope) {
|
||||
|
||||
final EntityManagerFactory entityManagerFactory = scope.getEntityManagerFactory();
|
||||
|
||||
|
@ -68,6 +81,74 @@ public class NamedQueryTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNativeWithMaxResults(EntityManagerFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
entityManager -> {
|
||||
final Query nativeQuery = entityManager.createNativeQuery(
|
||||
"Select p.id from PERSON_TABLE p" );
|
||||
nativeQuery.setMaxResults( 1 );
|
||||
scope.getEntityManagerFactory().addNamedQuery( "native", nativeQuery );
|
||||
|
||||
final Query namedQuery = entityManager.createNamedQuery( "native" );
|
||||
assertEquals( 1, namedQuery.getMaxResults() );
|
||||
|
||||
namedQuery.setMaxResults( 2 );
|
||||
assertEquals( 2, namedQuery.getMaxResults() );
|
||||
|
||||
final List<Integer> ids = namedQuery.getResultList();
|
||||
assertEquals( 2, ids.size() );
|
||||
assertThat( ids, hasItems( 1, 2 ) );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCriteriaWithMaxResults(EntityManagerFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
entityManager -> {
|
||||
final CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
|
||||
|
||||
final CriteriaQuery<Integer> criteriaQuery = criteriaBuilder.createQuery( Integer.class );
|
||||
final Root<Person> person = criteriaQuery.from( Person.class );
|
||||
criteriaQuery.select( person.get( "id" ) );
|
||||
criteriaQuery.orderBy( criteriaBuilder.asc( person.get( "id" ) ) );
|
||||
|
||||
final TypedQuery<Integer> typedQuery = entityManager.createQuery( criteriaQuery );
|
||||
typedQuery.setMaxResults( 1 );
|
||||
|
||||
scope.getEntityManagerFactory().addNamedQuery( "criteria", typedQuery );
|
||||
|
||||
final Query namedQuery = entityManager.createNamedQuery( "criteria" );
|
||||
assertEquals( 1, namedQuery.getMaxResults() );
|
||||
namedQuery.setMaxResults( 2 );
|
||||
assertEquals( 2, namedQuery.getMaxResults() );
|
||||
|
||||
final List<Integer> ids = namedQuery.getResultList();
|
||||
assertEquals( 2, ids.size() );
|
||||
assertThat( ids, hasItems( 1, 2 ) );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHqlWithMaxResults(EntityManagerFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
entityManager -> {
|
||||
final Query query = entityManager.createQuery( "Select p.id from Person p" );
|
||||
query.setMaxResults( 1 );
|
||||
scope.getEntityManagerFactory().addNamedQuery( "query", query );
|
||||
|
||||
final Query namedQuery = entityManager.createNamedQuery( "query" );
|
||||
assertEquals( 1, namedQuery.getMaxResults() );
|
||||
|
||||
namedQuery.setMaxResults( 2 );
|
||||
assertEquals( 2, namedQuery.getMaxResults() );
|
||||
|
||||
final List<Integer> ids = namedQuery.getResultList();
|
||||
assertEquals( 2, ids.size() );
|
||||
assertThat( ids, hasItems( 1, 2 ) );
|
||||
} );
|
||||
}
|
||||
|
||||
@Entity(name = "Person")
|
||||
@Table(name = "PERSON_TABLE")
|
||||
public static class Person {
|
||||
|
|
Loading…
Reference in New Issue