4

我需要从另一个具有相同 glassfish(3.1 最终版本)的 Web 应用程序调用远程无状态 EJB,它返回实体 Bean(JPA 2/Eclipselink)。我通过依赖注入(@EJB)在 Web 应用程序中获取 ejb 引用,但实体变为空。我用谷歌搜索,发现它可能是可序列化的问题。我在某个地方找到了这个

TopLink 要么在加载时修改实体类(“编织”它们),要么在运行时替换集合访问,以便能够检测延迟访问或修改的关系(如果没有这个或子类化或在运行时使用代理,就无法支持延迟加载)。这给我们带来了非常重要的一点:您不应该使用反射来访问实体,而只能通过其业务方法。当编织实体在服务器上序列化并在没有编织其相应实体的客户端上反序列化时,serialVersionUID 将不匹配,因为值的计算包括类字段和方法。

那么我需要在我的应用程序上进行 DTO 转换吗???

4

3 回答 3

2

“但实体变为空”是什么意思?您是调用远程 SessionBean 上的方法并返回 null,还是返回与关系为 null 的 Entity?

如果它是空关系,则可能是 LAZY 问题,如果您的关系是 LAZY,并且尚未获取或访问,那么它将为空。您需要获取它、访问它或使其成为 EAGER。

如果您返回 null,则说明其他问题。

于 2011-04-11T13:47:47.247 回答
2

也许您受到Glassfish bug 16164的影响。

建议的解决方法是将此属性添加到 persistence.xml:

<property name="eclipselink.weaving" value="false"/>

这解决了我的问题。

于 2011-07-11T20:27:00.120 回答
0

当您尝试返回实体时,使用 EclipseLink 和 Glassfish 的远程 EJB 无法正常工作。

Hibernate 也一样,您需要在返回响应之前删除所有代理。使用 Hibernate,您需要在删除代理之前刷新和清除持久性上下文。如果未加载,则将 null 设置为属性。您可以使用 Java EE 拦截器使其工作。

但是,EclipseLink 不像 Hibernate 那样工作。即使您清除了持久性上下文,get / set on lazy 属性也会尝试获取。甚至是外部交易。

如果您设置属性名称="eclipselink.weaving" value="false",它将起作用,因为 EclipseLink 不会更改您的 POJO 类的字节码,但将始终获取 ManyToOne。因此它可以将数据库加载到内存中。

我解决这个问题的唯一方法是使用 DTO 或使用带有拦截器的 Hibernate。

编辑:您始终可以使用外部化接口覆盖实体序列化。按字段获取对象以确保惰性获取不适用。

Openjpa 似乎也默认使用编织方法。http://openjpa.apache.org/entity-enhancement.html

于 2015-01-04T17:42:15.670 回答