DATAJPA-218 - Polishing.

Adapted to API changes in Spring Data Commons.

Related tickets: DATACMNS-810.
Original pull request: #164.
This commit is contained in:
Oliver Gierke
2016-03-17 16:24:59 +01:00
parent 75f2719c61
commit ed7df2eceb
4 changed files with 58 additions and 73 deletions

View File

@@ -7,9 +7,7 @@ In Spring Data JPA you can use Query by Example with Repositories.
====
[source, java]
----
public interface PersonRepository extends JpaRepository<Person, String> {
}
public interface PersonRepository extends JpaRepository<Person, String> { … }
public class PersonService {
@@ -22,10 +20,7 @@ public class PersonService {
----
====
An `Example` containing an untyped `ExampleSpec` uses the Repository type. Typed `ExampleSpec` use their type for creating JPA queries.
NOTE: Only SingularAttribute properties can be used for property matching.
NOTE: Only `SingularAttribute` properties can currently be used for property matching.
Property specifier accepts property names (e.g. "firstname" and "lastname"). You can navigate by chaining properties together with dots ("address.city"). You can tune it with matching options and case sensitivity.

View File

@@ -34,8 +34,8 @@ import javax.persistence.metamodel.SingularAttribute;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleSpec;
import org.springframework.data.repository.core.support.ExampleSpecAccessor;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.repository.core.support.ExampleMatcherAccessor;
import org.springframework.data.util.DirectFieldAccessFallbackBeanWrapper;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.util.Assert;
@@ -78,7 +78,7 @@ public class QueryByExamplePredicateBuilder {
Assert.notNull(example, "Example must not be null!");
List<Predicate> predicates = getPredicates("", cb, root, root.getModel(), example.getProbe(),
example.getProbeType(), new ExampleSpecAccessor(example.getExampleSpec()),
example.getProbeType(), new ExampleMatcherAccessor(example.getMatcher()),
new PathNode("root", null, example.getProbe()));
if (predicates.isEmpty()) {
@@ -94,7 +94,7 @@ public class QueryByExamplePredicateBuilder {
@SuppressWarnings({ "rawtypes", "unchecked" })
static List<Predicate> getPredicates(String path, CriteriaBuilder cb, Path<?> from, ManagedType<?> type, Object value,
Class<?> probeType, ExampleSpecAccessor exampleAccessor, PathNode currentNode) {
Class<?> probeType, ExampleMatcherAccessor exampleAccessor, PathNode currentNode) {
List<Predicate> predicates = new ArrayList<Predicate>();
DirectFieldAccessFallbackBeanWrapper beanWrapper = new DirectFieldAccessFallbackBeanWrapper(value);
@@ -112,7 +112,7 @@ public class QueryByExamplePredicateBuilder {
if (attributeValue == null) {
if (exampleAccessor.getNullHandler().equals(ExampleSpec.NullHandler.INCLUDE)) {
if (exampleAccessor.getNullHandler().equals(ExampleMatcher.NullHandler.INCLUDE)) {
predicates.add(cb.isNull(from.get(attribute)));
}
continue;

View File

@@ -44,7 +44,6 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.TypedExampleSpec;
import org.springframework.data.jpa.convert.QueryByExamplePredicateBuilder;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.provider.PersistenceProvider;
@@ -148,8 +147,8 @@ public class SimpleJpaRepository<T, ID extends Serializable>
T entity = findOne(id);
if (entity == null) {
throw new EmptyResultDataAccessException(String.format("No %s entity with id %s exists!",
entityInformation.getJavaType(), id), 1);
throw new EmptyResultDataAccessException(
String.format("No %s entity with id %s exists!", entityInformation.getJavaType(), id), 1);
}
delete(entity);
@@ -422,7 +421,7 @@ public class SimpleJpaRepository<T, ID extends Serializable>
@Override
public <S extends T> S findOne(Example<S> example) {
try {
return getQuery(new ExampleSpecification<S>(example), getResultType(example), (Sort) null).getSingleResult();
return getQuery(new ExampleSpecification<S>(example), example.getProbeType(), (Sort) null).getSingleResult();
} catch (NoResultException e) {
return null;
}
@@ -431,10 +430,10 @@ public class SimpleJpaRepository<T, ID extends Serializable>
/* (non-Javadoc)
* @see org.springframework.data.repository.query.QueryByExampleExecutor#count(org.springframework.data.domain.Example)
*/
@SuppressWarnings("unchecked")
@Override
@SuppressWarnings("unchecked")
public <S extends T> long count(Example<S> example) {
return executeCountQuery(getCountQuery(new ExampleSpecification<S>(example), getResultType(example)));
return executeCountQuery(getCountQuery(new ExampleSpecification<S>(example), example.getProbeType()));
}
/* (non-Javadoc)
@@ -442,7 +441,7 @@ public class SimpleJpaRepository<T, ID extends Serializable>
*/
@Override
public <S extends T> boolean exists(Example<S> example) {
return !getQuery(new ExampleSpecification<S>(example), getResultType(example), (Sort) null).getResultList()
return !getQuery(new ExampleSpecification<S>(example), example.getProbeType(), (Sort) null).getResultList()
.isEmpty();
}
@@ -452,7 +451,7 @@ public class SimpleJpaRepository<T, ID extends Serializable>
*/
@Override
public <S extends T> List<S> findAll(Example<S> example) {
return getQuery(new ExampleSpecification<S>(example), getResultType(example), (Sort) null).getResultList();
return getQuery(new ExampleSpecification<S>(example), example.getProbeType(), (Sort) null).getResultList();
}
/*
@@ -461,7 +460,7 @@ public class SimpleJpaRepository<T, ID extends Serializable>
*/
@Override
public <S extends T> List<S> findAll(Example<S> example, Sort sort) {
return getQuery(new ExampleSpecification<S>(example), getResultType(example), sort).getResultList();
return getQuery(new ExampleSpecification<S>(example), example.getProbeType(), sort).getResultList();
}
/*
@@ -472,9 +471,10 @@ public class SimpleJpaRepository<T, ID extends Serializable>
public <S extends T> Page<S> findAll(Example<S> example, Pageable pageable) {
ExampleSpecification<S> spec = new ExampleSpecification<S>(example);
TypedQuery<S> query = getQuery(new ExampleSpecification<S>(example), getResultType(example), pageable);
return pageable == null ? new PageImpl<S>(query.getResultList())
: readPage(query, getResultType(example), pageable, spec);
Class<S> probeType = example.getProbeType();
TypedQuery<S> query = getQuery(new ExampleSpecification<S>(example), probeType, pageable);
return pageable == null ? new PageImpl<S>(query.getResultList()) : readPage(query, probeType, pageable, spec);
}
/*
@@ -743,15 +743,6 @@ public class SimpleJpaRepository<T, ID extends Serializable>
}
}
private <S extends T> Class<S> getResultType(Example<S> example) {
if(example.getExampleSpec() instanceof TypedExampleSpec<?>){
return example.getResultType();
}
return (Class<S>) getDomainClass();
}
/**
* Executes a count query and transparently sums up all values returned.
*

View File

@@ -19,6 +19,7 @@ import static org.hamcrest.Matchers.*;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.*;
import static org.springframework.data.domain.Example.*;
import static org.springframework.data.domain.ExampleMatcher.*;
import static org.springframework.data.domain.Sort.Direction.*;
import static org.springframework.data.jpa.domain.Specifications.*;
import static org.springframework.data.jpa.domain.Specifications.not;
@@ -53,9 +54,9 @@ import org.springframework.dao.DataAccessException;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleSpec;
import org.springframework.data.domain.ExampleSpec.GenericPropertyMatcher;
import org.springframework.data.domain.ExampleSpec.StringMatcher;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.ExampleMatcher.GenericPropertyMatcher;
import org.springframework.data.domain.ExampleMatcher.StringMatcher;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
@@ -530,8 +531,8 @@ public class UserRepositoryTests {
firstUser = repository.save(firstUser);
secondUser = repository.save(secondUser);
assertTrue(repository.findByLastnameOrFirstname("Oliver", "Arrasz").containsAll(
Arrays.asList(firstUser, secondUser)));
assertTrue(
repository.findByLastnameOrFirstname("Oliver", "Arrasz").containsAll(Arrays.asList(firstUser, secondUser)));
}
@Test
@@ -1297,7 +1298,7 @@ public class UserRepositoryTests {
repository.saveAndFlush(user);
List<User> result = repository
.findAll(Example.of(new User(), ExampleSpec.untyped().withIgnorePaths("age", "createdAt", "dateOfBirth")));
.findAll(Example.of(new User(), ExampleMatcher.matching().withIgnorePaths("age", "createdAt", "dateOfBirth")));
assertThat(result, hasSize(5));
}
@@ -1316,8 +1317,7 @@ public class UserRepositoryTests {
repository.saveAndFlush(user);
Example<User> example = Example.of(new User(),
ExampleSpec.typed(User.class).withIgnorePaths("age", "createdAt", "dateOfBirth"));
Example<User> example = Example.of(new User(), matching().withIgnorePaths("age", "createdAt", "dateOfBirth"));
List<User> result = repository.findAll(example);
assertThat(result, hasSize(5));
@@ -1337,9 +1337,9 @@ public class UserRepositoryTests {
repository.saveAndFlush(user);
Example<User> example = Example.of(new User(),
ExampleSpec.typed(SpecialUser.class).withIgnorePaths("age", "createdAt", "dateOfBirth"));
List<User> result = repository.findAll(example);
Example<SpecialUser> example = Example.of(new SpecialUser(),
matching().withIgnorePaths("age", "createdAt", "dateOfBirth"));
List<SpecialUser> result = repository.findAll(example);
assertThat(result, hasSize(1));
}
@@ -1835,8 +1835,8 @@ public class UserRepositoryTests {
public void shouldfindUsersBySpELExpressionParametersWithSpelTemplateExpression() {
flushTestUsers();
List<User> users = repository.findUsersByFirstnameForSpELExpressionWithParameterIndexOnlyWithEntityExpression(
"Joachim", "Arrasz");
List<User> users = repository
.findUsersByFirstnameForSpELExpressionWithParameterIndexOnlyWithEntityExpression("Joachim", "Arrasz");
assertThat(users, hasSize(1));
assertThat(users.get(0), is(secondUser));
@@ -2008,7 +2008,7 @@ public class UserRepositoryTests {
prototype.setCreatedAt(null);
List<User> users = repository
.findAll(of(prototype, ExampleSpec.untyped().withIgnorePaths("age", "createdAt", "active")));
.findAll(of(prototype, ExampleMatcher.matching().withIgnorePaths("age", "createdAt", "active")));
assertThat(users, hasSize(4));
}
@@ -2018,7 +2018,7 @@ public class UserRepositoryTests {
*/
@Test(expected = InvalidDataAccessApiUsageException.class)
public void findAllByNullExample() {
repository.findAll((Example) null);
repository.findAll((Example<User>) null);
}
/**
@@ -2032,7 +2032,7 @@ public class UserRepositoryTests {
User prototype = new User();
prototype.setAge(28);
Example<User> example = Example.of(prototype, ExampleSpec.typed(User.class).withIgnorePaths("createdAt"));
Example<User> example = Example.of(prototype, matching().withIgnorePaths("createdAt"));
List<User> users = repository.findAll(example);
assertThat(users, hasSize(1));
@@ -2060,7 +2060,7 @@ public class UserRepositoryTests {
prototype.setCreatedAt(null);
prototype.setManager(manager);
Example<User> example = Example.of(prototype, ExampleSpec.typed(User.class).withIgnorePaths("age"));
Example<User> example = Example.of(prototype, matching().withIgnorePaths("age"));
List<User> users = repository.findAll(example);
assertThat(users, hasSize(1));
@@ -2082,7 +2082,7 @@ public class UserRepositoryTests {
prototype.setCreatedAt(null);
prototype.setAddress(new Address("germany", null, null, null));
Example<User> example = Example.of(prototype, ExampleSpec.typed(User.class).withIgnorePaths("age"));
Example<User> example = Example.of(prototype, matching().withIgnorePaths("age"));
List<User> users = repository.findAll(example);
assertThat(users, hasSize(1));
@@ -2101,7 +2101,7 @@ public class UserRepositoryTests {
prototype.setFirstname("Ol");
Example<User> example = Example.of(prototype,
ExampleSpec.typed(User.class).withStringMatcher(StringMatcher.STARTING).withIgnorePaths("age", "createdAt"));
matching().withStringMatcher(StringMatcher.STARTING).withIgnorePaths("age", "createdAt"));
List<User> users = repository.findAll(example);
assertThat(users, hasSize(1));
@@ -2120,7 +2120,7 @@ public class UserRepositoryTests {
prototype.setFirstname("ver");
Example<User> example = Example.of(prototype,
ExampleSpec.typed(User.class).withStringMatcher(StringMatcher.ENDING).withIgnorePaths("age", "createdAt"));
matching().withStringMatcher(StringMatcher.ENDING).withIgnorePaths("age", "createdAt"));
List<User> users = repository.findAll(example);
assertThat(users, hasSize(1));
@@ -2138,7 +2138,7 @@ public class UserRepositoryTests {
User prototype = new User();
prototype.setFirstname("^Oliver$");
Example<User> example = Example.of(prototype, ExampleSpec.typed(User.class).withStringMatcher(StringMatcher.REGEX));
Example<User> example = Example.of(prototype, matching().withStringMatcher(StringMatcher.REGEX));
repository.findAll(example);
}
@@ -2153,8 +2153,7 @@ public class UserRepositoryTests {
User prototype = new User();
prototype.setFirstname("oLiVer");
Example<User> example = Example.of(prototype,
ExampleSpec.typed(User.class).withIgnoreCase().withIgnorePaths("age", "createdAt"));
Example<User> example = Example.of(prototype, matching().withIgnoreCase().withIgnorePaths("age", "createdAt"));
List<User> users = repository.findAll(example);
@@ -2173,8 +2172,8 @@ public class UserRepositoryTests {
User prototype = new User();
prototype.setFirstname("oLiV");
Example<User> example = Example.of(prototype, ExampleSpec.typed(User.class)
.withStringMatcher(StringMatcher.STARTING).withIgnoreCase().withIgnorePaths("age", "createdAt"));
Example<User> example = Example.of(prototype,
matching().withStringMatcher(StringMatcher.STARTING).withIgnoreCase().withIgnorePaths("age", "createdAt"));
List<User> users = repository.findAll(example);
@@ -2207,8 +2206,8 @@ public class UserRepositoryTests {
User prototype = new User();
prototype.setFirstname(firstUser.getFirstname());
Example<User> example = Example.of(prototype, ExampleSpec.typed(User.class).withIncludeNullValues()
.withIgnorePaths("id", "binaryData", "lastname", "emailAddress", "age", "createdAt"));
Example<User> example = Example.of(prototype, matching().withIncludeNullValues().withIgnorePaths("id", "binaryData",
"lastname", "emailAddress", "age", "createdAt"));
List<User> users = repository.findAll(example);
@@ -2227,8 +2226,8 @@ public class UserRepositoryTests {
User prototype = new User();
prototype.setFirstname("oLi");
Example<User> example = Example.of(prototype, ExampleSpec.typed(User.class).withIgnoreCase()
.withIgnorePaths("age", "createdAt").withMatcher("firstname", new GenericPropertyMatcher().startsWith()));
Example<User> example = Example.of(prototype, matching().withIgnoreCase().withIgnorePaths("age", "createdAt")
.withMatcher("firstname", new GenericPropertyMatcher().startsWith()));
List<User> users = repository.findAll(example);
@@ -2252,8 +2251,8 @@ public class UserRepositoryTests {
User prototype = new User();
prototype.setFirstname("oLi");
Example<User> example = Example.of(prototype, ExampleSpec.typed(User.class).withIgnoreCase()
.withIgnorePaths("age", "createdAt").withStringMatcher(StringMatcher.STARTING).withIgnoreCase());
Example<User> example = Example.of(prototype, matching().withIgnoreCase().withIgnorePaths("age", "createdAt")
.withStringMatcher(StringMatcher.STARTING).withIgnoreCase());
List<User> users = repository.findAll(example, new Sort(DESC, "age"));
@@ -2280,8 +2279,8 @@ public class UserRepositoryTests {
User prototype = new User();
prototype.setFirstname("oLi");
Example<User> example = Example.of(prototype, ExampleSpec.typed(User.class).withIgnoreCase()
.withIgnorePaths("age", "createdAt").withStringMatcher(StringMatcher.STARTING).withIgnoreCase());
Example<User> example = Example.of(prototype, matching().withIgnoreCase().withIgnorePaths("age", "createdAt")
.withStringMatcher(StringMatcher.STARTING).withIgnoreCase());
Page<User> users = repository.findAll(example, new PageRequest(0, 10, new Sort(DESC, "age")));
@@ -2303,8 +2302,8 @@ public class UserRepositoryTests {
user1.setManager(user1);
Example<User> example = Example.of(user1, ExampleSpec.typed(User.class).withIgnoreCase()
.withIgnorePaths("age", "createdAt").withStringMatcher(StringMatcher.STARTING).withIgnoreCase());
Example<User> example = Example.of(user1, matching().withIgnoreCase().withIgnorePaths("age", "createdAt")
.withStringMatcher(StringMatcher.STARTING).withIgnoreCase());
repository.findAll(example, new PageRequest(0, 10, new Sort(DESC, "age")));
}
@@ -2326,8 +2325,8 @@ public class UserRepositoryTests {
user1.setManager(user2);
user2.setManager(user1);
Example<User> example = Example.of(user1, ExampleSpec.typed(User.class).withIgnoreCase()
.withIgnorePaths("age", "createdAt").withStringMatcher(StringMatcher.STARTING).withIgnoreCase());
Example<User> example = Example.of(user1, matching().withIgnoreCase().withIgnorePaths("age", "createdAt")
.withStringMatcher(StringMatcher.STARTING).withIgnoreCase());
repository.findAll(example, new PageRequest(0, 10, new Sort(DESC, "age")));
}
@@ -2343,7 +2342,7 @@ public class UserRepositoryTests {
User prototype = new User();
prototype.setAge(28);
Example<User> example = Example.of(prototype, ExampleSpec.typed(User.class).withIgnorePaths("createdAt"));
Example<User> example = Example.of(prototype, matching().withIgnorePaths("createdAt"));
User users = repository.findOne(example);
assertThat(users, is(firstUser));
@@ -2360,7 +2359,7 @@ public class UserRepositoryTests {
User prototype = new User();
prototype.setAge(28);
Example<User> example = Example.of(prototype, ExampleSpec.typed(User.class).withIgnorePaths("createdAt"));
Example<User> example = Example.of(prototype, matching().withIgnorePaths("createdAt"));
long count = repository.count(example);
assertThat(count, is(1L));
@@ -2377,7 +2376,7 @@ public class UserRepositoryTests {
User prototype = new User();
prototype.setAge(28);
Example<User> example = Example.of(prototype, ExampleSpec.typed(User.class).withIgnorePaths("createdAt"));
Example<User> example = Example.of(prototype, matching().withIgnorePaths("createdAt"));
boolean exists = repository.exists(example);
assertThat(exists, is(true));