1

我对 JPA 不太熟悉,但我有这种情况:出于 KISS/DRY 的原因,我想在服务器和客户端(Java SE)上使用相同的类(阅读“代码”)。在我看来,一种可能的方法是EntityManager在客户端上有一个(特殊的?),它将对实体的请求传递给服务器,最后将所有实体传递回服务器以进行“批量持久操作”,其中类可以(重新)验证它们的数据,应用一些事务性操作(更新和填充),并通过 JPA 实现很好地持久化。

问题是:这可能吗?如何?(是否已经有解决方案?用“一些”代码解决这个问题是否简单?)


编辑:好的,让我为大家澄清几件事。我的背景是一个内部开发的应用程序框架,它使用所谓的通用持久性服务;即用于在单个事务中执行 CRUD 操作(任何表的每个操作一个服务)的服务,但由拦截这些操作并提供验证和(通常)复杂的业务规则(对其他表的更新)的类(服务内)支持, ETC。)。这是使用较旧的 Microsoft 产品实现的。现在转向 .NET,最近出现了类似工作但更高级的框架,如 DevForce 和 CSLA。DevForce 特别提供了我想在 Java 中做的事情(请参阅此页面上的“在客户端执行”段落,然后访问此页面以获得更好的概述)。

我关于这个一般主题的一个较老的问题:Java“等效于”CSLA

4

2 回答 2

1

我之前尝试过做类似的事情,也许只是分享一下我的发现(当时我使用的是 Hibernate + XFire for WS)

我相信你的想法在理论上是可行的。您需要做的只是序列化您的托管实体并将其发送给客户端。客户端反序列化并更新对象(当然,在客户端,它只是普通的 POJO,而不是托管实体)并将其发送回服务器。此时,Server 收到的对象只是一个分离的对象。您可以重新连接到会话(JPA/Hibernate 将为您进行那些乐观的并发检查),并进行持久化。

然而,它只适用于非常简单的 POJO。主要问题之一是,在 JPA(或几乎所有 ORM 框架)中,您在不同实体之间存在关系。例如,一个订单将与产品和帐户有关系,一个帐户将与客户有关系,客户将有地址列表....等。如果您在服务器端进行操作,因为延迟获取,关系,这通常很好在您访问它之前不会实际获取。但是,当您执行序列化时,它会成为一个难以解决的问题:大多数像 JAXB 这样的序列化解决方案只会递归地导航所有属性。结果是,您希望只向客户端发送 Order 对象,但最终您向客户端发送了大量数据。简单地告诉序列化程序不要序列化某些属性是行不通的,因为当对象被发回并将分离的 obj 重新附加到会话时,JPA/Hibernate 无法知道您是否只是忽略了关系或者您实际上是删除关系。当然,您仍然可以使用一些技巧,但所有这些都使这种方法难以采用,并且不再优雅。

于 2013-02-20T02:13:47.623 回答
0

你的想法很聪明。

但不可能按照你的建议去做。为什么不是?好吧,要回答这个问题,我们首先要了解“什么是托管实体”。

托管实体只不过是“缓存”实例。驻留在实体管理器内的实例。如果您通过网络将此实例发送到另一台机器,您正在序列化它,从而复制它:在远程服务器上创建另一个实例,当然,它不受管理(因为实体管理器甚至不知道它的存在) .

另一方面,可能存在“足够聪明”的东西来模拟实体管理器并透明地“管理”这个复制的实体,但这超出了 JPA 规范,您必须自己实现它(这似乎不是放轻松)。我不认为存在任何可靠的东西。

您的解决方案是从您的客户端显式地持久化、更新等(通过从服务器公开的方法)。

于 2011-08-13T00:08:44.933 回答