DATAJPA-86 - Pagination over queries using group-by works correctly.

Added handling of count methods for queries using group by. In case the count query returns multiple results we use the number of results instead of failing. If the result contains one result we use this one.

Moved hint handling to AbstractJpaQuery.
This commit is contained in:
Oliver Gierke
2011-09-04 16:56:50 +02:00
parent 170d31707c
commit 04349d25dc
10 changed files with 89 additions and 85 deletions

View File

@@ -725,6 +725,18 @@ public class UserRepositoryTests {
assertThat(result, hasItem(firstUser));
}
/**
* @see DATADOC-86
*/
@Test
public void readsPageWithGroupByClauseCorrectly() {
flushTestUsers();
Page<String> result = repository.findByLastnameGrouped(new PageRequest(0, 10));
assertThat(result.getTotalPages(), is(1));
}
private Page<User> executeSpecWithSort(Sort sort) {
flushTestUsers();

View File

@@ -30,7 +30,7 @@ import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.data.jpa.repository.query.JpaQueryExecution.ModifyingExecution;
/**
* Unit test for {@link QueryExecution}.
* Unit test for {@link JpaQueryExecution}.
*
* @author Oliver Gierke
*/

View File

@@ -23,8 +23,7 @@ import static org.mockito.Mockito.*;
import java.lang.reflect.Method;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.QueryHint;
import javax.persistence.TypedQuery;
import org.junit.Before;
import org.junit.Test;
@@ -34,7 +33,6 @@ import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.QueryHints;
import org.springframework.data.jpa.repository.sample.UserRepository;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.query.Parameters;
@@ -54,31 +52,22 @@ public class SimpleJpaQueryUnitTests {
@Mock
QueryExtractor extractor;
@Mock
Query query;
TypedQuery<Long> query;
@Mock
RepositoryMetadata metadata;
@Mock
ParameterBinder binder;
@Before
@QueryHints(@QueryHint(name = "foo", value = "bar"))
public void setUp() throws SecurityException, NoSuchMethodException {
when(em.createQuery(anyString())).thenReturn(query);
when(em.createQuery(anyString(), eq(Long.class))).thenReturn(query);
Method setUp = UserRepository.class.getMethod("findByLastname", String.class);
method = new JpaQueryMethod(setUp, metadata, extractor);
}
@Test
public void appliesHintsCorrectly() throws Exception {
SimpleJpaQuery jpaQuery = new SimpleJpaQuery(method, em, "foobar");
jpaQuery.createQuery(new Object[] { "gierke" });
verify(query).setHint("foo", "bar");
}
@Test
public void prefersDeclaredCountQueryOverCreatingOne() throws Exception {
@@ -86,7 +75,7 @@ public class SimpleJpaQueryUnitTests {
when(method.getCountQuery()).thenReturn("foo");
when(method.getParameters()).thenReturn(
new Parameters(SimpleJpaQueryUnitTests.class.getMethod("prefersDeclaredCountQueryOverCreatingOne")));
when(em.createQuery("foo")).thenReturn(query);
when(em.createQuery("foo", Long.class)).thenReturn(query);
SimpleJpaQuery jpaQuery = new SimpleJpaQuery(method, em, "select u from User u");

View File

@@ -185,4 +185,9 @@ public interface UserRepository extends JpaRepository<User, Integer>, JpaSpecifi
List<User> findByLastnameAndFirstnameAllIgnoringCase(String lastname, String firstname);
/**
* @see DATADOC-86 - Count execution for group by
*/
@Query("select u.lastname from User u group by u.lastname")
Page<String> findByLastnameGrouped(Pageable pageable);
}