programing

Spring Data Rest - 내포된 특성별 정렬

css3 2023. 7. 29. 08:46

Spring Data Rest - 내포된 특성별 정렬

Spring Boot 1.5.1 및 Spring Data Rest를 사용하는 데이터베이스 서비스를 보유하고 있습니다.MySQL 데이터베이스에 엔티티를 저장하고 Spring의 PagingAndSortingRespository를 사용하여 REST를 통해 액세스합니다.중첩 매개 변수별 정렬이 지원되지만 중첩 필드별 정렬 방법을 찾을 수 없습니다.

다음과 같은 수업이 있습니다.

@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를 호출하면 Sort 매개 변수가 Spring에 의해 완전히 무시됩니다.

sort=name.lastName 및 sort=nameLastName 매개 변수도 작동하지 않았습니다.

Rest 요청을 잘못 작성했거나 일부 구성이 누락되었습니까?

감사해요!

내가 찾은 해결 방법은 정렬 목적으로만 추가 읽기 전용 속성을 만드는 것입니다.위의 예를 기반으로 구축:

@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;

    ...
}

제안된 해결 방법의 단점은 중첩 정렬을 지원하려는 모든 속성을 명시적으로 복제해야 한다는 것입니다.

나중에 편집: 내장된 속성을 클라이언트로부터 숨길 수 없다는 또 다른 단점이 있습니다.제 원래 답변에서, 저는 우리가 @JsonIgnore를 추가할 수 있다고 제안하고 있었지만, 분명히 그것은 그런 종류를 깨뜨렸습니다.

저는 그것을 디버그했고 그것은 앨런이 언급한 문제처럼 보입니다.

다음과 같은 도움이 될 수 있는 해결 방법을 찾았습니다.

자체 컨트롤러를 만들고, 레포를 주입하고, 선택적으로 투영 팩토리를 주입합니다(프로젝션이 필요한 경우).저장소에 호출을 위임하는 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에서 작동합니다.릴리스. 모든 버전에 문제가 있는 것 같습니다.

Spring Data REST 설명서에서:

연결 가능한 연결(즉, 최상위 리소스에 대한 링크)별 정렬은 지원되지 않습니다.

https://docs.spring.io/spring-data/rest/docs/current/reference/html/ #cisco-and-messages.messages

제가 찾은 대안은@ResResource(exported=false)리소스/엔티티가 HTTP 링크로 로드되지 않도록 방지하기 때문에(특히 레거시 Spring Data REST 프로젝트의 경우) 이것은 유효하지 않습니다.

JacksonBinder
BeanDeserializerBuilder updateBuilder throws
 com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of ' com...' no String-argument constructor/factory method to deserialize from String value

주석의 도움으로 연결 가능한 연결에 의한 정렬을 활성화하려고 했지만 성공하지 못했습니다. 항상 오버라이드가 필요하기 때문입니다.mappPropertyPathJacksonMappingAwareSortTranslator.SortTranslator주석 감지:

            if (associations.isLinkableAssociation(persistentProperty)) {
                if(!persistentProperty.isAnnotationPresent(SortByLinkableAssociation.class)) {
                    return Collections.emptyList();
                }
            }

주석

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface SortByLinkableAssociation {
}

프로젝트 마크 연결에서 @SortByLinkableAssociation:

@ManyToOne
@SortByLinkableAssociation
private Name name;

실제로 저는 이 문제에 대한 명확하고 성공적인 해결책을 찾지 못했지만, 이 문제에 대해 생각하거나 심지어 Spring 팀이 다음 릴리스에 포함할 것을 고려하기 위해 이 문제를 노출하기로 결정했습니다.

연결된 엔티티별로 정렬하고 싶을 때 가능한 해결 방법/해결 방법은 https://stackoverflow.com/a/66135148/6673169 을 참조하십시오.

언급URL : https://stackoverflow.com/questions/42262846/spring-data-rest-sort-by-nested-property