2009-04-29 198 views
11

我有一個參數化的hibernate dao,它執行基本的crud操作,並且當參數化時用作委託來完成給定dao的基本crud操作。從泛型T派生類

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

我希望能夠在運行時創建Hibernate的標準查詢在T派生類,使得:

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

我知道:

T.getClass() 

不存在,但有什麼辦法在運行時從T派生正確的類對象嗎?

我已經看過泛型和反射,但還沒有拿出一個合適的解決方案,也許我失去了一些東西。

謝謝。

回答

17

您可以將該類作爲構造函數參數傳遞。

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; 
    } 

    // .... 

} 
+0

是的,這是一個解決方案,我有。如果可能的話,我寧願能夠從T派生類,而不添加類依賴。 – bowsie 2009-04-29 11:52:03

+8

@bowsie:我明白你的痛苦。不幸的是,編譯器完成刪除T的所有痕跡。它被稱爲類型擦除:http://java.sun.com/docs/books/tutorial/java/generics/erasure.html – 2009-04-29 12:07:18

7

有怎樣的方式使用反射來找出類型參數Tclass

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

這裏就是這樣,我如何使用它:

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(); 
    } 

} 

我想這只是當您的ConcreteEntityDaoHibernateDao<ConcreteEntity,...>的直接超類時有效。

我發現在這裏:www.greggbolinger.com/blog/2008/04/17/1208457000000.html