DATAJPA-44 - Adapted changes in Spring Data Commons Core.
Added unit tests to ensure correct named query name.
This commit is contained in:
@@ -24,7 +24,6 @@ import org.springframework.data.jpa.repository.query.JpaQueryExecution.SingleEnt
|
||||
import org.springframework.data.repository.query.Parameters;
|
||||
import org.springframework.data.repository.query.QueryMethod;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
import org.springframework.data.repository.support.EntityMetadata;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
||||
@@ -109,9 +108,8 @@ public abstract class AbstractJpaQuery implements RepositoryQuery {
|
||||
case PAGING:
|
||||
return new PagedExecution(getParameters());
|
||||
case MODIFYING:
|
||||
EntityMetadata<?> metadata = method.getEntityInformation();
|
||||
return method.getClearAutomatically() ? new ModifyingExecution(
|
||||
metadata, em) : new ModifyingExecution(metadata, null);
|
||||
method, em) : new ModifyingExecution(method, null);
|
||||
default:
|
||||
return new SingleEntityExecution();
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import org.springframework.data.repository.query.ParameterAccessor;
|
||||
import org.springframework.data.repository.query.Parameters;
|
||||
import org.springframework.data.repository.query.ParametersParameterAccessor;
|
||||
import org.springframework.data.repository.query.QueryMethod;
|
||||
import org.springframework.data.repository.support.EntityMetadata;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
||||
@@ -218,13 +217,16 @@ public abstract class JpaQueryExecution {
|
||||
*
|
||||
* @param em
|
||||
*/
|
||||
public ModifyingExecution(EntityMetadata<?> metadata, EntityManager em) {
|
||||
public ModifyingExecution(JpaQueryMethod method, EntityManager em) {
|
||||
|
||||
Class<?> type = metadata.getJavaType();
|
||||
Class<?> returnType = method.getReturnType();
|
||||
|
||||
boolean isVoid = void.class.equals(type) || Void.class.equals(type);
|
||||
boolean isVoid =
|
||||
void.class.equals(returnType)
|
||||
|| Void.class.equals(returnType);
|
||||
boolean isInt =
|
||||
int.class.equals(type) || Integer.class.equals(type);
|
||||
int.class.equals(returnType)
|
||||
|| Integer.class.equals(returnType);
|
||||
|
||||
Assert.isTrue(isInt || isVoid,
|
||||
"Modifying queries can only use void or int/Integer as return type!");
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.QueryLookupStrategy;
|
||||
import org.springframework.data.repository.query.QueryLookupStrategy.Key;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
import org.springframework.data.repository.support.RepositoryMetadata;
|
||||
|
||||
|
||||
/**
|
||||
@@ -68,9 +69,10 @@ public final class JpaQueryLookupStrategy {
|
||||
* #resolveQuery(org.springframework.data.repository.query.QueryMethod)
|
||||
*/
|
||||
public final RepositoryQuery resolveQuery(Method method,
|
||||
Class<?> domainClass) {
|
||||
RepositoryMetadata metadata) {
|
||||
|
||||
return resolveQuery(new JpaQueryMethod(method, provider), em);
|
||||
return resolveQuery(new JpaQueryMethod(method, metadata, provider),
|
||||
em);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.jpa.repository.QueryHints;
|
||||
import org.springframework.data.repository.query.Parameters;
|
||||
import org.springframework.data.repository.query.QueryMethod;
|
||||
import org.springframework.data.repository.support.RepositoryMetadata;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -52,9 +53,10 @@ public class JpaQueryMethod extends QueryMethod {
|
||||
* @param extractor must not be {@literal null}
|
||||
* @param metadata must not be {@literal null}
|
||||
*/
|
||||
public JpaQueryMethod(Method method, QueryExtractor extractor) {
|
||||
public JpaQueryMethod(Method method, RepositoryMetadata metadata,
|
||||
QueryExtractor extractor) {
|
||||
|
||||
super(method);
|
||||
super(method, metadata);
|
||||
|
||||
Assert.notNull(method, "Method must not be null!");
|
||||
Assert.notNull(extractor, "Query extractor must not be null!");
|
||||
@@ -129,6 +131,17 @@ public class JpaQueryMethod extends QueryMethod {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the actual return type of the method.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Class<?> getReturnType() {
|
||||
|
||||
return method.getReturnType();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the query string declared in a {@link Query} annotation or
|
||||
* {@literal null} if neither the annotation found nor the attribute was
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package org.springframework.data.jpa.domain.sample;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class SpecialUser extends User {
|
||||
|
||||
}
|
||||
@@ -28,9 +28,7 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.mockito.stubbing.OngoingStubbing;
|
||||
import org.springframework.data.jpa.repository.query.JpaQueryExecution.ModifyingExecution;
|
||||
import org.springframework.data.repository.support.EntityMetadata;
|
||||
|
||||
|
||||
/**
|
||||
@@ -50,7 +48,7 @@ public class JpaQueryExecutionUnitTests {
|
||||
@Mock
|
||||
Query query;
|
||||
@Mock
|
||||
EntityMetadata<?> metadata;
|
||||
JpaQueryMethod method;
|
||||
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@@ -100,46 +98,41 @@ public class JpaQueryExecutionUnitTests {
|
||||
|
||||
|
||||
@Test
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public void modifyingExecutionClearsEntityManagerIfSet() {
|
||||
|
||||
Query param = any();
|
||||
when(binder.bind(param)).thenReturn(query);
|
||||
when(query.executeUpdate()).thenReturn(0);
|
||||
mock(metadata, void.class);
|
||||
when(method.getReturnType()).thenReturn((Class) void.class);
|
||||
|
||||
ModifyingExecution execution = new ModifyingExecution(metadata, em);
|
||||
ModifyingExecution execution = new ModifyingExecution(method, em);
|
||||
execution.execute(jpaQuery, binder);
|
||||
|
||||
verify(em, times(1)).clear();
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private void mock(EntityMetadata<?> method, Class<?> type,
|
||||
Class<?>... others) {
|
||||
|
||||
OngoingStubbing stubbing = when(method.getJavaType());
|
||||
stubbing.thenReturn(type);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public void allowsMethodReturnTypesForModifyingQuery() throws Exception {
|
||||
|
||||
mock(metadata, void.class, int.class, Integer.class);
|
||||
when(method.getReturnType()).thenReturn((Class) void.class,
|
||||
(Class) int.class, (Class) Integer.class);
|
||||
|
||||
new ModifyingExecution(metadata, em);
|
||||
new ModifyingExecution(metadata, em);
|
||||
new ModifyingExecution(metadata, em);
|
||||
new ModifyingExecution(method, em);
|
||||
new ModifyingExecution(method, em);
|
||||
new ModifyingExecution(method, em);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void modifyingExecutionRejectsNonIntegerOrVoidReturnType()
|
||||
throws Exception {
|
||||
|
||||
mock(metadata, Long.class);
|
||||
new ModifyingExecution(metadata, em);
|
||||
when(method.getReturnType()).thenReturn((Class) Long.class);
|
||||
new ModifyingExecution(method, em);
|
||||
}
|
||||
|
||||
static class StubQueryExecution extends JpaQueryExecution {
|
||||
|
||||
@@ -37,6 +37,8 @@ import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.data.jpa.repository.sample.UserRepository;
|
||||
import org.springframework.data.repository.query.QueryMethod;
|
||||
import org.springframework.data.repository.query.QueryMethod.Type;
|
||||
import org.springframework.data.repository.support.DefaultRepositoryMetadata;
|
||||
import org.springframework.data.repository.support.RepositoryMetadata;
|
||||
|
||||
|
||||
/**
|
||||
@@ -52,6 +54,8 @@ public class JpaQueryMethodUnitTests {
|
||||
|
||||
@Mock
|
||||
QueryExtractor extractor;
|
||||
@Mock
|
||||
RepositoryMetadata metadata;
|
||||
|
||||
Method repositoryMethod, invalidReturnType, pageableAndSort, pageableTwice,
|
||||
sortableTwice, modifyingMethod;
|
||||
@@ -88,7 +92,8 @@ public class JpaQueryMethodUnitTests {
|
||||
@Test
|
||||
public void testname() {
|
||||
|
||||
JpaQueryMethod method = new JpaQueryMethod(repositoryMethod, extractor);
|
||||
JpaQueryMethod method =
|
||||
new JpaQueryMethod(repositoryMethod, metadata, extractor);
|
||||
|
||||
assertEquals("User.findByLastname", method.getNamedQueryName());
|
||||
assertThat(method.getType(), is(Type.COLLECTION));
|
||||
@@ -98,21 +103,22 @@ public class JpaQueryMethodUnitTests {
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void preventsNullRepositoryMethod() {
|
||||
|
||||
new JpaQueryMethod(null, extractor);
|
||||
new JpaQueryMethod(null, metadata, extractor);
|
||||
}
|
||||
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void preventsNullQueryExtractor() {
|
||||
|
||||
new JpaQueryMethod(repositoryMethod, null);
|
||||
new JpaQueryMethod(repositoryMethod, metadata, null);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void returnsCorrectName() {
|
||||
|
||||
JpaQueryMethod method = new JpaQueryMethod(repositoryMethod, extractor);
|
||||
JpaQueryMethod method =
|
||||
new JpaQueryMethod(repositoryMethod, metadata, extractor);
|
||||
assertEquals(repositoryMethod.getName(), method.getName());
|
||||
}
|
||||
|
||||
@@ -120,7 +126,8 @@ public class JpaQueryMethodUnitTests {
|
||||
@Test
|
||||
public void returnsQueryIfAvailable() throws Exception {
|
||||
|
||||
JpaQueryMethod method = new JpaQueryMethod(repositoryMethod, extractor);
|
||||
JpaQueryMethod method =
|
||||
new JpaQueryMethod(repositoryMethod, metadata, extractor);
|
||||
|
||||
assertNull(method.getAnnotatedQuery());
|
||||
|
||||
@@ -128,7 +135,7 @@ public class JpaQueryMethodUnitTests {
|
||||
UserRepository.class.getMethod("findByAnnotatedQuery",
|
||||
String.class);
|
||||
|
||||
assertNotNull(new JpaQueryMethod(repositoryMethod, extractor)
|
||||
assertNotNull(new JpaQueryMethod(repositoryMethod, metadata, extractor)
|
||||
.getAnnotatedQuery());
|
||||
}
|
||||
|
||||
@@ -136,28 +143,28 @@ public class JpaQueryMethodUnitTests {
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void rejectsInvalidReturntypeOnPagebleFinder() {
|
||||
|
||||
new JpaQueryMethod(invalidReturnType, extractor);
|
||||
new JpaQueryMethod(invalidReturnType, metadata, extractor);
|
||||
}
|
||||
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void rejectsPageableAndSortInFinderMethod() {
|
||||
|
||||
new JpaQueryMethod(pageableAndSort, extractor);
|
||||
new JpaQueryMethod(pageableAndSort, metadata, extractor);
|
||||
}
|
||||
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void rejectsTwoPageableParameters() {
|
||||
|
||||
new JpaQueryMethod(pageableTwice, extractor);
|
||||
new JpaQueryMethod(pageableTwice, metadata, extractor);
|
||||
}
|
||||
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void rejectsTwoSortableParameters() {
|
||||
|
||||
new JpaQueryMethod(sortableTwice, extractor);
|
||||
new JpaQueryMethod(sortableTwice, metadata, extractor);
|
||||
}
|
||||
|
||||
|
||||
@@ -171,14 +178,15 @@ public class JpaQueryMethodUnitTests {
|
||||
|
||||
when(extractor.canExtractQuery()).thenReturn(false);
|
||||
|
||||
new JpaQueryMethod(method, extractor);
|
||||
new JpaQueryMethod(method, metadata, extractor);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void recognizesModifyingMethod() {
|
||||
|
||||
JpaQueryMethod method = new JpaQueryMethod(modifyingMethod, extractor);
|
||||
JpaQueryMethod method =
|
||||
new JpaQueryMethod(modifyingMethod, metadata, extractor);
|
||||
assertTrue(method.isModifyingQuery());
|
||||
}
|
||||
|
||||
@@ -190,7 +198,7 @@ public class JpaQueryMethodUnitTests {
|
||||
InvalidRepository.class.getMethod("updateMethod", String.class,
|
||||
Pageable.class);
|
||||
|
||||
new JpaQueryMethod(method, extractor);
|
||||
new JpaQueryMethod(method, metadata, extractor);
|
||||
}
|
||||
|
||||
|
||||
@@ -201,14 +209,15 @@ public class JpaQueryMethodUnitTests {
|
||||
InvalidRepository.class.getMethod("updateMethod", String.class,
|
||||
Sort.class);
|
||||
|
||||
new JpaQueryMethod(method, extractor);
|
||||
new JpaQueryMethod(method, metadata, extractor);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void discoversHintsCorrectly() {
|
||||
|
||||
JpaQueryMethod method = new JpaQueryMethod(repositoryMethod, extractor);
|
||||
JpaQueryMethod method =
|
||||
new JpaQueryMethod(repositoryMethod, metadata, extractor);
|
||||
List<QueryHint> hints = method.getHints();
|
||||
|
||||
assertNotNull(hints);
|
||||
@@ -216,6 +225,31 @@ public class JpaQueryMethodUnitTests {
|
||||
assertThat(hints.get(0).value(), is("bar"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void calculatesNamedQueryNamesCorrectly() throws SecurityException,
|
||||
NoSuchMethodException {
|
||||
|
||||
JpaQueryMethod queryMethod =
|
||||
new JpaQueryMethod(repositoryMethod, metadata, extractor);
|
||||
assertThat(queryMethod.getNamedQueryName(), is("User.findByLastname"));
|
||||
|
||||
RepositoryMetadata metadata =
|
||||
new DefaultRepositoryMetadata(UserRepository.class);
|
||||
Method method =
|
||||
UserRepository.class
|
||||
.getMethod("renameAllUsersTo", String.class);
|
||||
queryMethod = new JpaQueryMethod(method, metadata, extractor);
|
||||
assertThat(queryMethod.getNamedQueryName(), is("User.renameAllUsersTo"));
|
||||
|
||||
method =
|
||||
UserRepository.class.getMethod("findSpecialUsersByLastname",
|
||||
String.class);
|
||||
queryMethod = new JpaQueryMethod(method, metadata, extractor);
|
||||
assertThat(queryMethod.getNamedQueryName(),
|
||||
is("SpecialUser.findSpecialUsersByLastname"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface to define invalid repository methods for testing.
|
||||
*
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.data.jpa.repository.QueryHints;
|
||||
import org.springframework.data.jpa.repository.sample.UserRepository;
|
||||
import org.springframework.data.repository.support.RepositoryMetadata;
|
||||
|
||||
|
||||
/**
|
||||
@@ -51,6 +52,8 @@ public class SimpleJpaQueryUnitTests {
|
||||
QueryExtractor extractor;
|
||||
@Mock
|
||||
Query query;
|
||||
@Mock
|
||||
RepositoryMetadata metadata;
|
||||
|
||||
|
||||
@Before
|
||||
@@ -61,7 +64,7 @@ public class SimpleJpaQueryUnitTests {
|
||||
|
||||
Method setUp =
|
||||
UserRepository.class.getMethod("findByLastname", String.class);
|
||||
method = new JpaQueryMethod(setUp, extractor);
|
||||
method = new JpaQueryMethod(setUp, metadata, extractor);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import javax.persistence.QueryHint;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.jpa.domain.sample.SpecialUser;
|
||||
import org.springframework.data.jpa.domain.sample.User;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
@@ -208,4 +209,7 @@ public interface UserRepository extends JpaRepository<User, Integer>,
|
||||
|
||||
|
||||
List<User> findByEmailAddressLike(String email, Sort sort);
|
||||
|
||||
|
||||
List<SpecialUser> findSpecialUsersByLastname(String lastname);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user