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

Java GWT中的Hibernate序列化异常,但Eclipselink中没有,java,hibernate,gwt,jpa,eclipselink,Java,Hibernate,Gwt,Jpa,Eclipselink,我正在使用eclipselink JPA实现(实体)和表示层上的GWT2.0框架。 一切正常。但当我将我的JPA实现更改为Hibernate时,当我传递实体bean时,我在GWT层得到序列化/反序列化异常,但在eclipselink JPA上没有问题。 到底发生了什么?Hibernate也是JPA和eclipselink的实现,为什么它们的行为不同 在Hibernate上解决此异常应该怎么做?使用Hibernate4gwt 哪个JPA实现更适合GWT 关于我建议阅读整篇文章,它很好地解释了为什么

我正在使用eclipselink JPA实现(实体)和表示层上的GWT2.0框架。 一切正常。但当我将我的JPA实现更改为Hibernate时,当我传递实体bean时,我在GWT层得到序列化/反序列化异常,但在eclipselink JPA上没有问题。 到底发生了什么?Hibernate也是JPA和eclipselink的实现,为什么它们的行为不同

在Hibernate上解决此异常应该怎么做?使用Hibernate4gwt

哪个JPA实现更适合GWT


关于

我建议阅读整篇文章,它很好地解释了为什么增强类(无论您使用的是代理还是编织)对于GWT来说是“有问题的”:

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

当你拿一个物体并转动它时 在休眠对象中,该对象 现在增强为持久性。那个 坚持并不是没有一些 对象的检测类型。 在Hibernate的情况下 Javassist库实际上取代了 并重写这些的字节码 由持久实体生成的对象 冬眠的魔法工作<这是什么 GWT RPC的方法是 对象已准备好进行传输 通过电线,它实际上不是 与编译器认为的对象相同 就要调职了,所以什么时候 正在尝试反序列化GWT RPC 机制不再知道 类型为,并拒绝对其进行反序列化

事实上,如果你更深入地观察 先前对
loadAccounts()
的调用, 然后走进
RPC.invokeAndEncodeResponse()
方法, 你会看到我们现在的目标 尝试反序列化现在已经变得非常困难 帐户类型的
ArrayList
他们的
java.util.Set
记录 由
org.hibernate.collection.PersistentSet
类型

类似的问题也会出现在其他方面 持久性框架,如JDO或 JPA,用于谷歌应用程序引擎

因此,我的理解是,这不是一个特定于Hibernate的问题,您也可能会遇到其他JPA实现的问题,包括EclipseLink(您不必使用编织,但会错过延迟加载或获取组等功能)

本文提出了几种解决问题的集成策略:

  • 使用数据传输对象(argh!)
  • 用于Hibernate集成(先前方法的改进版本)
  • 使用(以前称为Hibernate4Gwt)进行Hibernate集成
它还讨论了它们的优缺点,看看吧

总而言之。。。 首先,我不认为GWT有一个“最佳”的JPA实现,它们都面临着相同的问题。如果您可以在没有延迟加载的情况下生活,那么没有
编织的EclipseLink可能会更简单。但是你会不知何故把头埋在沙子里,问题就在那里,你将无法使用另一个实现

第二,尽管前两个“集成策略”将适用于任何JPA提供商,但Hibernate是Gilead(but)目前支持的唯一JPA实现

选择你的毒药:)

另见

另一个想法:自定义字段序列化程序

示例:MyClass的一个成员映射为与YourClass的一对多关系:

public class MyClass implements Serializable {

    private List<YourClass> yourClassList;

    @OneToMany(mappedBy="myClass")
    public List<YourClass> getYourClassList {
        return yourClassList;
    }
}
公共类MyClass实现可序列化{
私有列表你的类列表;
@OneToMany(mappedBy=“myClass”)
公共列表getYourClassList{
返回你的类列表;
}
}
Hibernate将使用的精确实现可能是PersistentBag,由于Pascal提到的原因,它是不可序列化的。但是GWT提供了自定义字段序列化程序来控制序列化。它看起来像这样

public class MyClass_CustomFieldSerializer {
   public serialize(SerializationStreamWriter writer, MyClass instance) throws SerializationException {
       writer.write(new ArrayList<YourClass>(instance.getYourClassList());
   }
}
公共类MyClass\u CustomFieldSerializer{
公共序列化(SerializationStreamWriter编写器,MyClass实例)引发序列化异常{
write(新的ArrayList(instance.getYourClassList());
}
}
这里的优势是不必与Gilead/Dozer/更多的外部库发生冲突