Hibernate criteria: search by content on a property list in an entity

10,056

First of all, the UserLanguages entity should be named UserLanguage : it represents one language, and not several.

Then, the pers_id column is a foreign key to the User entity. It should thus be mapped as a ManyToOne relationship to the User entity rather than a basic column.

Finally, and to answer your question (I'll assume you want to find the users having at least one user language whose langISO code is in the contents list) : you should use a join :

// inner join between User and UserLanguages
criteria.createAlias("languages", "userLanguage"); 
// restriction on the langISO property of UserLanguage
criteria.add(Restrictions.in("userLanguage.langIso", contents));
Share:
10,056
BasicCoder
Author by

BasicCoder

Updated on June 04, 2022

Comments

  • BasicCoder
    BasicCoder almost 2 years

    I want to search by content on a property in an entity

    I have a simple class to define a User:

    @Entity
    public class User {
    
        @Id
        @Column(name = "pers_id")
        private int persId; 
    
        @Column(name = "full_name")
        private String fullName;    
    
        @OneToMany
        @JoinColumn(name = "PERS_ID")
        private List<UserLanguages> languages = new ArrayList<UserLanguages>();
    }
    

    A User can have multiple languages, here is the class to make the link between user and a language.

    @Entity
    public class UserLanguages {
        @Column(name="pers_id")
        private int persId; 
    
        @Id
        @Column(name="lang_iso_code")
        private String langISO;
    
        @Column(name="lang_full_name")
        private String langFullName;
    
        @Column(name="order_seq")
        private int order;
    }
    
    @Entity
    public class Language {
        @Id 
        @Column(name="ID")
        private long id;
    
        @Column(name = "CODE")  
        private String code;
    }
    

    I have created a object to do search:

    public class UserFilter {    
        private String name;
    
        private List<Language> languages;
    }
    

    I have defined a service:

    @Service("userService")
    public class UserServiceImpl implements UserService {
    
    @Override
    public List<User> findByFilter(UserFilter userFilter) {
        final Criteria criteria = userDao.createCriteria();
        if (userFilter.getName() != null) {
            for (final String token : userFilter.getName().toLowerCase().trim().split(" ")) {
            criteria.add(Restrictions.like("fullName", "%" + token + "%"));
            }
        }
    
        if (null != userFilter.getLanguages() && userFilter.getLanguages().size() > 0) {
    
            final List<String> contents = new ArrayList<String>(userFilter.getLanguages().size());
            for (final Language lang : userFilter.getLanguages()) {
            contents.add(lang.getCode());
            }    
            criteria.add(Restrictions.in("languages", contents));
        }
    
        return userDao.findByCriteria(criteria);
    }
    

    My question is how can I do search on languages. I want to find all users with this or thoses languages defined in the userFilter param. The part about languages doesn't work in the method findByFilter in the service. Can you help me?

  • BasicCoder
    BasicCoder about 13 years
    Ok, thank you. I have changed UserLanguages to UserLanguage, you right. Now, I used the ManyToOne relation. But I don't understand where come from the language.langIso in the last Restrictions?
  • JB Nizet
    JB Nizet about 13 years
    Sorry. I forget the double quotes and the user prefix. I updated my answer.