Spring Data JPA projections (#6733)
This commit is contained in:
parent
6796ec3af7
commit
4ca3d5049d
|
@ -0,0 +1,57 @@
|
|||
package com.baeldung.projection.model;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToOne;
|
||||
|
||||
@Entity
|
||||
public class Address {
|
||||
@Id
|
||||
private Long id;
|
||||
@OneToOne
|
||||
private Person person;
|
||||
private String state;
|
||||
private String city;
|
||||
private String street;
|
||||
private String zipCode;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public String getStreet() {
|
||||
return street;
|
||||
}
|
||||
|
||||
public void setStreet(String street) {
|
||||
this.street = street;
|
||||
}
|
||||
|
||||
public String getZipCode() {
|
||||
return zipCode;
|
||||
}
|
||||
|
||||
public void setZipCode(String zipCode) {
|
||||
this.zipCode = zipCode;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package com.baeldung.projection.model;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToOne;
|
||||
|
||||
@Entity
|
||||
public class Person {
|
||||
@Id
|
||||
private Long id;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
@OneToOne(mappedBy = "person")
|
||||
private Address address;
|
||||
|
||||
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 Address getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(Address address) {
|
||||
this.address = address;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package com.baeldung.projection.repository;
|
||||
|
||||
import com.baeldung.projection.view.AddressView;
|
||||
import com.baeldung.projection.model.Address;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface AddressRepository extends Repository<Address, Long> {
|
||||
List<AddressView> getAddressByState(String state);
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package com.baeldung.projection.repository;
|
||||
|
||||
import com.baeldung.projection.model.Person;
|
||||
import com.baeldung.projection.view.PersonDto;
|
||||
import com.baeldung.projection.view.PersonView;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
public interface PersonRepository extends Repository<Person, Long> {
|
||||
PersonView findByLastName(String lastName);
|
||||
|
||||
PersonDto findByFirstName(String firstName);
|
||||
|
||||
<T> T findByLastName(String lastName, Class<T> type);
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package com.baeldung.projection.view;
|
||||
|
||||
public interface AddressView {
|
||||
String getZipCode();
|
||||
|
||||
PersonView getPerson();
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package com.baeldung.projection.view;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class PersonDto {
|
||||
private final String firstName;
|
||||
private final String lastName;
|
||||
|
||||
public PersonDto(String firstName, String lastName) {
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
PersonDto personDto = (PersonDto) o;
|
||||
return Objects.equals(firstName, personDto.firstName) && Objects.equals(lastName, personDto.lastName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(firstName, lastName);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.baeldung.projection.view;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
public interface PersonView {
|
||||
String getFirstName();
|
||||
|
||||
String getLastName();
|
||||
|
||||
@Value("#{target.firstName + ' ' + target.lastName}")
|
||||
String getFullName();
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package com.baeldung.projection;
|
||||
|
||||
import com.baeldung.projection.model.Person;
|
||||
import com.baeldung.projection.repository.AddressRepository;
|
||||
import com.baeldung.projection.repository.PersonRepository;
|
||||
import com.baeldung.projection.view.AddressView;
|
||||
import com.baeldung.projection.view.PersonDto;
|
||||
import com.baeldung.projection.view.PersonView;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.test.context.jdbc.Sql;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.AFTER_TEST_METHOD;
|
||||
|
||||
@DataJpaTest
|
||||
@RunWith(SpringRunner.class)
|
||||
@Sql(scripts = "/projection-insert-data.sql")
|
||||
@Sql(scripts = "/projection-clean-up-data.sql", executionPhase = AFTER_TEST_METHOD)
|
||||
public class JpaProjectionIntegrationTest {
|
||||
@Autowired
|
||||
private AddressRepository addressRepository;
|
||||
|
||||
@Autowired
|
||||
private PersonRepository personRepository;
|
||||
|
||||
@Test
|
||||
public void whenUsingClosedProjections_thenViewWithRequiredPropertiesIsReturned() {
|
||||
AddressView addressView = addressRepository.getAddressByState("CA").get(0);
|
||||
assertThat(addressView.getZipCode()).isEqualTo("90001");
|
||||
|
||||
PersonView personView = addressView.getPerson();
|
||||
assertThat(personView.getFirstName()).isEqualTo("John");
|
||||
assertThat(personView.getLastName()).isEqualTo("Doe");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingOpenProjections_thenViewWithRequiredPropertiesIsReturned() {
|
||||
PersonView personView = personRepository.findByLastName("Doe");
|
||||
assertThat(personView.getFullName()).isEqualTo("John Doe");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingClassBasedProjections_thenDtoWithRequiredPropertiesIsReturned() {
|
||||
PersonDto personDto = personRepository.findByFirstName("John");
|
||||
assertThat(personDto.getFirstName()).isEqualTo("John");
|
||||
assertThat(personDto.getLastName()).isEqualTo("Doe");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingDynamicProjections_thenObjectWithRequiredPropertiesIsReturned() {
|
||||
Person person = personRepository.findByLastName("Doe", Person.class);
|
||||
PersonView personView = personRepository.findByLastName("Doe", PersonView.class);
|
||||
PersonDto personDto = personRepository.findByLastName("Doe", PersonDto.class);
|
||||
|
||||
assertThat(person.getFirstName()).isEqualTo("John");
|
||||
assertThat(personView.getFirstName()).isEqualTo("John");
|
||||
assertThat(personDto.getFirstName()).isEqualTo("John");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
DELETE FROM address;
|
||||
DELETE FROM person;
|
|
@ -0,0 +1,2 @@
|
|||
INSERT INTO person(id,first_name,last_name) VALUES (1,'John','Doe');
|
||||
INSERT INTO address(id,person_id,state,city,street,zip_code) VALUES (1,1,'CA', 'Los Angeles', 'Standford Ave', '90001');
|
Loading…
Reference in New Issue