diff --git a/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfig.java b/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfig.java index 76fc96b3ce..c9358190e7 100644 --- a/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfig.java +++ b/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfig.java @@ -12,6 +12,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; @@ -25,6 +26,7 @@ import com.google.common.base.Preconditions; @EnableTransactionManagement @PropertySource({ "classpath:persistence-mysql.properties" }) @ComponentScan({ "org.baeldung.persistence" }) +@EnableJpaRepositories(basePackages = "org.baeldung.persistence.dao") public class PersistenceJPAConfig { @Autowired diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/dao/UserRepository.java b/spring-jpa/src/main/java/org/baeldung/persistence/dao/UserRepository.java new file mode 100644 index 0000000000..de7acf60d5 --- /dev/null +++ b/spring-jpa/src/main/java/org/baeldung/persistence/dao/UserRepository.java @@ -0,0 +1,9 @@ +package org.baeldung.persistence.dao; + +import org.baeldung.persistence.model.User; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +public interface UserRepository extends JpaRepository, JpaSpecificationExecutor { + +} diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/dao/UserSpecifications.java b/spring-jpa/src/main/java/org/baeldung/persistence/dao/UserSpecifications.java new file mode 100644 index 0000000000..a0f545b158 --- /dev/null +++ b/spring-jpa/src/main/java/org/baeldung/persistence/dao/UserSpecifications.java @@ -0,0 +1,45 @@ +package org.baeldung.persistence.dao; + +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; + +import org.baeldung.persistence.model.User; +import org.baeldung.persistence.model.User_; +import org.springframework.data.jpa.domain.Specification; + +public class UserSpecifications { + public static Specification firstNameIsLike(final String term) { + + return new Specification() { + @Override + public Predicate toPredicate(final Root root, final CriteriaQuery query, final CriteriaBuilder cb) { + return cb.like(root.get(User_.firstName), "%"+term+"%"); + } + + }; + } + + public static Specification lastNameIsLike(final String term) { + + return new Specification() { + @Override + public Predicate toPredicate(final Root root, final CriteriaQuery query, final CriteriaBuilder cb) { + return cb.like(root.get(User_.lastName), "%" + term + "%"); + } + + }; + } + + public static Specification ageIsGreaterThan(final int minAge) { + + return new Specification() { + @Override + public Predicate toPredicate(final Root root, final CriteriaQuery query, final CriteriaBuilder cb) { + return cb.greaterThanOrEqualTo(root.get(User_.age), minAge); + } + + }; + } +} diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/model/User_.java b/spring-jpa/src/main/java/org/baeldung/persistence/model/User_.java new file mode 100644 index 0000000000..c7b6ba2de8 --- /dev/null +++ b/spring-jpa/src/main/java/org/baeldung/persistence/model/User_.java @@ -0,0 +1,11 @@ +package org.baeldung.persistence.model; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +@StaticMetamodel(User.class) +public class User_ { + public static volatile SingularAttribute firstName; + public static volatile SingularAttribute lastName; + public static volatile SingularAttribute age; +} \ No newline at end of file diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/query/JPACriteriaQueryTest.java b/spring-jpa/src/test/java/org/baeldung/persistence/query/JPACriteriaQueryTest.java index 5d76a7ce5c..7482f296b5 100644 --- a/spring-jpa/src/test/java/org/baeldung/persistence/query/JPACriteriaQueryTest.java +++ b/spring-jpa/src/test/java/org/baeldung/persistence/query/JPACriteriaQueryTest.java @@ -26,25 +26,25 @@ public class JPACriteriaQueryTest { @Autowired private UserService userService; - private User user_john; + private User userJohn; - private User user_tom; + private User userTom; @Before public void init() { - user_john = new User(); - user_john.setFirstName("John"); - user_john.setLastName("Doe"); - user_john.setEmail("john@doe.com"); - user_john.setAge(22); - userService.saveUser(user_john); + userJohn = new User(); + userJohn.setFirstName("John"); + userJohn.setLastName("Doe"); + userJohn.setEmail("john@doe.com"); + userJohn.setAge(22); + userService.saveUser(userJohn); - user_tom = new User(); - user_tom.setFirstName("Tom"); - user_tom.setLastName("Doe"); - user_tom.setEmail("tom@doe.com"); - user_tom.setAge(26); - userService.saveUser(user_tom); + userTom = new User(); + userTom.setFirstName("Tom"); + userTom.setLastName("Doe"); + userTom.setEmail("tom@doe.com"); + userTom.setAge(26); + userService.saveUser(userTom); } @Test @@ -52,7 +52,7 @@ public class JPACriteriaQueryTest { final List result = userService.searchUser("John", "Doe", 0); assertEquals(1, result.size()); - assertEquals(user_john.getEmail(), result.get(0).getEmail()); + assertEquals(userJohn.getEmail(), result.get(0).getEmail()); } @Test @@ -66,7 +66,7 @@ public class JPACriteriaQueryTest { final List result = userService.searchUser("", "doe", 25); assertEquals(1, result.size()); - assertEquals(user_tom.getEmail(), result.get(0).getEmail()); + assertEquals(userTom.getEmail(), result.get(0).getEmail()); } @Test @@ -76,10 +76,10 @@ public class JPACriteriaQueryTest { } @Test - public void givenPartialFirstAndLast_whenGettingListOfUsers_thenCorrect() { + public void givenPartialFirst_whenGettingListOfUsers_thenCorrect() { final List result = userService.searchUser("jo", "", 0); assertEquals(1, result.size()); - assertEquals(user_john.getEmail(), result.get(0).getEmail()); + assertEquals(userJohn.getEmail(), result.get(0).getEmail()); } } diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/query/JPASpecificationsTest.java b/spring-jpa/src/test/java/org/baeldung/persistence/query/JPASpecificationsTest.java new file mode 100644 index 0000000000..374afc1ef7 --- /dev/null +++ b/spring-jpa/src/test/java/org/baeldung/persistence/query/JPASpecificationsTest.java @@ -0,0 +1,89 @@ +package org.baeldung.persistence.query; + +import static org.baeldung.persistence.dao.UserSpecifications.ageIsGreaterThan; +import static org.baeldung.persistence.dao.UserSpecifications.firstNameIsLike; +import static org.baeldung.persistence.dao.UserSpecifications.lastNameIsLike; +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.baeldung.config.PersistenceJPAConfig; +import org.baeldung.persistence.dao.UserRepository; +import org.baeldung.persistence.model.User; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.jpa.domain.Specifications; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; +import org.springframework.test.context.transaction.TransactionConfiguration; +import org.springframework.transaction.annotation.Transactional; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { PersistenceJPAConfig.class }, loader = AnnotationConfigContextLoader.class) +@Transactional +@TransactionConfiguration +public class JPASpecificationsTest { + + @Autowired + private UserRepository repository; + + private User userJohn; + + private User userTom; + + @Before + public void init() { + userJohn = new User(); + userJohn.setFirstName("John"); + userJohn.setLastName("Doe"); + userJohn.setEmail("john@doe.com"); + userJohn.setAge(22); + repository.save(userJohn); + + userTom = new User(); + userTom.setFirstName("Tom"); + userTom.setLastName("Doe"); + userTom.setEmail("tom@doe.com"); + userTom.setAge(26); + repository.save(userTom); + } + + @Test + public void givenLast_whenGettingListOfUsers_thenCorrect() { + final List result = repository.findAll(lastNameIsLike("doe")); + assertEquals(2, result.size()); + } + + @Test + public void givenFirstAndLastName_whenGettingListOfUsers_thenCorrect() { + final List result = repository.findAll(Specifications.where(lastNameIsLike("doe")).and(firstNameIsLike("john"))); + + assertEquals(1, result.size()); + assertEquals(userJohn.getEmail(), result.get(0).getEmail()); + } + + @Test + public void givenLastAndAge_whenGettingListOfUsers_thenCorrect() { + final List result = repository.findAll(Specifications.where(lastNameIsLike("doe")).and(ageIsGreaterThan(25))); + + assertEquals(1, result.size()); + assertEquals(userTom.getEmail(), result.get(0).getEmail()); + } + + @Test + public void givenWrongFirstAndLast_whenGettingListOfUsers_thenCorrect() { + final List result = repository.findAll(Specifications.where(lastNameIsLike("Adam")).and(firstNameIsLike("Fox"))); + assertEquals(0, result.size()); + } + + @Test + public void givenPartialFirst_whenGettingListOfUsers_thenCorrect() { + final List result = repository.findAll(firstNameIsLike("jo")); + + assertEquals(1, result.size()); + assertEquals(userJohn.getEmail(), result.get(0).getEmail()); + } +}