Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deriving Class from Generic T

I have a parameterized hibernate dao that performs basic crud operations, and when parameterized is used as a delegate to fulfil basic crud operations for a given dao.

public class HibernateDao <T, ID extends Serializable> implements GenericDao<T, ID>

I want to be able to derive Class from T at runtime to create criteria queries in Hibernate, such that:

public T findByPrimaryKey(ID id) {
    return (T) HibernateUtil.getSession().load(T.getClass(), id);
}

I know:

T.getClass()

does not exist, but is there any way to derive the correct Class object from T at runtime?

I have looked at generics and reflection but have not come up with a suitable solution, perhaps I am missing something.

Thanks.

like image 325
bowsie Avatar asked Apr 29 '09 11:04

bowsie


People also ask

What does T stand for in generics?

< T > is a conventional letter that stands for "Type", and it refers to the concept of Generics in Java. You can use any letter, but you'll see that 'T' is widely preferred. WHAT DOES GENERIC MEAN? Generic is a way to parameterize a class, method, or interface.

What is T type in C#?

T is called type parameter, which can be used as a type of fields, properties, method parameters, return types, and delegates in the DataStore class. For example, Data is generic property because we have used a type parameter T as its type instead of the specific data type. Note.

What is a class T?

In java <T> means Generic class. A Generic Class is a class which can work on any type of data type or in other words we can say it is data type independent.


2 Answers

You could have the Class passed as a constructor argument.

public class HibernateDao <T, ID extends Serializable> implements GenericDao<T, ID> {

    private final Class<? extends T> type;

    public HibernateDao(Class<? extends T> type) {
        this.type = type;
    }

    // ....

}
like image 188
Adam Paynter Avatar answered Oct 27 '22 14:10

Adam Paynter


There is the way how to figure out class of type argument T using reflection:

private Class<T> persistentClass = (Class<T>)
    ((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];

Here is the way how I use it:

public class GenericDaoJPA<T> implements GenericDao<T> {

    @PersistenceContext
    protected EntityManager entityManager;

    protected Class<T> persistentClass = figureOutPersistentClass();

    private Class<T> figureOutPersistentClass() {
        Class<T> clazz = (Class<T>)((ParameterizedType) (getClass().getGenericSuperclass())).getActualTypeArguments()[0];
        log.debug("persistentClass set to {}", clazz.getName());
        return clazz;
    }

    public List<T> findAll() {
        Query q = entityManager.createQuery("SELECT e FROM " + persistentClass.getSimpleName() + " e");
        return (List<T>) q.getResultList();
    }

}

I suppose this only works when your ConcreteEntityDao is a direct superclass of HibernateDao<ConcreteEntity,...>.

I've found it here: www.greggbolinger.com/blog/2008/04/17/1208457000000.html

like image 31
rdk Avatar answered Oct 27 '22 13:10

rdk