【问题标题】:How to re-attach an object to EclipseLink session after deserialization反序列化后如何将对象重新附加到 EclipseLink 会话
【发布时间】:2011-04-11 14:11:07
【问题描述】:

这是一个简单的 POC:

public void main(String[] args) {
    final String FILE_NAME = "c:/poc.ser";
    try {
        HotelJdo hotel = HotelJdoFinder.findById(430);
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(FILE_NAME));
        // serialize the object
        oos.writeObject(hotel);
        oos.close();
        // read the object in the same vm
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(FILE_NAME));
        HotelJdo hotel2 = (HotelJdo) ois.readObject();
        // this line throws an exception
        System.out.println("number of crs channels: " + hotel2.getAvailableRooms().size());
        ois.close();
    } catch (Exception e) {
        System.out.println("Unexpected exception:");
        e.printStackTrace();
    }
}

hotel2.getAvailableRooms() 查询配置为使用透明间接的房间列表。该调用会引发以下异常:

Exception [EclipseLink-7242] (Eclipse Persistence Services - 1.2.1.v20100428-r70
82): org.eclipse.persistence.exceptions.ValidationException
Exception Description: An attempt was made to traverse a relationship using indi
rection that had a null Session.  This often occurs when an entity with an unins
tantiated LAZY relationship is serialized and that lazy relationship is traverse
d after serialization.  To avoid this issue, instantiate the LAZY relationship p
rior to serialization.
        at org.eclipse.persistence.exceptions.ValidationException.instantiatingV
alueholderWithNullSession(ValidationException.java:975)
        at org.eclipse.persistence.internal.indirection.QueryBasedValueHolder.in
stantiate(QueryBasedValueHolder.java:83)
        at org.eclipse.persistence.internal.indirection.QueryBasedValueHolder.in
stantiate(QueryBasedValueHolder.java:75)
        at org.eclipse.persistence.internal.indirection.DatabaseValueHolder.getV
alue(DatabaseValueHolder.java:83)
        at org.eclipse.persistence.indirection.IndirectList.buildDelegate(Indire
ctList.java:237)
        at org.eclipse.persistence.indirection.IndirectList.getDelegate(Indirect
List.java:397)
        at org.eclipse.persistence.indirection.IndirectList.size(IndirectList.ja
va:726)

我知道我可以在序列化之前触发房间列表的初始化,但我想知道如何将 hotel2 对象重新附加到 EclipseLink 会话以便懒惰地获取房间列表。

【问题讨论】:

  • HotelJdoFinder 是一个执行 EclipseLink 查询的简单静态类

标签: java orm serialization eclipselink indirection


【解决方案1】:

要重新附加对象,您必须在访问其关系之前使用EntityManager.merge 方法。

类似:

hotel2 = em.merge(hotel2);

【讨论】:

  • 但是有EntityManager吗?这个findById 方法看起来很奇怪。
  • 如果使用 EclipseLink,我认为是这样,因为 EclipseLink 是一个 JPA 实现。我想 HotelJdoFinder 是用于访问数据库的自定义类型?
  • 像 Hibernate 一样,EclipseLink 有一个专有的 API。使用 EclipseLink 并不一定意味着使用 JPA。
  • 我在项目的类路径中没有 JPA,因此很遗憾我不能使用 EntityManager
猜你喜欢
  • 2018-01-08
  • 2011-02-13
  • 2019-07-10
  • 2016-03-11
  • 2013-03-14
  • 1970-01-01
  • 2014-12-12
  • 2021-06-14
  • 2019-07-23
相关资源
最近更新 更多