Mohammad Ashfaq
Mohammad Ashfaq

Reputation: 147

Get Generic list using Hibernate criteria

I have two classes State and City and two separate DAO objects to perform CRUD operation on State and City.

List<Chapter> getAllStates();
int save(State state);

and

List<City> getAllCities();
int save(Citycity);

I can have many more classes which need to have their own DAOs.

I want to use generic so that I will have only one DAO object which can perform CRUD on any given type.

I am trying.

@Override
    public <T> List<T> getAllItems() {
        return sessionFactory.getCurrentSession().createCriteria<T>().list();
    }

gives the following error:

Syntax error on token "(", Expression expected after this token"

and

@Override
    public <T> List<T> getAllItems() {
        return sessionFactory.getCurrentSession().createCriteria(T).list();
    }

which shows

T cannot be resolved to a variable

Is there a way to achieve what I want?

If yes please help me with example or correcting my code.

Thanks

Upvotes: 2

Views: 1641

Answers (1)

Naros
Naros

Reputation: 21113

There are a couple solutions to your problem. Using your example, the easiest would be to simply pass the class type as a method argument:

public <T> List<T> findAll(Class<T> clazz) {
   return sessionFactory.getCurrentSession().createCriteria(clazz).list();
}

But if you're looking for a slightly more elegant way, it would require the involvement of a generic-based class and interface to achieve this:

public interface GenericDAO<T> {
    List<T> findAll();
}

public class GenericDAOImpl<T> implements GenericDAO<T> {
    private final Class<T> entityClass;
    /* others stuff */

    public GenericDAOImpl() {
      ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass();
      this.entityClass = (Class<T>)type.getActualTypeArguments()[0];
    }

    public List<T> findAll() {
       return sessionFactory().getCurrentSession().createCriteria(entityClass).list();
    }
}

The above allows you to infer the type argument from the interface stub and then use that captured type in methods inside the implementation class.

Upvotes: 2

Related Questions