Reputation: 147
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
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