在EJB< - > JSF2应用程序中重用服务器和客户端上的实体

时间:2013-09-11 12:36:50

标签: oop java-ee ejb client-server

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

  1. 服务器编写为EJB并管理数据(创建,读取,更新,删除)。它使用JPA连接数据库。
  2. 客户端是使用JSF2编写的,它是一个简单的gui,它使用远程EJB来管理数据。
  3. 两者(客户端和服务器)都在不同的服务器上运行。
  4. 要使用EJB,客户端需要具有EJB接口和实体(需要实体来反序列化EJB返回的对象)。
  5. 服务器端实体已获得JPA注释。
  6. 客户端实体需要与服务器相同,但不需要JPA注释。
  7. 两个(客户端和服务器)实体应该位于同一个jar库中,因为它更容易维护。
  8. 这些是我解决问题的建议:

    1. 创建仅包含实体接口的库,以便客户端和服务器能够以他们需要的方式实现它。
    2. 创建包含没有JPA注释的实体实现的库(服务器需要使用xml而不是注释)。
    3. 什么是最佳解决方案?我的解决方案是否正确我会很感激任何建议。

1 个答案:

答案 0 :(得分:2)

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

或者,您可以为每个实体创建DTO。每个实体可能有许多DTO(例如,包含论坛帖子的所有字段的完整DTO,仅包含标题,日期,作者的摘要DTO)。您可以使用Commons BeanUtils之类的实用程序反复地从实体复制到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 - 多年来都没有使用它)。 / p>

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