List属性を持つクラスにexampleMatcherを使用する方法を尋ねたいと思います。同時に複数の役割を持つことができるユーザーがいると仮定しましょう。 DBからユーザーロールを持つすべてのユーザーを取得したい
エンティティ
@Entity(name = "UserEntity")
public class User {
Private Long id;
private String name;
private String surname;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn
private Address address;
@ManyToMany(cascade = CascadeType.MERGE, fetch = FetchType.EAGER)
@JoinColumn
private List<UserRole> roles;
}
@Entity
public class UserRole {
private Long id;
private String name;
}
いくつかの属性を持つUserクラスをgetExampleEntityに送信します。選択した役割のリストをUIから送信しようとしています。
コントローラの機能
@Override
protected User getExampleEntity() {
User clonedUser = new User();
List<UserRole> selectedRole = new ArrayList<>();
// this cycle just find and add all roles in db based on selection from UI
for (Long roleID : selectedUserRoleIDs)
selectedRole.add(userRoleService.find(roleID));
clonedUser.setRoles(selectedRole);
return clonedUser;
}
JpaRepositoryの関数。Matcherの例を使用してfindByExample関数を呼び出します。
@Override
public List<TObjectType> findByExample(int first, int pageSize, String sortField, Sort.Direction sortOrder, TObjectType type)
{
PageRequest pageRequest = getPageRequest(first, pageSize, sortField, sortOrder);
ExampleMatcher exampleMatcher = getExampleMatcher();
Example<TObjectType> example = Example.of(type, exampleMatcher);
return repository.findAll(example, pageRequest).getContent();
}
/**
* Generates an example matcher for the instance of {@link TObjectType}.
* This can be overriden if a custom matcher is needed! The default property matcher ignores the "id" path and ignores null values.
* @return
*/
protected ExampleMatcher getExampleMatcher() {
return ExampleMatcher.matching()
.withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING)
.withIgnoreNullValues();
}
属性名/姓、またはAddressクラスの任意の属性を持つユーザーを送信する場合、それは夢のように機能しますが、リストロールでは機能しません。この問題を解決する方法と、TObjectTypeの配列を属性としてfindByExampleを使用する方法のヒントをいただければ幸いです。どうもありがとうございました
編集:私は問題を見つけました。 repository.findAll関数のコードがあります(org.springframework.data.repository.query.QueryByExampleExecutor#findAll)
@Override
public <S extends T> Page<S> findAll(Example<S> example, Pageable pageable) {
ExampleSpecification<S> spec = new ExampleSpecification<S>(example);
Class<S> probeType = example.getProbeType();
TypedQuery<S> query = getQuery(new ExampleSpecification<S>(example), probeType, pageable);
return pageable == null ? new PageImpl<S>(query.getResultList()) : readPage(query, probeType, pageable, spec);
}
生成されたクエリにはリスト属性が含まれていませんが、理由がわかりません。また、Exampleオブジェクトに含まれています。誰かがこの問題を経験したことがありますか?設定/注釈の問題だけがあると思います。
最初はトランスフォーマーを使用してみてください。以下の例はMongodbの例ですが、アプローチを見ることができます。私の場合、Userクラスにはロールのリストが文字列として含まれています。
final ExampleMatcher matcher = ExampleMatcher.matching()
.withIgnoreNullValues()
.withMatcher("roles", match -> match.transform(source -> ((BasicDBList) source).iterator().next()).caseSensitive());
users = userRepository.findAll(Example.of(criteria, matcher), pageRequest);