GWT中的Hibernate序列化异常,但Eclipselink没有

3

我正在使用eclipselink JPA实现(Entity)和GWT 2.0框架在presentation layer上,一切运作正常。但是当我将我的JPA实现更改为Hibernate时,在传递entity beans时,我会在GWT层上遇到Serialization/Deserialization异常,但在eclipselink JPA中则没有问题。

真正发生了什么?Hibernate是JPA的一个实现,eclipselink也是,为什么它们会有所不同?

为解决Hibernate上的这个异常,我应该怎么做?是否可以使用Hibernate4gwt?

哪个JPA实现更适合用于GWT?

致敬

2个回答

7
我建议阅读整篇 使用 GWT 和 Hibernate 论文,它很好地解释了为什么增强类(无论你是否使用代理 编织)对于 GWT 是“有问题的”。

为什么当Hibernate对象到达浏览器世界时无法理解

...

当你将一个对象转换成Hibernate对象时,该对象现在被增强为持久化对象。这种持久性不是没有对对象进行仪器化。在Hibernate的情况下,Javassist库实际上替换并重写了这些对象的字节码,使它们成为持久化实体,以使Hibernate魔法生效。对于GWT RPC来说,这意味着当对象准备好通过网络传输时,它实际上不是编译器认为要传输的相同对象,因此在尝试反序列化时,GWT RPC机制不再知道类型并拒绝反序列化它

事实上,如果您深入查看之前对loadAccounts()的调用,并进入RPC.invokeAndEncodeResponse()方法,您会发现我们正在尝试反序列化的对象现在已经变成了一个Account类型的ArrayList,其中包含其记录的java.util.Set被替换为org.hibernate.collection.PersistentSet类型。

类似的问题也会出现在其他持久化框架中,例如在Google App Engine上使用的JDO或JPA

...

我的理解是,这不是一个Hibernate特定的问题,你可能也会遇到其他JPA实现的麻烦,包括EclipseLink {{link1:如果使用静态或动态编织}}(你不强制使用编织,但这样你就会错过像懒加载或获取组这样的功能)。

该论文提出了几种集成策略,允许解决这些问题:

  • 使用数据传输对象(呃!)
  • 使用{{link2:Dozer}}进行Hibernate集成(前一方法的改进版本)
  • 使用{{link3:Gilead}}(以前称为Hibernate4Gwt)进行Hibernate集成

它还讨论了它们的优缺点,请查看。

总之...

首先,我认为没有适用于GWT的“最佳”JPA实现,它们都面临相同的问题。如果你可以不使用延迟加载,那么没有织入的EclipseLink可能会更简单。但是你会有些掩耳盗铃,这个问题确实存在,你将无法使用另一个实现。
其次,虽然前两种“集成策略”可以与任何JPA提供者一起使用,但Hibernate是目前唯一由Gilead支持的JPA实现(但计划支持OpenJPA和EclipseLink)。
选择你的毒药:)
另请参阅:
- Gilead Presentation - GWT Developer Forum

0
另一个想法:自定义字段序列化器。
例如:MyClass具有与YourClass的一对多关系中映射的成员:
public class MyClass implements Serializable {

    private List<YourClass> yourClassList;

    @OneToMany(mappedBy="myClass")
    public List<YourClass> getYourClassList {
        return yourClassList;
    }
}

Hibernate 可能会使用 PersistentBag 进行精确实现,但由于 Pascal 提到的原因,它不可序列化。但是 GWT 提供了自定义字段序列化器来控制序列化。它看起来会像这样。

public class MyClass_CustomFieldSerializer {
   public serialize(SerializationStreamWriter writer, MyClass instance) throws SerializationException {
       writer.write(new ArrayList<YourClass>(instance.getYourClassList());
   }
}

这里的优点在于不必处理Gilead/Dozer/更多的外部库。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接