diff --git a/src/main/java/org/springframework/data/jpa/domain/Specifications.java b/src/main/java/org/springframework/data/jpa/domain/Specifications.java index 8d1ab2485..4dce73921 100644 --- a/src/main/java/org/springframework/data/jpa/domain/Specifications.java +++ b/src/main/java/org/springframework/data/jpa/domain/Specifications.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2011 the original author or authors. + * Copyright 2008-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,8 @@ import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; +import org.springframework.util.Assert; + /** * Helper class to easily combine {@link Specification} instances. * @@ -27,15 +29,16 @@ import javax.persistence.criteria.Root; */ public class Specifications implements Specification { + private static final String NOT_NULL = "Specification given to %s(…) must not be null!"; + private final Specification spec; /** * Creates a new {@link Specifications} wrapper for the given {@link Specification}. * - * @param spec + * @param spec must not be {@literal null}. */ private Specifications(Specification spec) { - this.spec = spec; } @@ -43,26 +46,28 @@ public class Specifications implements Specification { * Simple static factory method to add some syntactic sugar around a {@link Specification}. * * @param - * @param spec + * @param spec must not be {@literal null}. * @return */ public static Specifications where(Specification spec) { + Assert.notNull(spec, String.format(NOT_NULL, "where")); return new Specifications(spec); } /** * ANDs the given {@link Specification} to the current one. * - * @param other + * @param + * @param other must not be {@literal null}. * @return */ public Specifications and(final Specification other) { + Assert.notNull(spec, String.format(NOT_NULL, "and")); + return new Specifications(new Specification() { - public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder builder) { - return builder.and(spec.toPredicate(root, query, builder), other.toPredicate(root, query, builder)); } }); @@ -71,15 +76,16 @@ public class Specifications implements Specification { /** * ORs the given specification to the current one. * - * @param other + * @param + * @param other must not be {@literal null}. * @return */ public Specifications or(final Specification other) { + Assert.notNull(spec, String.format(NOT_NULL, "or")); + return new Specifications(new Specification() { - public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder builder) { - return builder.or(spec.toPredicate(root, query, builder), other.toPredicate(root, query, builder)); } }); @@ -89,30 +95,25 @@ public class Specifications implements Specification { * Negates the given {@link Specification}. * * @param - * @param spec + * @param spec must not be {@literal null}. * @return */ public static Specifications not(final Specification spec) { - return new Specifications(spec) { + Assert.notNull(spec, String.format(NOT_NULL, "not")); - @Override + return new Specifications(new Specification() { public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder builder) { - return builder.not(spec.toPredicate(root, query, builder)); } - }; + }); } /* * (non-Javadoc) - * - * @see org.springframework.data.jpa.domain.Specification#toPredicate(javax. - * persistence.criteria.Root, javax.persistence.criteria.CriteriaQuery, - * javax.persistence.criteria.CriteriaBuilder) + * @see org.springframework.data.jpa.domain.Specification#toPredicate(javax.persistence.criteria.Root, javax.persistence.criteria.CriteriaQuery, javax.persistence.criteria.CriteriaBuilder) */ public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder builder) { - return spec.toPredicate(root, query, builder); } } diff --git a/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java b/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java index 90571a87e..7221c8e6c 100644 --- a/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java @@ -443,7 +443,21 @@ public class UserRepositoryTests { flushTestUsers(); Specification spec = where(userHasFirstname("Oliver")).or(userHasLastname("Arrasz")); - assertThat(repository.findAll(spec).size(), is(2)); + assertThat(repository.findAll(spec), hasSize(2)); + } + + /** + * @see DATAJPA-253 + */ + @Test + public void executesNegatingSpecificationCorrectly() { + + flushTestUsers(); + Specification spec = not(userHasFirstname("Oliver")).and(userHasLastname("Arrasz")); + List result = repository.findAll(spec); + + assertThat(result, hasSize(1)); + assertThat(result, hasItem(secondUser)); } @Test