tags:

views:

429

answers:

2

Hi,

i was wondering whether it is possible to find an object using an example object like you can in hibernate with:

Cat cat = new Cat();
cat.Sex = 'F';
cat.Color = Color.Black;
List results = session.CreateCriteria(typeof(Cat)).Add( Example.Create(cat)).List();

I know i can find by primary key, just not looking forward to writing a million lines of findByX, findByY etc etc.

thanks.

Nico

+2  A: 

It seems as if the Criteria API is being considered for the next JPA release. There is some discussion about it here.

It would seem that at the moment if you want the Query by Example and Criteria features then you will have to use Hibernate.

Vincent Ramdhanie
+1 thanks.. good to know it's coming.
Nico
A: 

so since it's not available in the current JPA API, the only way i can see how to implement it would be by using this:

 public <T> List<T> findByAttribute(T object) {
    List<T> found = new ArrayList<T>();
    Map m = null;
    try {
        m = BeanUtils.describe(object);
    } catch (Exception ex) {
        return null;
    }

    String query = "select c from " + object.getClass().getSimpleName() + " c  where ";
    if (m != null) {
        for (Object key : m.keySet()) {
            if (!key.equals("class")) {
                Object value = m.get(key);

                if (value != null) {
                    try {
                        ConvertUtils.convert(m.get(key), PropertyUtils.getPropertyType(object, key.toString()));
                        query += " c." + key + " = :" + key + " and";

                    } catch (Exception ex) {
                        // the reason for this noncy try catch is so that you don't add parameters that are not primitives
                    }
                }
            }
        }
        query = query.substring(0, query.lastIndexOf("and"));
        Query q = getEntityManager().createQuery(query);
        for (Object key : m.keySet()) {
            if (!key.equals("class")) {
                if (m.get(key) != null) {
                    try {
                        Object o = ConvertUtils.convert(m.get(key), PropertyUtils.getPropertyType(object, key.toString()));
                        q.setParameter(key.toString(), o);
                    } catch (Exception ex) {
                        System.out.println("what we have here is a failure to communicate");
                        System.out.println("only primitive types allowed");
                    }
                }
            }
        }
        List resultList = q.getResultList();
        if (resultList != null) {
            found.addAll(resultList);
        }
    }
    return found;
}

but this will only work for primitive types i think. I guess it's something.

Thanks anyway

N

Nico