使用JPA实体的最佳做法是什么?
由于JPA实体只是POJO,是否认为将该对象用作系统其他部分的数据对象是合适的,还是应该将它们转换为另一个数据对象?
在与JPA无关的系统其他部分使用JPA实体POJO是否可以接受?
答案 0 :(得分:8)
实体现在自己能够传输自己的数据,为什么还要将它们转换成其他东西呢?换句话说,我倾向于同意DTO an AntiPattern in EJB 3.0:
EJB 3.0之前EJB规范中Entity Beans的重量级特性导致使用Data Transfer Objects(DTO)等设计模式。 DTO成为轻量级对象(首先应该是实体bean本身),用于跨层发送数据。 [...]
EJB 3.0规范使Entity bean模型与Plain old Java object(POJO)相同。使用这个新的POJO模型,您将不再需要为每个实体或一组实体创建DTO。如果要在整个层中发送EJB 3.0实体,只需实现
java.io.Serialiazable
。
答案 1 :(得分:6)
这是一个很好的问题。
通过将JPA实体类公开给系统的其余部分,您可以将持久性机制和对象公开给db mapping。您无法控制这些对象的CRUDded和托管方式。通过打破持久性封装,更改可能会对系统的其余部分产生连锁反应。
系统持久性的未来变化可能是不可能的,尴尬的,有限的和/或有风险的。示例:您可能需要针对性能和/或可伸缩性进行优化。这可能需要缓存,数据库架构更改,非RDBMS使用,多个数据库。封装还有助于减少迁移到未来的数据库模式。
所以权衡是:
如果不能接受频繁的系统范围变更,则可能需要第一个选项 - 例如第三方正在访问您的数据。或许您已经决定采用3层架构:GUI,业务逻辑,持久性。
如果您拥有灵活的开发流程并控制整个系统并接受可能需要进行系统范围更改的事实,则第二个选项是可以的。
答案 2 :(得分:3)
这取决于你对“其他部分”的意思。由于您的JPA实体必须以某种方式与您的系统相关,为什么不使用它们,因为它们已经存在。重要的是,你没有使用同一个类来解决两个完全不同的问题(这可能表明设计不好或只是一个非常大的系统)。其他一切可能最终会在你不同的POJO之间无休止地映射。
例如用户登录。为基于Web的登录创建单独的UserLoginForm Bean可能是常见的详细Java实践,但请考虑这一点:
您已经拥有数据库中的用户JPA实体(因此也就是用户POJO)(它具有用户名,密码哈希,地址以及可能存储的其他内容)。您也可以在Web表单的登录请求中使用完全相同的对象(一些像Spring这样的框架会立即映射它)。创建一个空的User对象,设置用户名和散列密码,并通过示例创建一个JPA Query。如果该查询只返回一个结果,则登录有效,您可以将加载的用户对象存储在会话中。