Search code examples
hibernatehibernate-criteria

Hibernate generic query method for non-ID columns?


I've been working on Java EE project which uses JAX-RS and Hibernate for accesing the database. So far I've used hibernate's criteria api to do querys and I have a good generic method for getting all the rows from a table. The problem comes when I only query for a part of a table. I have multiple tables, most of which has an auto generated int id and string fields. Usually some of the string fields have uniqe constraint on them. I have to write querys based on these string fields, which together has to be uniqe. So far I've used methods like this for this: (the Service class is one of my entities)

public Service getService(String serviceGroup, String serviceDefinition){
    Service service = new Service();

    Session session = getSessionFactory().openSession();
    Transaction transaction = null;

    try {
         transaction = session.beginTransaction();
         Criteria criteria = session.createCriteria(Service.class);
         criteria.add(Restrictions.eq("serviceGroup", serviceGroup));
         criteria.add(Restrictions.eq("serviceDefinition", serviceDefinition));
         service = (Service) criteria.uniqueResult();
         transaction.commit();
     }
     catch (Exception e) {
         if (transaction!=null) transaction.rollback();
         throw e;
     }
     finally {
         session.close();
     }

    return service;
}

My problem is that the rows with the Restrictions has hardcoded strings, which have to match the field names in my entity classes. This is getting problematic as I have more and more tables. (basically I have the same method for every table) How could I make a generic query method witch functions like this method? Do I have a better option than the criteria api? Anything pointing me in the good direction would be great.


Solution

  • You can do something like this

    public Service getService(String serviceGroup, String serviceDefinition,Map<String,String> restrictionMap,Class queryClass ){
    Service service = new Service();
    
    Session session = getSessionFactory().openSession();
    Transaction transaction = null;
    
    try {
         transaction = session.beginTransaction();
         Criteria criteria = session.createCriteria(queryClass);
          if(null!=restrictionMap && !restrictionMap .isEmpty()){
           for(Entry<String,String> entry:restrictionMap.entrySet()){
            criteria.add(Restrictions.eq(entry.getKey(), entry.getValue());
         }
       }
         service = (Service) criteria.uniqueResult();
         transaction.commit();
     }
     catch (Exception e) {
         if (transaction!=null) transaction.rollback();
         throw e;
     }
     finally {
         session.close();
     }
    
    return service;
    

    }

    Restriction map will have the class member name as key and the corresponding value as the value in the map