Spring Data Rest-сортировка по вложенному свойству

у меня есть служба базы данных, использующая Spring Boot 1.5.1 и Spring Data Rest. Я храню свои сущности в базе данных MySQL и обращаюсь к ним через REST, используя Spring PagingAndSortingRepository. Я нашел этой в котором говорится, что сортировка по вложенным параметрам поддерживается, но я не могу найти способ сортировки по вложенным полям.

у меня есть эти классы:

@Entity(name = "Person")
@Table(name = "PERSON")
public class Person {
    @ManyToOne
    protected Address address;

    @ManyToOne(targetEntity = Name.class, cascade = {
        CascadeType.ALL
    })
    @JoinColumn(name = "NAME_PERSON_ID")
    protected Name name;

    @Id
    protected Long id;

    // Setter, getters, etc.
}

@Entity(name = "Name")
@Table(name = "NAME")
public class Name{

    protected String firstName;

    protected String lastName;

    @Id
    protected Long id;

    // Setter, getters, etc.
}

например, при использовании метода:

Page<Person> findByAddress_Id(@Param("id") String id, Pageable pageable);

и вызов URI http://localhost:8080/people/search/findByAddress_Id?id=1 & sort=name_lastName, desc параметр сортировки полностью игнорируется Весна.

параметры сортировка=имя.фамилия и сортировка=nameLastName не работает.

я формирую запрос Rest неправильно или отсутствует какая-то конфигурация?

спасибо!

2 ответов


Я отладил это, и это похоже на проблему, о которой упоминал Алан.

Я нашел обходной путь, который может помочь:

создайте собственный контроллер, введите свое РЕПО и, возможно, фабрику проекций (если вам нужны проекции). Реализуйте метод get для делегирования вызова вашему репозиторию

 @RestController
 @RequestMapping("/people")
 public class PeopleController {

    @Autowired
    PersonRepository repository;

    //@Autowired
    //PagedResourcesAssembler<MyDTO> resourceAssembler;

    @GetMapping("/by-address/{addressId}")
    public Page<Person> getByAddress(@PathVariable("addressId") Long addressId, Pageable page)  {

        // spring doesn't spoil your sort here ... 
        Page<Person> page = repository.findByAddress_Id(addressId, page)

        // optionally, apply projection
        //  to return DTO/specifically loaded Entity objects ...
        //  return type would be then PagedResources<Resource<MyDTO>>
        // return resourceAssembler.toResource(page.map(...))

        return page;
    }

}

это работает для меня с 2.6.8.Выпуск; проблема, кажется, во всех версиях.


обходной путь, который я нашел, заключается в создании дополнительного свойства только для чтения только для целей сортировки. Построение на примере выше:

@Entity(name = "Person")
@Table(name = "PERSON")
public class Person {

    // read only, for sorting purposes only
    // @JsonIgnore // we can hide it from the clients, if needed
    @RestResource(exported=false) // read only so we can map 2 fields to the same database column
    @ManyToOne
    @JoinColumn(name = "address_id", insertable = false, updatable = false) 
    private Address address;

    // We still want the linkable association created to work as before so we manually override the relation and path
    @RestResource(exported=true, rel="address", path="address")
    @ManyToOne
    private Address addressLink;

    ...
}

недостатком предлагаемого обходного пути является то, что теперь мы должны явно дублировать все свойства, для которых мы хотим поддерживать вложенную сортировку.

LATER EDIT: еще один недостаток заключается в том, что мы не можем скрыть встроенное свойство от клиентов. В моем первоначальном ответе я предлагал добавить @JsonIgnore, но, по-видимому, что ломает рода.