diff --git a/persistence-modules/spring-data-jpa-5/pom.xml b/persistence-modules/spring-data-jpa-5/pom.xml
index 3053384559..6a5cdc86c2 100644
--- a/persistence-modules/spring-data-jpa-5/pom.xml
+++ b/persistence-modules/spring-data-jpa-5/pom.xml
@@ -1,6 +1,7 @@
+
4.0.0
spring-data-jpa-5
spring-data-jpa-5
@@ -11,7 +12,7 @@
0.0.1-SNAPSHOT
../../parent-boot-2
-
+
org.springframework.boot
@@ -28,10 +29,43 @@
spring-boot-starter-data-jdbc
+
+ org.springframework.boot
+ spring-boot-starter-cache
+
+
com.h2database
h2
+
+
+ org.mapstruct
+ mapstruct-jdk8
+ 1.3.1.Final
+ provided
+
+
-
+
+ src/main/java
+
+
+ maven-compiler-plugin
+ 3.8.1
+
+
+ 1.8
+
+
+ org.mapstruct
+ mapstruct-processor
+ 1.3.1.Final
+
+
+
+
+
+
+
diff --git a/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/PartialUpdateApplication.java b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/PartialUpdateApplication.java
new file mode 100644
index 0000000000..a750fcadf7
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/PartialUpdateApplication.java
@@ -0,0 +1,12 @@
+package com.baeldung.partialupdate;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class PartialUpdateApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(PartialUpdateApplication.class, args);
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/model/ContactPhone.java b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/model/ContactPhone.java
new file mode 100644
index 0000000000..352e361bd9
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/model/ContactPhone.java
@@ -0,0 +1,22 @@
+package com.baeldung.partialupdate.model;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Entity
+public class ContactPhone {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ public long id;
+ @Column(nullable=false)
+ public long customerId;
+ public String phone;
+
+ @Override
+ public String toString() {
+ return phone;
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/model/Customer.java b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/model/Customer.java
new file mode 100644
index 0000000000..b19d0b7952
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/model/Customer.java
@@ -0,0 +1,23 @@
+package com.baeldung.partialupdate.model;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Entity
+public class Customer {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ public long id;
+ public String name;
+ public String phone;
+ //...
+ public String phone99;
+
+ @Override public String toString() {
+ return String.format("Customer %s, Phone: %s",
+ this.name, this.phone);
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/model/CustomerDto.java b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/model/CustomerDto.java
new file mode 100644
index 0000000000..0ecf206d9a
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/model/CustomerDto.java
@@ -0,0 +1,31 @@
+package com.baeldung.partialupdate.model;
+
+public class CustomerDto {
+ private long id;
+ public String name;
+ public String phone;
+ //...
+ private String phone99;
+
+ public CustomerDto(long id) {
+ this.id = id;
+ }
+
+ public CustomerDto(Customer c) {
+ this.id = c.id;
+ this.name = c.name;
+ this.phone = c.phone;
+ }
+
+ public long getId() {
+ return this.id;
+ }
+
+ public Customer convertToEntity() {
+ Customer c = new Customer();
+ c.id = id;
+ c.name = name;
+ c.phone = phone;
+ return c;
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/model/CustomerStructured.java b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/model/CustomerStructured.java
new file mode 100644
index 0000000000..dd053a963d
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/model/CustomerStructured.java
@@ -0,0 +1,27 @@
+package com.baeldung.partialupdate.model;
+
+import java.util.List;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+
+@Entity
+public class CustomerStructured {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ public long id;
+ public String name;
+ @OneToMany(fetch = FetchType.EAGER, targetEntity = ContactPhone.class, mappedBy = "customerId")
+ public List contactPhones;
+
+ @Override public String toString() {
+ return String.format("Customer %s, Phone: %s",
+ this.name, this.contactPhones.stream()
+ .map(e -> e.toString()).reduce("", String::concat));
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/repository/ContactPhoneRepository.java b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/repository/ContactPhoneRepository.java
new file mode 100644
index 0000000000..4668181e05
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/repository/ContactPhoneRepository.java
@@ -0,0 +1,12 @@
+package com.baeldung.partialupdate.repository;
+
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.stereotype.Repository;
+
+import com.baeldung.partialupdate.model.ContactPhone;
+
+@Repository
+public interface ContactPhoneRepository extends CrudRepository {
+ ContactPhone findById(long id);
+ ContactPhone findByCustomerId(long id);
+}
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/repository/CustomerRepository.java b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/repository/CustomerRepository.java
new file mode 100644
index 0000000000..43e61df8ab
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/repository/CustomerRepository.java
@@ -0,0 +1,18 @@
+package com.baeldung.partialupdate.repository;
+
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+
+import com.baeldung.partialupdate.model.Customer;
+
+@Repository
+public interface CustomerRepository extends CrudRepository {
+ Customer findById(long id);
+
+ @Modifying
+ @Query("update Customer u set u.phone = :phone where u.id = :id")
+ void updatePhone(@Param(value = "id") long id, @Param(value = "phone") String phone);
+}
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/repository/CustomerStructuredRepository.java b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/repository/CustomerStructuredRepository.java
new file mode 100644
index 0000000000..0f9fd1e92e
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/repository/CustomerStructuredRepository.java
@@ -0,0 +1,11 @@
+package com.baeldung.partialupdate.repository;
+
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.stereotype.Repository;
+
+import com.baeldung.partialupdate.model.CustomerStructured;
+
+@Repository
+public interface CustomerStructuredRepository extends CrudRepository {
+ CustomerStructured findById(long id);
+}
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/service/CustomerService.java b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/service/CustomerService.java
new file mode 100644
index 0000000000..9da97a7775
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/service/CustomerService.java
@@ -0,0 +1,87 @@
+package com.baeldung.partialupdate.service;
+
+import javax.transaction.Transactional;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.baeldung.partialupdate.model.ContactPhone;
+import com.baeldung.partialupdate.model.Customer;
+import com.baeldung.partialupdate.model.CustomerDto;
+import com.baeldung.partialupdate.model.CustomerStructured;
+import com.baeldung.partialupdate.repository.ContactPhoneRepository;
+import com.baeldung.partialupdate.repository.CustomerRepository;
+import com.baeldung.partialupdate.repository.CustomerStructuredRepository;
+import com.baeldung.partialupdate.util.CustomerMapper;
+
+@Service
+@Transactional
+public class CustomerService {
+
+ @Autowired
+ CustomerRepository repo;
+ @Autowired
+ CustomerStructuredRepository repo2;
+ @Autowired
+ ContactPhoneRepository repo3;
+ @Autowired
+ CustomerMapper mapper;
+
+ public Customer getCustomer(long id) {
+ return repo.findById(id);
+ }
+
+ public void updateCustomerWithCustomQuery(long id, String phone) {
+ repo.updatePhone(id, phone);
+ }
+
+ public Customer addCustomer(String name) {
+ Customer myCustomer = new Customer();
+ myCustomer.name = name;
+ repo.save(myCustomer);
+ return myCustomer;
+ }
+
+ public Customer updateCustomer(long id, String phone) {
+ Customer myCustomer = repo.findById(id);
+ myCustomer.phone = phone;
+ repo.save(myCustomer);
+ return myCustomer;
+ }
+
+ public Customer addCustomer(CustomerDto dto) {
+ Customer myCustomer = new Customer();
+ mapper.updateCustomerFromDto(dto, myCustomer);
+ repo.save(myCustomer);
+ return myCustomer;
+ }
+
+ public Customer updateCustomer(CustomerDto dto) {
+ Customer myCustomer = repo.findById(dto.getId());
+ mapper.updateCustomerFromDto(dto, myCustomer);
+ repo.save(myCustomer);
+ return myCustomer;
+ }
+
+ public CustomerStructured addCustomerStructured(String name) {
+ CustomerStructured myCustomer = new CustomerStructured();
+ myCustomer.name = name;
+ repo2.save(myCustomer);
+ return myCustomer;
+ }
+
+ public void addCustomerPhone(long customerId, String phone) {
+ ContactPhone myPhone = new ContactPhone();
+ myPhone.phone = phone;
+ myPhone.customerId = customerId;
+ repo3.save(myPhone);
+ }
+
+ public CustomerStructured updateCustomerStructured(long id, String name) {
+ CustomerStructured myCustomer = repo2.findById(id);
+ myCustomer.name = name;
+ repo2.save(myCustomer);
+ return myCustomer;
+ }
+
+}
diff --git a/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/util/CustomerMapper.java b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/util/CustomerMapper.java
new file mode 100644
index 0000000000..8a666e3e6c
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-5/src/main/java/com/baeldung/partialupdate/util/CustomerMapper.java
@@ -0,0 +1,15 @@
+package com.baeldung.partialupdate.util;
+
+import org.mapstruct.BeanMapping;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingTarget;
+import org.mapstruct.NullValuePropertyMappingStrategy;
+
+import com.baeldung.partialupdate.model.Customer;
+import com.baeldung.partialupdate.model.CustomerDto;
+
+@Mapper(componentModel = "spring")
+public interface CustomerMapper {
+ @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
+ void updateCustomerFromDto(CustomerDto dto, @MappingTarget Customer entity);
+}
diff --git a/persistence-modules/spring-data-jpa-5/src/test/java/com/baeldung/partialupdate/PartialUpdateUnitTest.java b/persistence-modules/spring-data-jpa-5/src/test/java/com/baeldung/partialupdate/PartialUpdateUnitTest.java
new file mode 100644
index 0000000000..874e18c4ad
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-5/src/test/java/com/baeldung/partialupdate/PartialUpdateUnitTest.java
@@ -0,0 +1,63 @@
+package com.baeldung.partialupdate;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import com.baeldung.partialupdate.model.Customer;
+import com.baeldung.partialupdate.model.CustomerDto;
+import com.baeldung.partialupdate.model.CustomerStructured;
+import com.baeldung.partialupdate.service.CustomerService;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = PartialUpdateApplication.class)
+public class PartialUpdateUnitTest {
+
+ @Autowired
+ CustomerService service;
+
+ @Test
+ public void givenCustomer_whenUpdate_thenSuccess() {
+ Customer myCustomer = service.addCustomer("John");
+ myCustomer = service.updateCustomer(myCustomer.id, "+00");
+ assertEquals("+00", myCustomer.phone);
+ }
+
+ @Test
+ public void givenCustomer_whenUpdateWithQuery_thenSuccess() {
+ Customer myCustomer = service.addCustomer("John");
+ service.updateCustomerWithCustomQuery(myCustomer.id, "+88");
+ myCustomer = service.getCustomer(myCustomer.id);
+ assertEquals("+88", myCustomer.phone);
+ }
+
+ @Test
+ public void givenCustomerDto_whenUpdateWithMapper_thenSuccess() {
+ CustomerDto dto = new CustomerDto(new Customer());
+ dto.name = "Johnny";
+ Customer entity = service.addCustomer(dto);
+
+ CustomerDto dto2 = new CustomerDto(entity.id);
+ dto2.phone = "+44";
+ entity = service.updateCustomer(dto2);
+
+ assertEquals("Johnny", entity.name);
+ }
+
+ @Test
+ public void givenCustomerStructured_whenUpdateCustomerPhone_thenSuccess() {
+ CustomerStructured myCustomer = service.addCustomerStructured("John");
+ assertEquals(null, myCustomer.contactPhones);
+
+ service.addCustomerPhone(myCustomer.id, "+44");
+ myCustomer = service.updateCustomerStructured(myCustomer.id, "Mr. John");
+
+ assertNotEquals(null, myCustomer.contactPhones);
+ assertEquals(1, myCustomer.contactPhones.size());
+ }
+}