我曾經需要類似的東西,我不得不使用反射來解決它。在我的情況下,我使用hql來檢索記錄。另外,這是我爲加載記錄定義爲延遲加載而創建的一種方法,因此您可能需要修改第一個方法以便不查找FetchType.LAZY屬性,並始終無論如何都可以獲取它。
我建立的方法之一將「準備」懶取。基本上有兩種方法:在@ManyToOne上使用hql上的「left join fetch」,在@OneToMany和@ManyToMany上使用hibernate.initialize()。
所以,這第一個方法返回一個字符串,其中包含hql所需的「left john fetch」es,並且還構建了一個nToMany字段的列表,該字段必須在執行查詢後由Hibernate.initialize()調用。
private String buildLazyFetch(Class<? extends GenericEntity> entityClass, List<String> nToManyFields) {
String lazyFetches = new String();
lazyFetches += " fetch all properties ";
// iterate through all fields looking for lazy loaded relationships
for (Field f : entityClass.getDeclaredFields()) {
ManyToOne manyToOne = f.getAnnotation(ManyToOne.class);
if (manyToOne != null) {
if (manyToOne.fetch().equals(FetchType.LAZY)) {
lazyFetches += " left join fetch t." + f.getName() + " ";
}
}
OneToMany oneToMany = f.getAnnotation(OneToMany.class);
if (oneToMany != null) {
if (oneToMany.fetch().equals(FetchType.LAZY)) {
nToManyFields.add(f.getName());
}
}
ManyToMany manyToMany = f.getAnnotation(ManyToMany.class);
if (manyToMany != null) {
if (manyToMany.fetch().equals(FetchType.LAZY)) {
nToManyFields.add(f.getName());
}
}
}
return lazyFetches;
}
並執行HQL後,致電:
private void lazyFetchNToMany (List<String> nToManyFields, GenericEntity entity) {
for (String field : nToManyFields) {
try {
Hibernate.initialize(BeanUtils.getProperty(entity, field));
} catch (HibernateException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
我明白這不是正是你所期待的,但它可能會幫助你的情況下,你沒有找到你想要的解決方案
這不是一個選項。這棵樹很複雜,只有一個我想解決整個事情的例子。 Hibernate適合99%的賬單,但有一些邊緣情況需要加載和緩存複雜圖形的分離副本。如果沒有其他人對此感到困擾,那麼當我完成後,我只需要去反射路線並在這裏發佈代碼。 – Nim
您可以嘗試從Hibernate中提取運行時配置,因爲該配置已包含獲取所有引用所需的全部信息。當我用Hibernate 3.5試過這個時,我很快遇到了私人類/領域,這太難了,但也許API爲4.x打開。 –
@Nim:你能找到問題的解決方案嗎?我也面臨這個問題。 –