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