【问题标题】:Object Serialization somehow initialise hibernate proxies对象序列化以某种方式初始化休眠代理
【发布时间】:2017-01-28 04:23:06
【问题描述】:

我有一个名为employees 的列表(List<Employee>) 由休眠(session.createQuery().list()) 返回,用于我的域employee。此列表的员工元素具有外键元素的代理,例如 department,它们由 employee.getDepartment() 获取。

但是当我这样做时:

{
                FileOutputStream fout = new FileOutputStream("d:\\addresss.ser");
                ObjectOutputStream oos = new ObjectOutputStream(fout);
                oos.writeObject(employees);
                oos.close();
                fout.close();


                ObjectInputStream ois= new ObjectInputStream(new FileInputStream("d:\\addresss.ser"));
                List<Employee> retrived=(List<Employee>)ois.readObject();
                ois.close();
            }

然后我得到的列表,即 retrived 具有完全初始化的员工元素,但实际列表 employees 没有完全初始化的元素。

问题,我需要了解retrieved 列表已初始化元素而实际列表employee 没有的序列化或反序列化过程中可能发生的情况。

我不能 100% 确定上述序列化是否不调用 getter/setter 方法,因此无法初始化代理。

注意我没有调用员工的 getter 来检查它是代理还是初始化,因为我知道调用 getter 会初始化代理。我只是使用 ecrise 调试检查变量进行检查。

另外,我在日志中看到的另一件事(部门初始化时):

System.out.println("class:"+((Employee)employees.get(0)).getDepartment().getClass().getSimpleName()); 
//prints: "Department_$$_jvstfcc_41"


  System.out.println("class:"+((Employee)retrived.get(0)).getDepartment().getClass().getSimpleName()); 
//prints: "Department"

一些信息: employee.hbm.xml 包含:

<many-to-one
            name="department"
                    column="department_id" 
        >

休眠版:4.3.4.Final

任何帮助将不胜感激。提前致谢。

【问题讨论】:

  • 请注意,返回像 Department_$$_jvstfcc_41 这样的名称的 object.getClass() 可能仍处于初始化状态。更多信息检查:object.getHandler().isUninitialized
  • 您使用哪个休眠版本?你可以发布你的映射吗?我用Hibernate 4.3.10和@ManyToOne做了一个小测试,序列化前后类名都一样。
  • 刚刚做了。您的班级名称类似于 Class 或 Class_$$_blabla ?
  • Class_$$_jvst875_0 和反序列化后同名。与 4.3.4.Final 相同
  • 做一件事,初始化后序列化。然后你会看到不同的类名。初始化使用 Hibernate.initialise(obj)。

标签: java hibernate serialization proxy


【解决方案1】:

序列化不调用getter/setter,也不调用构造函数。这是初始化 PersistenceCollection 的 Eclipse 调试器。

除非您有一些自定义序列化代码,否则集合将保持未初始化状态。

您可以尝试在代码中添加类似

System.out.println(Hibernate.isInitialized(retrived.get(0).getDepartments()));

它应该打印false

或在阅读和反对之前关闭您的会话。 Eclipse 调试器将在 value 列中显示类似 com.sun.jdi.InvocationException occurred invoking method. 的内容。

【讨论】:

  • 请查看更新,其中反序列化将代理类名转换为真实类名。
  • 请注意,除了部门之外没有部门,因此不存在 PersistenceCollection,存在 HibernateProxy。
猜你喜欢
  • 2010-09-25
  • 1970-01-01
  • 2013-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多