2017-02-03 2 views
6

Je voudrais demander comment utiliser exampleMatcher pour la classe avec l'attribut List. Supposons, nous avons un utilisateur qui peut avoir plusieurs rôles en même temps. Je veux tous les utilisateurs avec le rôle de l'utilisateur de DBcomment utiliser l'exemple de données printanier pour l'attribut de liste - problème de requête

entités

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

J'envoie une classe utilisateur avec quelques attributs à getExampleEntity. J'essaie d'envoyer la liste des rôles sélectionnés de l'interface utilisateur maintenant. fonction

dans le contrôleur

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

// ce cycle trouver juste et ajouter tous les rôles dans db basés sur la sélection de l'interface utilisateur pour (Long RoleId: selectedUserRoleIDs) selectedRole.add (userRoleService.find (RoleId)) clonedUser.setRoles (selectedRole); return clonedUser; }

Fonction de JpaRepository, qui appelle la fonction findByExample avec l'exemple 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(); 

    } 

Il fonctionne comme un rêve si enverra un utilisateur avec le nom d'attribut/nom ou même un attribut dans la classe d'adresses, mais il ne fonctionne pas avec la liste des rôles. J'apprécierai des conseils comment résoudre ce problème et comment je peux utiliser findByExample avec le tableau de TObjectType comme attribut. Merci beaucoup

EDIT: J'ai trouvé le problème. Il y a un code de la fonction 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); 
    } 

requête générée ne comprend pas l'attribut de liste, mais je ne sais pas pourquoi et il est inclus de Exemple d'objet Quelqu'un at-il de l'expérience avec ce problème? Je suppose qu'il y a un problème de réglage/annotation seulement.

+1

J'ai la même question que vous. J'ai vu dans la documentation, mais il est dit [link] (http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#query-by-example.execution) Seules les propriétés SingularAttribute peuvent actuellement être utilisé pour la correspondance de propriété. J'ai essayé de rechercher les propriétés de SingularAttribute, mais je pensais que cela pouvait faire référence à l'exclusion des listes ... – ejgreenwald

+0

Avez-vous trouvé une solution à ce problème ?! Votre question est sur, et je suis vraiment intéressé par ce que vous avez réellement fait. – Thodoris

Répondre

0

Vous devriez essayer d'utiliser un transformateur dans un premier temps. L'exemple ci-dessous est pour Mongodb, mais vous pouvez voir l'approche. Dans mon cas, la classe User contient la liste des rôles en tant que chaînes:

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