3

几周前我开始学习 EJB,我对如何在客户端和服务器端重用实体类有疑问。假设我们有 CRUD 应用程序。

  1. 服务器以 EJB 形式编写并管理数据(创建、读取、更新、删除)。它使用 JPA 连接数据库。
  2. 客户端是使用 JSF2 编写的,它是一个简单的 gui,它使用远程 EJB 来管理数据。
  3. 两者(客户端和服务器)都在不同的服务器上工作。
  4. 要使用 EJB,客户端需要有 EJB 接口和实体(需要实体来反序列化 EJB 返回的对象)。
  5. 服务器端实体有 JPA 注释。
  6. 客户端实体需要与服务器相同,但不需要 JPA 注释。
  7. (客户端和服务器)实体都应该在同一个 jar 库中,因为它更易于维护。

这些是我解决问题的建议:

  1. 创建仅包含实体接口的库,以便客户端和服务器可以以他们需要的方式实现它。
  2. 创建包含没有 JPA 注释的实体实现的库(服务器将需要使用 xml 而不是注释)。

什么是最好的解决方案?我的解决方案正确吗?我将不胜感激任何建议。

4

1 回答 1

2

如果您信任客户端,或者如果您不关心是否有任何 JPA 注释泄漏到客户端,则可以将 JPA 实体用作数据传输对象 (DTO)。警告:任何未被服务器获取的惰性托管关系对客户端都将不可用,可能会在序列化过程中导致异常,或者可能查询和序列化太多东西。(这是您的选择1)

或者,您可以为每个实体创建 DTO。每个实体可能有许多 DTO(例如,包含论坛帖子所有字段的完整 DTO,仅包含标题、日期、作者的摘要 DTO)。您可以使用Commons BeanUtils之类的实用程序来反射地从 Entity 复制到 DTO,而无需编写大量样板代码 ( dto.setTitle(entity.getTitle()); dto.setDate(entity.getDate()); ...)。在这种情况下,DTO 存在于单独的 JAR 中,由客户端和服务器共享,但实体存在于它们自己的部署单元中,并且对服务器来说是私有的。这是过去 EJB 1/2 最广为宣传的做法。(这与您的选项 2 有一些相似之处,但您将重用 DTO 而不是实体本身)

然后您可以将服务器公开为 WEB 服务或 REST 端点(JAX-WS 和 JAX-RS 使这非常容易)。通过适当的配置,甚至可以在客户端中重用 JPA bean。这具有与其他技术互操作的额外好处,但可能会很慢。

您的选项 2 也是可行的,但是您将增加维护 XML 部署描述符的开销(XDoclet 在这种情况下可能会有所帮助,如果它支持 JPA - 已经很多年没有使用它了)。

使用任何类型的远程处理时,请注意通信通常很昂贵。因此,远程调用应该尽可能粗粒度,并且数据交换尽可能少(因此上面提到了摘要 DTO)。

于 2013-09-11T14:44:10.407 回答