diff --git a/persistence-modules/spring-data-jpa-repo-2/pom.xml b/persistence-modules/spring-data-jpa-repo-2/pom.xml index 9240a00ee2..dd0406eca8 100644 --- a/persistence-modules/spring-data-jpa-repo-2/pom.xml +++ b/persistence-modules/spring-data-jpa-repo-2/pom.xml @@ -1,7 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-data-jpa-repo-2 spring-data-jpa-repo-2 @@ -34,6 +34,14 @@ com.h2database h2 + + com.querydsl + querydsl-apt + + + com.querydsl + querydsl-jpa + com.google.guava guava @@ -41,4 +49,53 @@ + + + + com.mysema.maven + apt-maven-plugin + 1.1.3 + + + generate-sources + + process + + + ${project.build.directory}/generated-sources + com.querydsl.apt.jpa.JPAAnnotationProcessor + + + + + + org.bsc.maven + maven-processor-plugin + 3.3.3 + + + process + + process + + generate-sources + + ${project.build.directory}/generated-sources + + org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor + + + + + + + org.hibernate + hibernate-jpamodelgen + 5.6.11.Final + + + + + + \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/springdatajpadifference/model/Employee.java b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/springdatajpadifference/model/Employee.java new file mode 100644 index 0000000000..9690bcf68a --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/springdatajpadifference/model/Employee.java @@ -0,0 +1,76 @@ +package com.baeldung.spring.data.persistence.springdatajpadifference.model; + +import java.io.Serializable; +import java.util.Objects; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.NamedQuery; +import javax.persistence.Table; + +@Entity +@Table(name = "employee") +@NamedQuery(name = "Employee.findById", query = "SELECT e FROM Employee e WHERE e.id = :id") +public class Employee implements Serializable { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + @Column(nullable = false) + private String firstName; + @Column(nullable = false) + private String lastName; + + @Column(nullable = false) + private String email; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + Employee employee = (Employee) o; + return Objects.equals(id, employee.id) && Objects.equals(firstName, employee.firstName) && Objects.equals(lastName, employee.lastName) && Objects.equals(email, employee.email); + } + + @Override + public int hashCode() { + return Objects.hash(id, firstName, lastName, email); + } +} diff --git a/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/springdatajpadifference/springdata/config/SpringDataJpaConfig.java b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/springdatajpadifference/springdata/config/SpringDataJpaConfig.java new file mode 100644 index 0000000000..57f9d2981f --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/springdatajpadifference/springdata/config/SpringDataJpaConfig.java @@ -0,0 +1,66 @@ +package com.baeldung.spring.data.persistence.springdatajpadifference.springdata.config; + +import java.util.Properties; + +import javax.persistence.EntityManager; +import javax.sql.DataSource; + +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.JpaVendorAdapter; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import com.baeldung.spring.data.persistence.springdatajpadifference.springdata.repository.EmployeeRepository; +import com.querydsl.jpa.impl.JPAQueryFactory; + +@Configuration +@EnableTransactionManagement +@EnableJpaRepositories(basePackageClasses = EmployeeRepository.class) +public class SpringDataJpaConfig { + + @Bean + public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) { + LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); + em.setDataSource(dataSource); + em.setPackagesToScan("com.baeldung.spring.data.persistence.springdata_jpa_difference.model"); + + JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); + em.setJpaVendorAdapter(vendorAdapter); + + Properties properties = new Properties(); + properties.setProperty("hibernate.hbm2ddl.auto", "create-drop"); + properties.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect"); + + em.setJpaProperties(properties); + + return em; + } + + @Bean + public PlatformTransactionManager transactionManager(LocalContainerEntityManagerFactoryBean entityManagerFactoryBean) { + JpaTransactionManager transactionManager = new JpaTransactionManager(); + transactionManager.setEntityManagerFactory(entityManagerFactoryBean.getObject()); + return transactionManager; + } + + @Bean + public DataSource dataSource() { + return DataSourceBuilder.create() + .url("jdbc:h2:mem:db;DB_CLOSE_DELAY=-1") + .driverClassName("org.h2.Driver") + .username("sa") + .password("sa") + .build(); + } + + @Bean + public JPAQueryFactory jpaQueryFactory(EntityManager entityManager) { + return new JPAQueryFactory((entityManager)); + } +} diff --git a/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/springdatajpadifference/springdata/repository/EmployeeRepository.java b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/springdatajpadifference/springdata/repository/EmployeeRepository.java new file mode 100644 index 0000000000..012a46d885 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/springdatajpadifference/springdata/repository/EmployeeRepository.java @@ -0,0 +1,19 @@ +package com.baeldung.spring.data.persistence.springdatajpadifference.springdata.repository; + +import java.util.List; + +import org.springframework.data.domain.Sort; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +import com.baeldung.spring.data.persistence.springdatajpadifference.model.Employee; + +@Repository +public interface EmployeeRepository extends JpaRepository { + + List findByFirstName(String firstName); + + @Query(value = "SELECT e FROM Employee e") + List findAllEmployee(Sort sort); +} \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/springdatajpadifference/springdata/repository/EmployeeRepositoryPagingAndSort.java b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/springdatajpadifference/springdata/repository/EmployeeRepositoryPagingAndSort.java new file mode 100644 index 0000000000..731735ea62 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/springdatajpadifference/springdata/repository/EmployeeRepositoryPagingAndSort.java @@ -0,0 +1,11 @@ +package com.baeldung.spring.data.persistence.springdatajpadifference.springdata.repository; + +import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.stereotype.Repository; + +import com.baeldung.spring.data.persistence.springdatajpadifference.model.Employee; + +@Repository +public interface EmployeeRepositoryPagingAndSort extends PagingAndSortingRepository { + +} \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-repo-2/src/test/java/com/baeldung/spring/data/persistence/springdatajpadifference/JpaDaoIntegrationTest.java b/persistence-modules/spring-data-jpa-repo-2/src/test/java/com/baeldung/spring/data/persistence/springdatajpadifference/JpaDaoIntegrationTest.java new file mode 100644 index 0000000000..b25038f175 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-2/src/test/java/com/baeldung/spring/data/persistence/springdatajpadifference/JpaDaoIntegrationTest.java @@ -0,0 +1,201 @@ +package com.baeldung.spring.data.persistence.springdatajpadifference; + +import static com.baeldung.spring.data.persistence.springdatajpadifference.TestUtils.employee; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.util.Arrays; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; +import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.CriteriaUpdate; +import javax.persistence.criteria.Root; + +import org.junit.Before; +import org.junit.Test; + +import com.baeldung.spring.data.persistence.springdatajpadifference.model.Employee; +import com.baeldung.spring.data.persistence.springdatajpadifference.model.Employee_; + +public class JpaDaoIntegrationTest { + + private final EntityManagerFactory emf = Persistence.createEntityManagerFactory("pu-test"); + private final EntityManager entityManager = emf.createEntityManager(); + + @Before + public void setup() { + deleteAllEmployees(); + } + + @Test + public void givenPersistedEmployee_whenFindById_thenEmployeeIsFound() { + Employee employee = employee("John", "Doe"); + save(employee); + + assertEquals(employee, entityManager.find(Employee.class, employee.getId())); + } + + @Test + public void givenPersistedEmployee_whenFindByIdCriteriaQuery_thenEmployeeIsFound() { + Employee employee = employee("John", "Doe"); + save(employee); + + CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); + CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Employee.class); + Root root = criteriaQuery.from(Employee.class); + criteriaQuery.select(root); + + criteriaQuery.where(criteriaBuilder.equal(root.get(Employee_.ID), employee.getId())); + + assertEquals(employee, entityManager.createQuery(criteriaQuery) + .getSingleResult()); + } + + @Test + public void givenPersistedEmployee_whenFindByIdJpql_thenEmployeeIsFound() { + Employee employee = employee("John", "Doe"); + save(employee); + + Query jpqlQuery = entityManager.createQuery("SELECT e from Employee e WHERE e.id=:id"); + jpqlQuery.setParameter("id", employee.getId()); + + assertEquals(employee, jpqlQuery.getSingleResult()); + } + + @Test + public void givenPersistedEmployee_whenFindByIdNamedQuery_thenEmployeeIsFound() { + Employee employee = employee("John", "Doe"); + save(employee); + + Query query = entityManager.createNamedQuery("Employee.findById"); + + query.setParameter(Employee_.ID, employee.getId()); + + assertEquals(employee, query.getSingleResult()); + } + + @Test + public void givenPersistedEmployee_whenFindWithPaginationAndSort_thenEmployeesAreFound() { + Employee john = employee("John", "Doe"); + Employee bob = employee("Bob", "Smith"); + Employee frank = employee("Frank", "Brown"); + Employee james = employee("James", "Smith"); + save(john); + save(bob); + save(frank); + save(james); + + CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); + CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Employee.class); + Root root = criteriaQuery.from(Employee.class); + criteriaQuery.select(root); + criteriaQuery.orderBy(criteriaBuilder.asc(root.get(Employee_.FIRST_NAME))); + + TypedQuery query = entityManager.createQuery(criteriaQuery); + + query.setFirstResult(0); + query.setMaxResults(3); + + List employeeList = query.getResultList(); + + assertEquals(Arrays.asList(bob, frank, james), employeeList); + } + + @Test + public void givenPersistedEmployee_whenUpdateEmployeeEmail_thenEmployeeHasUpdatedEmail() { + Employee employee = employee("John", "Doe"); + save(employee); + + Employee employeeToUpdate = entityManager.find(Employee.class, employee.getId()); + + String updatedEmail = "email@gmail.com"; + + employeeToUpdate.setEmail(updatedEmail); + + update(employeeToUpdate); + + assertEquals(updatedEmail, entityManager.find(Employee.class, employee.getId()) + .getEmail()); + } + + @Test + public void givenPersistedEmployee_whenUpdateEmployeeEmailWithCriteria_thenEmployeeHasUpdatedEmail() { + Employee employee = employee("John", "Doe"); + save(employee); + + String updatedEmail = "email@gmail.com"; + + CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); + CriteriaUpdate criteriaUpdate = criteriaBuilder.createCriteriaUpdate(Employee.class); + Root root = criteriaUpdate.from(Employee.class); + + criteriaUpdate.set(Employee_.EMAIL, updatedEmail); + criteriaUpdate.where(criteriaBuilder.equal(root.get(Employee_.ID), employee.getId())); + + assertEquals(1, update(criteriaUpdate)); + + assertEquals(updatedEmail, entityManager.find(Employee.class, employee.getId()) + .getEmail()); + } + + @Test + public void givenPersistedEmployee_whenRemoveEmployee_thenNoEmployeeIsFound() { + Employee employee = employee("John", "Doe"); + save(employee); + + delete(employee.getId()); + + assertNull(entityManager.find(Employee.class, employee.getId())); + } + + private void deleteAllEmployees() { + entityManager.getTransaction() + .begin(); + entityManager.createNativeQuery("DELETE from Employee") + .executeUpdate(); + entityManager.getTransaction() + .commit(); + } + + public void save(Employee entity) { + entityManager.getTransaction() + .begin(); + entityManager.persist(entity); + entityManager.getTransaction() + .commit(); + } + + public void update(Employee entity) { + entityManager.getTransaction() + .begin(); + entityManager.merge(entity); + entityManager.getTransaction() + .commit(); + } + + public void delete(Long employee) { + entityManager.getTransaction() + .begin(); + entityManager.remove(entityManager.find(Employee.class, employee)); + entityManager.getTransaction() + .commit(); + } + + public int update(CriteriaUpdate criteriaUpdate) { + entityManager.getTransaction() + .begin(); + int result = entityManager.createQuery(criteriaUpdate) + .executeUpdate(); + entityManager.getTransaction() + .commit(); + entityManager.clear(); + + return result; + } +} diff --git a/persistence-modules/spring-data-jpa-repo-2/src/test/java/com/baeldung/spring/data/persistence/springdatajpadifference/SpringDataJpaIntegrationTest.java b/persistence-modules/spring-data-jpa-repo-2/src/test/java/com/baeldung/spring/data/persistence/springdatajpadifference/SpringDataJpaIntegrationTest.java new file mode 100644 index 0000000000..e6febdc9f1 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-2/src/test/java/com/baeldung/spring/data/persistence/springdatajpadifference/SpringDataJpaIntegrationTest.java @@ -0,0 +1,153 @@ +package com.baeldung.spring.data.persistence.springdatajpadifference; + +import static com.baeldung.spring.data.persistence.springdatajpadifference.TestUtils.employee; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + +import com.baeldung.spring.data.persistence.springdatajpadifference.model.Employee; +import com.baeldung.spring.data.persistence.springdatajpadifference.model.QEmployee; +import com.baeldung.spring.data.persistence.springdatajpadifference.springdata.config.SpringDataJpaConfig; +import com.baeldung.spring.data.persistence.springdatajpadifference.springdata.repository.EmployeeRepository; +import com.baeldung.spring.data.persistence.springdatajpadifference.springdata.repository.EmployeeRepositoryPagingAndSort; +import com.querydsl.jpa.impl.JPAQueryFactory; + +@ContextConfiguration(classes = SpringDataJpaConfig.class) +@RunWith(SpringJUnit4ClassRunner.class) +@Transactional +@Rollback +public class SpringDataJpaIntegrationTest { + + @Autowired + private EmployeeRepository employeeRepository; + + @Autowired + private EmployeeRepositoryPagingAndSort employeeRepositoryPagingAndSort; + + @Autowired + private JPAQueryFactory jpaQueryFactory; + + @Test + public void givenPersistedEmployee_whenFindById_thenEmployeeIsFound() { + Employee employee = employee("John", "Doe"); + + employeeRepository.save(employee); + + assertEquals(Optional.of(employee), employeeRepository.findById(employee.getId())); + } + + @Test + public void givenPersistedEmployee_whenFindByFirstName_thenEmployeeIsFound() { + Employee employee = employee("John", "Doe"); + + employeeRepository.save(employee); + + assertEquals(employee, employeeRepository.findByFirstName(employee.getFirstName()) + .get(0)); + } + + @Test + public void givenPersistedEmployee_whenUpdateEmployeeEmail_thenEmployeeHasUpdatedEmail() { + Employee employee = employee("John", "Doe"); + + employeeRepository.save(employee); + + Employee employeeToUpdate = employeeRepository.findById(employee.getId()) + .orElse(null); + + assertNotNull(employeeToUpdate); + assertEquals(employee, employeeToUpdate); + + String updatedEmail = "email@gmail.com"; + + employeeToUpdate.setEmail(updatedEmail); + + employeeRepository.save(employeeToUpdate); + + assertEquals(Optional.of(employeeToUpdate), employeeRepository.findById(employee.getId())); + } + + @Test + public void givenPersistedEmployee_whenRemoveEmployee_thenNoEmployeeIsFound() { + Employee employee = employee("John", "Doe"); + + employeeRepository.save(employee); + + Employee persistedEmployee = employeeRepository.findById(employee.getId()) + .orElse(null); + + assertNotNull(persistedEmployee); + + employeeRepository.delete(persistedEmployee); + + assertFalse(employeeRepository.findById(employee.getId()) + .isPresent()); + } + + @Test + public void givenPersistedEmployees_whenFindSortedByFirstName_thenEmployeeAreFoundInOrder() { + Employee john = employee("John", "Doe"); + Employee bob = employee("Bob", "Smith"); + Employee frank = employee("Frank", "Brown"); + + employeeRepository.saveAll(Arrays.asList(john, bob, frank)); + + List employees = employeeRepository.findAllEmployee(Sort.by("firstName")); + + assertEquals(3, employees.size()); + assertEquals(bob, employees.get(0)); + assertEquals(frank, employees.get(1)); + assertEquals(john, employees.get(2)); + } + + @Test + public void givenPersistedEmployee_whenFindByQueryDsl_thenEmployeeIsFound() { + Employee john = employee("John", "Doe"); + Employee frank = employee("Frank", "Doe"); + + employeeRepository.saveAll(Arrays.asList(john, frank)); + + QEmployee employeePath = QEmployee.employee; + + List employees = jpaQueryFactory.selectFrom(employeePath) + .where(employeePath.firstName.eq("John"), employeePath.lastName.eq("Doe")) + .fetch(); + + assertEquals(1, employees.size()); + assertEquals(john, employees.get(0)); + } + + @Test + public void givenPersistedEmployee_whenFindBySortAndPagingRepository_thenEmployeeAreFound() { + Employee john = employee("John", "Doe"); + Employee bob = employee("Bob", "Smith"); + Employee frank = employee("Frank", "Brown"); + Employee jimmy = employee("Jimmy", "Armstrong"); + + employeeRepositoryPagingAndSort.saveAll(Arrays.asList(john, bob, frank, jimmy)); + + Pageable pageable = PageRequest.of(0, 2, Sort.by("firstName")); + + Page employees = employeeRepositoryPagingAndSort.findAll(pageable); + + assertEquals(Arrays.asList(bob, frank), employees.get() + .collect(Collectors.toList())); + } +} diff --git a/persistence-modules/spring-data-jpa-repo-2/src/test/java/com/baeldung/spring/data/persistence/springdatajpadifference/TestUtils.java b/persistence-modules/spring-data-jpa-repo-2/src/test/java/com/baeldung/spring/data/persistence/springdatajpadifference/TestUtils.java new file mode 100644 index 0000000000..989a7db247 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-2/src/test/java/com/baeldung/spring/data/persistence/springdatajpadifference/TestUtils.java @@ -0,0 +1,15 @@ +package com.baeldung.spring.data.persistence.springdatajpadifference; + +import com.baeldung.spring.data.persistence.springdatajpadifference.model.Employee; + +public class TestUtils { + + public static Employee employee(String firstName, String lastname) { + Employee employee = new Employee(); + employee.setFirstName(firstName); + employee.setLastName(lastname); + employee.setEmail(firstName + lastname + "@baeldung.com"); + + return employee; + } +} diff --git a/persistence-modules/spring-data-jpa-repo-2/src/test/resources/META-INF/persistence.xml b/persistence-modules/spring-data-jpa-repo-2/src/test/resources/META-INF/persistence.xml new file mode 100644 index 0000000000..94df50cf0a --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-2/src/test/resources/META-INF/persistence.xml @@ -0,0 +1,21 @@ + + + + org.hibernate.jpa.HibernatePersistenceProvider + com.baeldung.spring.data.persistence.springdatajpadifference.model.Employee + + + + + + + + + + + +