我正在尝试制作一个通用加载程序来 hibernate ,这就是问题所在。 我的 View 搜索对象数组并从 Controller 获取它, Controller 关闭 session 。 然后, View 需要使用对象信息和一些关系。由于我使用的是延迟加载,我尝试创建一个方法来加载该对象以及该方法传递的关系中的对象,问题是当我找到我正在搜索的对象时,我从该对象中调用 getId为了使对象加载。但 getId 会阻塞并且永远不会返回。
该方法的用法是:
LoadGeneric.load(myObject, Class1.class, Class2.class ...); myObejct 与 Class1 和 Class2 之间的所有关系都会加载对象,如果它们有关系的话,Class1 也会加载 Class2,依此类推...
这是迄今为止我的代码:
public class LoadGeneric
{
private static ArrayList<Object> objs = new ArrayList<Object>();
public static void load(Object objeto, Class... loadClasses) throws Exception
{
Session s = HibernateUtil.getSession();
try
{
if(objeto instanceof Collection)
{
Collection lo = (Collection) objeto;
for(Object ob : lo)
{
Method mGetId = findGetIdMethod(ob);
Object mid = mGetId.invoke(ob, (Object[]) null);
Integer id = (Integer) mid;
s.get(ob.getClass(), id);
LoadGeneric.invokeAllMethods(ob, loadClasses);
}
}
else
{
Method mGetId = findGetIdMethod(objeto);
Object mid = mGetId.invoke(objeto, (Object[]) null);
Integer id = (Integer) mid;
s.get(objeto.getClass(), id);
LoadGeneric.invokeAllMethods(objeto, loadClasses);
}
}
finally
{
objs.clear();
if(s.isOpen())
s.close();
}
}
//Find method like getIdNameOfTheClass
private static Method findGetIdMethod(Object object) throws Exception
{
Class co = object.getClass();
Method[] ml = co.getDeclaredMethods();
String[] name = co.getName().split("\\.");
String mn = "getid"+name[name.length-1];
mn = mn.toLowerCase();
for(Method m : ml)
{
if(m.getName().toLowerCase().contains( mn ))
return m;
}
throw new IllegalArgumentException("Erro ao achar método 'get id' do objeto, procurado algo como: "+mn);
}
//Find all methods that returns the class searched
private static List<Method> findGetObjectMethods(Object object,
Class searchedClass) throws Exception
{
ArrayList<Method> lm = new ArrayList<Method>();
Class co = object.getClass();
Method[] ml = co.getDeclaredMethods();
for(Method m : ml)
{
if(m.getReturnType().equals(searchedClass))
lm.add(m);
else if(m.getReturnType().equals(java.util.Collection.class))
{
System.out.println("****************************COLLECTION: "+m);
}
else
{
//System.out.println("TIPO DE RETORNO DESCARTADO: "+m);
}
}
return lm;
}
private static void invokeAllMethods(Object object, Class... classes) throws Exception
{
ArrayList<Method> lm = new ArrayList<Method>();
for(Class c : classes)
{
lm.addAll(findGetObjectMethods(object, c));
}
for(Method m : lm)
{
System.out.println("Invocando metodo: "+m);
Object o = m.invoke(object, (Object[]) null);
if(o != null)
{
findGetIdMethod(o).invoke(o, (Object[]) null);
objs.add(o);
if(objs.contains(o))
continue;
invokeAllMethods(o, classes);
}
}
}
}
PS:我所有返回 X 类的方法的类的名称都类似于 getIdNameOfXClass()
编辑:更改为新代码......我收到异常,我的 get id 方法找不到 getIdNameOfClass_$$_javassist......我认为 hibernate 给了我一个代理一个真实的物体,对吗?
最佳答案
解决了另一个 stackoverflow 帖子的问题 我所做的只是取消实体的代理
SessionImpl imp = (SessionImpl) session;
o = imp.getPersistenceContext().unproxyAndReassociate(o);
关于java - 使用 hibernate 持久抛出的反射调用方法 object.getId() 抛出lazyInitializeException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9033566/