From fb210d0499052a5b18cfffa042e714b1d00227c9 Mon Sep 17 00:00:00 2001 From: FrancoCorleone Date: Tue, 18 Dec 2018 02:56:30 +0100 Subject: [PATCH] BAEL-2090 Insert With JPA * Adding inserts for JPA objects repositories * Refactor tests * Small refactor * Small refactor * Remove redundant @Repository annotation * Refactor tests * Change to simple entity manager implementation * Refactor changes --- .../dao/repositories/InsertRepository.java | 5 + .../PersonEntityManagerInsertRepository.java | 7 ++ .../PersonEntityManagerRepository.java | 10 ++ .../PersonQueryInsertRepository.java | 7 ++ .../repositories/PersonQueryRepository.java | 16 +++ ...rsonEntityManagerInsertRepositoryImpl.java | 21 ++++ .../impl/PersonQueryInsertRepositoryImpl.java | 24 +++++ .../main/java/com/baeldung/domain/Person.java | 47 ++++++++ ...PersonInsertRepositoryIntegrationTest.java | 102 ++++++++++++++++++ 9 files changed, 239 insertions(+) create mode 100644 persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/InsertRepository.java create mode 100644 persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/PersonEntityManagerInsertRepository.java create mode 100644 persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/PersonEntityManagerRepository.java create mode 100644 persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/PersonQueryInsertRepository.java create mode 100644 persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/PersonQueryRepository.java create mode 100644 persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/impl/PersonEntityManagerInsertRepositoryImpl.java create mode 100644 persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/impl/PersonQueryInsertRepositoryImpl.java create mode 100644 persistence-modules/spring-data-jpa/src/main/java/com/baeldung/domain/Person.java create mode 100644 persistence-modules/spring-data-jpa/src/test/java/com/baeldung/dao/repositories/PersonInsertRepositoryIntegrationTest.java diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/InsertRepository.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/InsertRepository.java new file mode 100644 index 0000000000..6a74e067fe --- /dev/null +++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/InsertRepository.java @@ -0,0 +1,5 @@ +package com.baeldung.dao.repositories; + +public interface InsertRepository { + void insert(S entity); +} diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/PersonEntityManagerInsertRepository.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/PersonEntityManagerInsertRepository.java new file mode 100644 index 0000000000..6d3cbb07df --- /dev/null +++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/PersonEntityManagerInsertRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.dao.repositories; + +import com.baeldung.domain.Person; + +public interface PersonEntityManagerInsertRepository { + void insert(Person person); +} diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/PersonEntityManagerRepository.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/PersonEntityManagerRepository.java new file mode 100644 index 0000000000..cbf3d59620 --- /dev/null +++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/PersonEntityManagerRepository.java @@ -0,0 +1,10 @@ +package com.baeldung.dao.repositories; + +import com.baeldung.domain.Person; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface PersonEntityManagerRepository extends JpaRepository, PersonEntityManagerInsertRepository { + +} diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/PersonQueryInsertRepository.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/PersonQueryInsertRepository.java new file mode 100644 index 0000000000..be01e9883a --- /dev/null +++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/PersonQueryInsertRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.dao.repositories; + +import com.baeldung.domain.Person; + +public interface PersonQueryInsertRepository { + void insert(Person person); +} diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/PersonQueryRepository.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/PersonQueryRepository.java new file mode 100644 index 0000000000..1516c38443 --- /dev/null +++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/PersonQueryRepository.java @@ -0,0 +1,16 @@ +package com.baeldung.dao.repositories; + +import com.baeldung.domain.Person; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +@Repository +public interface PersonQueryRepository extends JpaRepository, PersonQueryInsertRepository { + + @Modifying + @Query(value = "INSERT INTO person (id, first_name, last_name) VALUES (:id,:firstName,:lastName)", nativeQuery = true) + void insertWithAnnotation(@Param("id") Long id, @Param("firstName") String firstName, @Param("lastName") String lastName); +} diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/impl/PersonEntityManagerInsertRepositoryImpl.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/impl/PersonEntityManagerInsertRepositoryImpl.java new file mode 100644 index 0000000000..c14cc44125 --- /dev/null +++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/impl/PersonEntityManagerInsertRepositoryImpl.java @@ -0,0 +1,21 @@ +package com.baeldung.dao.repositories.impl; + +import com.baeldung.dao.repositories.PersonEntityManagerInsertRepository; +import com.baeldung.domain.Person; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; + +@Transactional +public class PersonEntityManagerInsertRepositoryImpl implements PersonEntityManagerInsertRepository { + + @PersistenceContext + private EntityManager entityManager; + + @Override + public void insert(Person person) { + this.entityManager.persist(person); + } +} + diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/impl/PersonQueryInsertRepositoryImpl.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/impl/PersonQueryInsertRepositoryImpl.java new file mode 100644 index 0000000000..341db1615d --- /dev/null +++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/impl/PersonQueryInsertRepositoryImpl.java @@ -0,0 +1,24 @@ +package com.baeldung.dao.repositories.impl; + +import com.baeldung.dao.repositories.PersonQueryInsertRepository; +import com.baeldung.domain.Person; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.transaction.Transactional; + +@Transactional +public class PersonQueryInsertRepositoryImpl implements PersonQueryInsertRepository { + + @PersistenceContext + private EntityManager entityManager; + + @Override + public void insert(Person person) { + entityManager.createNativeQuery("INSERT INTO person (id,first_name, last_name) VALUES (?,?,?)") + .setParameter(1, person.getId()) + .setParameter(2, person.getFirstName()) + .setParameter(3, person.getLastName()) + .executeUpdate(); + } +} diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/domain/Person.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/domain/Person.java new file mode 100644 index 0000000000..30d7370982 --- /dev/null +++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/domain/Person.java @@ -0,0 +1,47 @@ +package com.baeldung.domain; + +import javax.persistence.Entity; +import javax.persistence.Id; + +@Entity +public class Person { + + @Id + private Long id; + private String firstName; + private String lastName; + + public Person() { + } + + public Person(Long id, String firstName, String lastName) { + this.id = id; + this.firstName = firstName; + this.lastName = lastName; + } + + 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; + } + +} diff --git a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/dao/repositories/PersonInsertRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/dao/repositories/PersonInsertRepositoryIntegrationTest.java new file mode 100644 index 0000000000..476554f6d6 --- /dev/null +++ b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/dao/repositories/PersonInsertRepositoryIntegrationTest.java @@ -0,0 +1,102 @@ +package com.baeldung.dao.repositories; + +import com.baeldung.domain.Person; +import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.test.context.junit4.SpringRunner; + +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +@RunWith(SpringRunner.class) +@DataJpaTest +public class PersonInsertRepositoryIntegrationTest { + + private static final Long ID = 1L; + private static final String FIRST_NAME = "firstname"; + private static final String LAST_NAME = "lastname"; + private static final Person PERSON = new Person(ID, FIRST_NAME, LAST_NAME); + + @Autowired + private PersonQueryRepository personQueryRepository; + + @Autowired + private PersonEntityManagerRepository personEntityManagerRepository; + + @BeforeEach + public void clearDB() { + personQueryRepository.deleteAll(); + } + + @Test + public void givenPersonEntity_whenInsertWithNativeQuery_ThenPersonIsPersisted() { + insertPerson(); + + assertPersonPersisted(); + } + + @Test + public void givenPersonEntity_whenInsertedTwiceWithNativeQuery_thenDataIntegrityViolationExceptionIsThrown() { + assertThatExceptionOfType(DataIntegrityViolationException.class).isThrownBy(() -> { + insertPerson(); + insertPerson(); + }); + } + + @Test + public void givenPersonEntity_whenInsertWithQueryAnnotation_thenPersonIsPersisted() { + insertPersonWithQueryAnnotation(); + + assertPersonPersisted(); + } + + @Test + public void givenPersonEntity_whenInsertedTwiceWithQueryAnnotation_thenDataIntegrityViolationExceptionIsThrown() { + assertThatExceptionOfType(DataIntegrityViolationException.class).isThrownBy(() -> { + insertPersonWithQueryAnnotation(); + insertPersonWithQueryAnnotation(); + }); + } + + @Test + public void givenPersonEntity_whenInsertWithEntityManager_thenPersonIsPersisted() { + insertPersonWithEntityManager(); + + assertPersonPersisted(); + } + + @Test + public void givenPersonEntity_whenInsertedTwiceWithEntityManager_thenDataIntegrityViolationExceptionIsThrown() { + assertThatExceptionOfType(DataIntegrityViolationException.class).isThrownBy(() -> { + insertPersonWithEntityManager(); + insertPersonWithEntityManager(); + }); + } + + private void insertPerson() { + personQueryRepository.insert(PERSON); + } + + private void insertPersonWithQueryAnnotation() { + personQueryRepository.insertWithAnnotation(ID, FIRST_NAME, LAST_NAME); + } + + private void insertPersonWithEntityManager() { + personEntityManagerRepository.insert(new Person(ID, FIRST_NAME, LAST_NAME)); + } + + private void assertPersonPersisted() { + Optional personOptional = personQueryRepository.findById(PERSON.getId()); + + assertThat(personOptional.isPresent()).isTrue(); + assertThat(personOptional.get().getId()).isEqualTo(PERSON.getId()); + assertThat(personOptional.get().getFirstName()).isEqualTo(PERSON.getFirstName()); + assertThat(personOptional.get().getLastName()).isEqualTo(PERSON.getLastName()); + } +}