Spring Boot1.5.1とSpringDataRestを使用するデータベースサービスがあります。エンティティをMySQLデータベースに保存し、SpringのPagingAndSortingRepositoryを使用してRESTでアクセスします。ネストされたパラメーターによる並べ替えがサポートされていることを示す this を見つけましたが、ネストされたフィールドでソートする方法が見つかりません。
私はこれらのクラスを持っています:
@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リクエストの作成が間違っているのですか、それとも一部の構成が欠落していますか?
ありがとうございました!
私はそれを通してデバッグしました、そしてそれはアランが言及した問題のように見えます。
私は助けることができる回避策を見つけました:
独自のコントローラーを作成し、リポジトリとオプションでプロジェクションファクトリ(プロジェクションが必要な場合)を挿入します。 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.RELEASEで機能します。問題はすべてのバージョンにあるようです。
私が見つけた回避策は、並べ替えの目的でのみ追加の読み取り専用プロパティを作成することです。上記の例に基づいて構築:
@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;
...
}
提案された回避策の欠点は、ネストされた並べ替えをサポートするすべてのプロパティを明示的に複製する必要があることです。
後の編集:もう1つの欠点は、埋め込みプロパティをクライアントから隠すことができないことです。私の元の答えでは、@ JsonIgnoreを追加できることを提案していましたが、どうやらそれはソートを壊します。