2017-02-03 5 views
6

Я хотел бы спросить, как использовать exampleMatcher для класса с атрибутом List. Предположим, у нас есть пользователь, который может иметь несколько ролей одновременно. Я хочу, чтобы все пользователи с ролью пользователя из БДкак использовать пример весны пример matcher для атрибута списка - проблема запроса

объекты

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

Я посылаю класс пользователя с некоторыми атрибутами getExampleEntity. Я пытаюсь отправить список выбранных ролей из пользовательского интерфейса.

функция в контроллере

@Override 
    protected User getExampleEntity() { 
     User clonedUser = new User(); 
     List<UserRole> selectedRole = new ArrayList<>(); 

// этот цикл просто найти и добавить все роли в БД на основе выбора из UI для (Long: Идентификатор роли selectedUserRoleIDs) selectedRole.add (userRoleService.find (Идентификатор роли)); clonedUser.setRoles (selectedRole); return clonedUser; }

Функция из JpaRepository, вызывающая функцию findByExample с примером Matcher.

@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 класса, но он не работает с ролями списка. Я буду благодарен за любые советы, как решить эту проблему и как я могу использовать findByExample с массивом TObjectType в качестве атрибута. Большое спасибо

EDIT: Я нашел проблему. Существует код функции 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); 
    } 

Сформирован запрос не включает в себя атрибут списка, но я понятия не имею, почему и он включен в Пример объекта. Кто-нибудь сталкивается с этой проблемой? Я предполагаю, что есть только проблема с установкой/аннотацией.

+1

У меня такой же вопрос, как и вы. Я видел в документации, хотя он говорит [link] (http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#query-by-example.execution). Только свойства SingularAttribute могут в настоящее время используется для сопоставления свойств. Я попытался изучить свойства SingularAttribute, но я подумал, что это может означать исключение списков ... – ejgreenwald

+0

Вы нашли решение этой проблемы ?! Ваш вопрос на месте, и меня действительно интересует то, что вы на самом деле делали. – Thodoris

ответ

0

Сначала вы должны попробовать использовать трансформатор. Пример ниже для 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); 
Смежные вопросы