【问题标题】:Is it possible to have remotely managed entities?是否可以拥有远程管理的实体?
【发布时间】:2011-08-12 23:07:27
【问题描述】:

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

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


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

我关于这个一般主题的一个较早的问题:Java "equivalent" to CSLA

【问题讨论】:

  • 这与将分离的实体发送到客户端,修改它们,然后将它们发送回服务器进行重新连接和持久化有何不同?
  • @edalorzo 这就是我要说的,但是......“管理”是关键词。由于我的类是启用 JPA 的,所以在客户端上拥有一个 EntityManager 并添加(?)能力来“打包”我一直在使用的所有实体并将它们发送到,这不是“很好”吗?某个服务器上的 EntityManager 可以一次性妥善处理持久性事务?
  • 我认为我还没有理解您的情况。从我的角度来看,客户甚至不应该知道存在实体管理器之类的东西。通过业务接口正确公开,服务器可以在客户端要求时执行您建议的所有工作,并且实体甚至不会放弃服务器的安全性。在并发方面,每个客户端都有一个持久性上下文一定是一场噩梦。根据并发级别,每个客户端都可能在很短的时间内变成过时的缓存。你不觉得吗?

标签: java jpa devforce


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    你的想法很聪明。

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

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

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

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

    【讨论】:

    • 你的意思是,我应该向我的客户端公开EntityManager 在服务器上的重要方法?交易呢?我已经在示例中看到我必须自己控制事务:启动事务,做我的事情,然后提交事务。我想做我的事情,然后告诉 EntityManager 自动执行事务持久性所需的任何操作。
    • 做这件事的方法是从在 1 个事务中执行的服务器公开“业务服务”(例如:placeBid),并在用户的“屏幕流”时调用它已完成。维护从客户端打开的事务(因此可能)通常不是一个好主意。可以维护从客户端打开的跨越多个服务调用的事务,但实体在通过网络发送时总是会被分离而没有补救措施。
    猜你喜欢
    • 2014-11-01
    • 1970-01-01
    • 2021-10-11
    • 1970-01-01
    • 1970-01-01
    • 2021-09-18
    • 2017-06-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多