DATAREST-883 - Consider Jackson field names in Sort mapping.
We now consider Jackson field names when resolving Sort arguments. Domain model properties annotated with @JsonProperty("sales") can be specified by their Jackson-mapped field name in sort arguments. Field names are mapped to their according persistent property names to be used in repository query method sorting. Unknown field names are silently dropped.
Original pull request: #222.
This commit is contained in:
committed by
Oliver Gierke
parent
bacd8be4fc
commit
a999bd3ca8
@@ -26,8 +26,11 @@ import javax.persistence.ManyToMany;
|
||||
|
||||
import org.springframework.data.rest.core.annotation.RestResource;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@Entity
|
||||
public class Book {
|
||||
@@ -35,16 +38,20 @@ public class Book {
|
||||
public @Id @GeneratedValue Long id;
|
||||
public String isbn, title;
|
||||
|
||||
@JsonProperty("sales")
|
||||
public long soldUnits;
|
||||
|
||||
@ManyToMany(cascade = { CascadeType.MERGE }) //
|
||||
@RestResource(path = "creators") //
|
||||
public Set<Author> authors;
|
||||
|
||||
protected Book() {}
|
||||
|
||||
public Book(String isbn, String title, Iterable<Author> authors) {
|
||||
public Book(String isbn, String title, long soldUnits, Iterable<Author> authors) {
|
||||
|
||||
this.isbn = isbn;
|
||||
this.title = title;
|
||||
this.soldUnits = soldUnits;
|
||||
|
||||
this.authors = new HashSet<Author>();
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@ package org.springframework.data.rest.webmvc.jpa;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
@@ -26,6 +28,7 @@ import org.springframework.data.rest.core.annotation.RestResource;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@RepositoryRestResource(excerptProjection = BookExcerpt.class)
|
||||
public interface BookRepository extends CrudRepository<Book, Long> {
|
||||
@@ -35,4 +38,8 @@ public interface BookRepository extends CrudRepository<Book, Long> {
|
||||
|
||||
@Query("select b from Book b where :author member of b.authors")
|
||||
List<Book> findByAuthorsContains(@Param("author") Author author);
|
||||
|
||||
@RestResource(rel = "find-spring-books-sorted")
|
||||
@Query("select b from Book b where b.title like 'Spring%'")
|
||||
Page<Book> findByTitleIsLike(Pageable pageable);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import static org.junit.Assert.*;
|
||||
import static org.springframework.data.rest.webmvc.util.TestUtils.*;
|
||||
import static org.springframework.http.HttpHeaders.*;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
||||
|
||||
import net.minidev.json.JSONArray;
|
||||
@@ -57,6 +58,7 @@ import com.jayway.jsonpath.JsonPath;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Greg Turnquist
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@Transactional
|
||||
@ContextConfiguration(classes = JpaRepositoryConfig.class)
|
||||
@@ -546,7 +548,7 @@ public class JpaWebTests extends CommonWebTests {
|
||||
* @see DATAREST-384
|
||||
*/
|
||||
@Test
|
||||
public void execturesSearchThatTakesASort() throws Exception {
|
||||
public void exectuesSearchThatTakesASort() throws Exception {
|
||||
|
||||
Link booksLink = client.discoverUnique("books");
|
||||
Link searchLink = client.discoverUnique(booksLink, "search");
|
||||
@@ -568,6 +570,57 @@ public class JpaWebTests extends CommonWebTests {
|
||||
andExpect(client.hasLinkWithRel("self"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAREST-883
|
||||
*/
|
||||
@Test
|
||||
public void exectuesSearchThatTakesAMappedSortProperty() throws Exception {
|
||||
|
||||
Link booksLink = client.discoverUnique("books");
|
||||
Link searchLink = client.discoverUnique(booksLink, "search");
|
||||
Link findBySortedLink = client.discoverUnique(searchLink, "find-by-sorted");
|
||||
|
||||
// Assert sort options advertised
|
||||
assertThat(findBySortedLink.isTemplated(), is(true));
|
||||
assertThat(findBySortedLink.getVariableNames(), hasItems("sort", "projection"));
|
||||
|
||||
// Assert results returned as specified
|
||||
client.follow(findBySortedLink.expand("sales,desc")).//
|
||||
andExpect(jsonPath("$._embedded.books[0].title").value("Spring Data (Second Edition)")).//
|
||||
andExpect(jsonPath("$._embedded.books[1].title").value("Spring Data")).//
|
||||
andExpect(client.hasLinkWithRel("self"));
|
||||
|
||||
client.follow(findBySortedLink.expand("sales,asc")).//
|
||||
andExpect(jsonPath("$._embedded.books[0].title").value("Spring Data")).//
|
||||
andExpect(jsonPath("$._embedded.books[1].title").value("Spring Data (Second Edition)")).//
|
||||
andExpect(client.hasLinkWithRel("self"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAREST-883
|
||||
*/
|
||||
@Test
|
||||
public void exectuesCustomQuerySearchThatTakesAMappedSortProperty() throws Exception {
|
||||
|
||||
Link booksLink = client.discoverUnique("books");
|
||||
Link searchLink = client.discoverUnique(booksLink, "search");
|
||||
Link findByLink = client.discoverUnique(searchLink, "find-spring-books-sorted");
|
||||
|
||||
// Assert sort options advertised
|
||||
assertThat(findByLink.isTemplated(), is(true));
|
||||
|
||||
// Assert results returned as specified
|
||||
client.follow(findByLink.expand("0", "10", "sales,desc")).//
|
||||
andExpect(jsonPath("$._embedded.books[0].title").value("Spring Data (Second Edition)")).//
|
||||
andExpect(jsonPath("$._embedded.books[1].title").value("Spring Data")).//
|
||||
andExpect(client.hasLinkWithRel("self"));
|
||||
|
||||
client.follow(findByLink.expand("0", "10", "unknown,asc,sales,asc")).//
|
||||
andExpect(jsonPath("$._embedded.books[0].title").value("Spring Data")).//
|
||||
andExpect(jsonPath("$._embedded.books[1].title").value("Spring Data (Second Edition)")).//
|
||||
andExpect(client.hasLinkWithRel("self"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAREST-160
|
||||
*/
|
||||
|
||||
@@ -53,8 +53,8 @@ public class TestDataPopulator {
|
||||
|
||||
Iterable<Author> authors = this.authors.save(Arrays.asList(ollie, mark, michael, david, john, thomas));
|
||||
|
||||
books.save(new Book("1449323952", "Spring Data", authors));
|
||||
books.save(new Book("1449323953", "Spring Data (Second Edition)", authors));
|
||||
books.save(new Book("1449323952", "Spring Data", 1000, authors));
|
||||
books.save(new Book("1449323953", "Spring Data (Second Edition)", 2000, authors));
|
||||
}
|
||||
|
||||
private void populateOrders() {
|
||||
|
||||
Reference in New Issue
Block a user