0

I am having a lot of methods of this type:

public static List<EduUsers> getDetails(Class c, Map<String, Integer> params) {
        List<EduUsers> details = null;
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            Criteria cr = session.createCriteria(c);
            for (Map.Entry<String, Integer> entry : params.entrySet()) {
                cr.add(Restrictions.eq(entry.getKey(), entry.getValue()));
            }
            details = cr.list();
            tx.commit();
        } catch (Exception asd) {
            log.debug(asd.getMessage());
            if (tx != null) {
                tx.commit();
            }
        } finally {
            session.close();
        }
        return details;
    }

I am trying to have a generic Method for them and this is what I have written so far:

 public static <T> List<T> getDetails(Class<T> c, Class<T> b) {
        List<T> details = null;
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            Criteria cr = session.createCriteria(c);
            //am stuck on iteration of the map from Class T b
            details = cr.list();
            tx.commit();
        } catch (Exception asd) {
            log.debug(asd.getMessage());
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            session.close();
        }
        return details;
    }

How do I put up a generic Map onto the method?

EDIT: My Map values type can change I need to be able to put not just Integers but Strings as well and other types

Stanley Mungai
  • 4,044
  • 30
  • 100
  • 168

2 Answers2

1

To use generic map you should define your method to allow a Map with any type of object to pass in Value place of Map.

Your new method should look like this getDetails(Class<T> c,Map<String,?> params)

and Map Entry iterator should look like as below:

for (Map.Entry<String, Object> entry : params.entrySet()) {
                cr.add(Restrictions.eq(entry.getKey(), entry.getValue()));
 }
Raju Sharma
  • 2,496
  • 3
  • 23
  • 41
  • This does not work, had actually tried that. It returns `name clash: getDetails(Class,Map) and getDetails(Class,Map) have the same erasure` – Stanley Mungai Aug 20 '17 at 04:52
  • @ErrorNotFoundException are you writing new method , without removing old method? if it is then it will give the error as you mentioned., check the link for more on this https://stackoverflow.com/questions/1998544/method-has-the-same-erasure-as-another-method-in-type, you cannot make it is because Map and generic Map are same based on Map./ – Raju Sharma Aug 20 '17 at 05:04
  • Oh, sorry, I had to remove the first Method which was clashing with the first one. My bad. This actually Worked. Thanks. – Stanley Mungai Aug 20 '17 at 05:11
1

Just as easy as adding Map<? extends Object, ? extends Object>to your method's parameters list.

public static<T> List<T> getDetails(Class<T> c, Map<? extends Object, ? extends Object> params)

Another option would be adding two other parameter types:

private static <T, S, X> List<T> getDetails(Class<T> clazz, Map<S, X> map) {
    ...
    for (Map.Entry<S, X> entry : params.entrySet()) {
            cr.add(Restrictions.eq(entry.getKey(), entry.getValue()));
     }
    ...
  }

The new parameter Class<T> b can be removed, since it doesn't been used anywhere.

Shmulik Klein
  • 3,754
  • 19
  • 34