Merge pull request #9268 from mguarnaccia/BAEL-3985
[BAEL-3985] First commit
This commit is contained in:
commit
f5c5cc5290
|
@ -1,6 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns="http://maven.apache.org/POM/4.0.0" 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">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>spring-data-jpa-5</artifactId>
|
<artifactId>spring-data-jpa-5</artifactId>
|
||||||
<name>spring-data-jpa-5</name>
|
<name>spring-data-jpa-5</name>
|
||||||
|
@ -11,7 +12,7 @@
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-boot-2</relativePath>
|
<relativePath>../../parent-boot-2</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
@ -28,10 +29,43 @@
|
||||||
<artifactId>spring-boot-starter-data-jdbc</artifactId>
|
<artifactId>spring-boot-starter-data-jdbc</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-cache</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.h2database</groupId>
|
<groupId>com.h2database</groupId>
|
||||||
<artifactId>h2</artifactId>
|
<artifactId>h2</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mapstruct</groupId>
|
||||||
|
<artifactId>mapstruct-jdk8</artifactId>
|
||||||
|
<version>1.3.1.Final</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<sourceDirectory>src/main/java</sourceDirectory>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
<annotationProcessorPaths>
|
||||||
|
<path>
|
||||||
|
<groupId>org.mapstruct</groupId>
|
||||||
|
<artifactId>mapstruct-processor</artifactId>
|
||||||
|
<version>1.3.1.Final</version>
|
||||||
|
</path>
|
||||||
|
</annotationProcessorPaths>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<ContactPhone> contactPhones;
|
||||||
|
|
||||||
|
@Override public String toString() {
|
||||||
|
return String.format("Customer %s, Phone: %s",
|
||||||
|
this.name, this.contactPhones.stream()
|
||||||
|
.map(e -> e.toString()).reduce("", String::concat));
|
||||||
|
}
|
||||||
|
}
|
|
@ -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, Long> {
|
||||||
|
ContactPhone findById(long id);
|
||||||
|
ContactPhone findByCustomerId(long id);
|
||||||
|
}
|
|
@ -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, Long> {
|
||||||
|
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);
|
||||||
|
}
|
|
@ -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, Long> {
|
||||||
|
CustomerStructured findById(long id);
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue