2 Replies Latest reply on Jan 29, 2007 2:15 PM by perrylucas

    Query By Example in Seam

    perrylucas Newbie

      So I was looking around Hibernate's API and found the QBE bit which seems to be handy for simple queries. I then wondered how I could go about something similar in Seam. I didn't want to open up my own Hibernate Session and consequently manage that Session, so I came up with a little utility method for QBE. Granted this example is very limited and simplistic, but I could see it coming in handy for some of the simpler queries.

      public class QueryUtils {
      ...
       public static <T> List<T> queryByExample(T example, EntityManager em){
       Class clazz = example.getClass();
       StringBuffer q = new StringBuffer("from " + clazz.getName() + " obj");
       Map<String, Object> params = new HashMap<String, Object>();
       Field[] fields = clazz.getDeclaredFields();
       boolean isFirstClause = true;
       for(Field field: fields){
       String getterName = "get" + StringUtils.capitalize(field.getName());
       try{
       Method getter = clazz.getDeclaredMethod(getterName, new Class[0]);
       Object propertyValue = getter.invoke(example, new Object[0]);
       if(propertyValue != null){
       if(isFirstClause){
       q.append(" where ");
       }else{
       q.append(" and ");
       }
       q.append("obj." + field.getName() + " = :" + field.getName());
       params.put(field.getName(), propertyValue);
       isFirstClause = false;
       }
       }catch(NoSuchMethodException nsme){
       //do nothing for now
       }catch(InvocationTargetException ite){
       //do nothing for now
       }catch(IllegalAccessException iae){
       //do nothing for now
       }
       }
       Query query = em.createQuery(q.toString());
       for(String key: params.keySet()){
       query.setParameter(key, params.get(key));
       }
       System.out.println(q.toString());
       return query.getResultList();
       }
      ...
      


      Also, I wanted to mention that QBE inherently does not include any way to search, say, within a date range or an integer range if your bean so happens to have a date or integer property. In this case, would you just opt not to use QBE at all, or do you go into adding Expressions via hints? The end goal is to be able to make otherwise long/tedious queries simply by providing an example (and perhaps also expressions for ranged properties). I just wanted to present this to the community and see what others are doing.