【问题标题】:Can't Serialize Session Beans - Warning thrown无法序列化会话 Bean - 引发警告
【发布时间】:2012-07-18 04:40:16
【问题描述】:

我正在使用 EclipseLink (JPA 2.0) 在 netbeans 中运行 JSF + Primefaces + tomcat 6.0.32 的环境。

我的应用程序运行良好,但每次运行它时,我都会收到很多警告说不能序列化我的会话 bean,并为每个会话 bean 显示这样的块:

18-jul-2012 23:05:46 org.apache.catalina.session.StandardSession writeObject
ADVERTENCIA: No puedo serializar atributo de sesión facturacionController para sesión 62A53325838E1E7C6EB6607B1E7965E6
java.io.NotSerializableException: org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
    ... and so on...

问题是我的会话 bean 已经实现了 Serializable。 那么我能做些什么来解决这个问题呢?

谢谢!

---- 添加信息 07/20/2012 ----

我从会话 bean 中引用 EntityManager 的唯一一点是当我在 getter 属性中创建 jpaController 时,如下所示:

private JpaController getJpaController() {
    if (jpaController == null) {
        jpaController = new JpaController(Persistence.createEntityManagerFactory("myPersistenceUnit"));
    }
    return jpaControllerPedido;
}

那是因为我这样定义了 jpaController 构造函数:

public JpaController(EntityManagerFactory emf) {
    this.emf = emf;
}

【问题讨论】:

  • 请发布完整的 StackTrace。此外,也许this post 可以帮助您解决问题:ava.io.NotSerializableException: org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl (JPA with JSF)。
  • 您在会话范围的 JSF 托管 bean 中保留对 EntityManager 的引用的确切原因是什么?您是在尝试模拟有状态的 EJB 吗?
  • 感谢您的回复!,我不是想总结一个有状态的 EJB,当我在 getter 属性中创建 JPA 控制器时,我有一个参考。我在问题中添加了代码。

标签: jsf jpa session-bean


【解决方案1】:

你只添加这个:

transient EntityManagerFactory entityManagerFactory;

但是如果有任何其他实现 entityManagerFactory 的对象,这个对象也必须定义为。例如

transient static final EntityManagerFactory emf = Persistence.createEntityManagerFactory("porpertiesConexion");
transient EntityManager em;    


public void beginTransaction() {           
    em = emf.createEntityManager();  //
        //code....
} 

【讨论】:

    【解决方案2】:

    使类可序列化并不意味着其中的所有内容都可以序列化。您类中的所有引用(依赖项/属性),它们本身应该是可序列化的,并且它们的引用也是可序列化的。

    根据上述异常,您的会话 bean 似乎引用了不可序列化的 EntityManagerFactoryImpl 对象,因此出现错误。

    要解决这个问题,您可以将其定义为transient,而不是对其进行序列化,但唯一的问题是在反序列化期间您必须手动构建对象或分配引用。

    我建议在Serilization 上查看这篇文章。

    如何解决这个问题,我不做 JPA,所以无法判断是否有相同的序列化类,

    要解决它,请将引用定义为transient

    transient EntityManagerFactory entityManagerFactory
    

    并在反序列化挂钩方法中手动将引用分配回 bean,如下所述。

    private void readObject(java.io.ObjectInputStream stream)
            throws java.io.IOException, ClassNotFoundException
        {
            stream.defaultReadObject();
    
            // assign reference manually.
            this.entityManagerFactory =  //get from factory;
        }
    

    希望这会有所帮助!!!!

    【讨论】:

    • 感谢您的回复!我不认为在反序列化钩子方法中手动将引用分配回 bean 是一个好主意,我更喜欢让 JSF 处理这个问题。我认为它必须是您所说的 EntityManager 引用,可能在我在问题中显示的 jpaController 的 getter 属性中。
    猜你喜欢
    • 2016-09-02
    • 1970-01-01
    • 2017-08-29
    • 2013-02-26
    • 2015-07-31
    • 2012-05-07
    • 2013-09-24
    相关资源
    最近更新 更多