BAEL-5547: added code for specifications join (#12212)
* BAEL-5547: added code for specifications join * BAEL-5547: renamed test class and formatted the code
This commit is contained in:
parent
8e7dc50c0e
commit
93b3264964
|
@ -0,0 +1,57 @@
|
||||||
|
package com.baeldung.spring.data.jpa.query.specifications.join;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Author {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String firstName;
|
||||||
|
|
||||||
|
private String lastName;
|
||||||
|
|
||||||
|
@OneToMany(cascade = CascadeType.ALL)
|
||||||
|
private List<Book> books;
|
||||||
|
|
||||||
|
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 List<Book> getBooks() {
|
||||||
|
return books;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBooks(List<Book> books) {
|
||||||
|
this.books = books;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Author{" + "id=" + id + ", firstName='" + firstName + '\'' + ", lastName='" + lastName + '\'' + ", books=" + books + '}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.baeldung.spring.data.jpa.query.specifications.join;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
|
|
||||||
|
import javax.persistence.criteria.*;
|
||||||
|
|
||||||
|
public class AuthorSpecifications {
|
||||||
|
|
||||||
|
public static Specification<Author> hasFirstNameLike(String name) {
|
||||||
|
return (root, query, criteriaBuilder) -> criteriaBuilder.like(root.<String>get("firstName"), "%" + name + "%");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Specification<Author> hasLastName(String name) {
|
||||||
|
return (root, query, cb) -> cb.equal(root.<String>get("lastName"), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Specification<Author> hasBookWithTitle(String bookTitle) {
|
||||||
|
return (root, query, criteriaBuilder) -> {
|
||||||
|
Join<Book, Author> authorsBook = root.join("books");
|
||||||
|
return criteriaBuilder.equal(authorsBook.get("title"), bookTitle);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.baeldung.spring.data.jpa.query.specifications.join;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface AuthorsRepository extends JpaRepository<Author, Long>, JpaSpecificationExecutor<Author> {
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.baeldung.spring.data.jpa.query.specifications.join;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Book {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Book{" + "id=" + id + ", title='" + title + '\'' + '}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
package com.baeldung.spring.data.jpa.query.specifications.join;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
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.data.jpa.domain.Specification;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.baeldung.spring.data.jpa.query.specifications.join.AuthorSpecifications.*;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@DataJpaTest
|
||||||
|
public class SpecificationsJoinIntegrationTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AuthorsRepository repository;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void beforeEach() {
|
||||||
|
saveTestData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSearchingByLastName_thenOneAuthorIsReturned() {
|
||||||
|
|
||||||
|
List<Author> authors = repository.findAll(hasLastName("Martin"));
|
||||||
|
|
||||||
|
assertThat(authors).hasSize(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSearchingByLastNameAndFirstNameLike_thenOneAuthorIsReturned() {
|
||||||
|
|
||||||
|
Specification<Author> specification = hasLastName("Martin").and(hasFirstNameLike("Robert"));
|
||||||
|
|
||||||
|
List<Author> authors = repository.findAll(specification);
|
||||||
|
|
||||||
|
assertThat(authors).hasSize(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSearchingByBookTitle_thenOneAuthorIsReturned() {
|
||||||
|
|
||||||
|
Specification<Author> specification = hasBookWithTitle("Clean Code");
|
||||||
|
|
||||||
|
List<Author> authors = repository.findAll(specification);
|
||||||
|
|
||||||
|
assertThat(authors).hasSize(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSearchingByBookTitleAndAuthorName_thenOneAuthorIsReturned() {
|
||||||
|
|
||||||
|
Specification<Author> specification = hasLastName("Martin").and(hasBookWithTitle("Clean Code"));
|
||||||
|
|
||||||
|
List<Author> authors = repository.findAll(specification);
|
||||||
|
|
||||||
|
assertThat(authors).hasSize(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveTestData() {
|
||||||
|
Author uncleBob = new Author();
|
||||||
|
uncleBob.setFirstName("Robert");
|
||||||
|
uncleBob.setLastName("Martin");
|
||||||
|
|
||||||
|
Book book1 = new Book();
|
||||||
|
book1.setTitle("Clean Code");
|
||||||
|
Book book2 = new Book();
|
||||||
|
book2.setTitle("Clean Architecture");
|
||||||
|
|
||||||
|
uncleBob.setBooks(Arrays.asList(book1, book2));
|
||||||
|
repository.save(uncleBob);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue