我需要从另一个Web应用程序调用远程无状态EJB,使用相同的glassfish(3.1最终版本)返回实体Bean(JPA 2 / Eclipselink)。通过依赖注入(@EJB)但实体变为null。我谷歌并发现它可能是可序列化问题。某处我发现了这个
TopLink要么修改实体类 (“编织”它们)在装载或替代品上 运行时的集合访问权限 能够检测到懒惰访问或 修改过的关系(没有 没有这个支持延迟加载的方法 或继承或使用代理 运行)。这让我们很开心 重点:你不应该使用 反射来访问实体,但是 只有通过它的商业方法。什么时候 weaved实体序列化了 服务器并在客户端上反序列化 没有相应的 实体编织,serialVersionUIDs 不会匹配作为计算 值包括类字段和 方法
所以我的应用程序需要DTO转换吗?
答案 0 :(得分:2)
你的意思是“但实体变为空”?你是否在远程SessionBean上调用一个方法并返回null,或者你回来并且它的关系为null的实体?
如果它是一个空关系,它可能是一个LAZY问题,如果你的关系是LAZY,并且没有被提取或访问,那么它将为null。您需要获取它,访问它或使其成为EAGER。
如果你回到null,那么其他的东西就错了。
答案 1 :(得分:2)
也许你受到Glassfish bug 16164的影响。
建议的解决方法是将此属性添加到persistence.xml:
<property name="eclipselink.weaving" value="false"/>
这解决了我的问题。
答案 2 :(得分:0)
当您尝试返回实体时,使用EclipseLink和Glassfish的远程EJB无法正常工作。
对于Hibernate,您需要在返回响应之前删除所有代理。 使用Hibernate,您需要在删除代理之前刷新并清除持久性上下文。如果未加载,则将null设置为attribute。您可以使用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