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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user