我有类似的问题和疑虑,关于如何在Web服务返回的Hibernate实体和数据传输对象之间进行转换,如本问题所述:
Is using data transfer objects in ejb3 considered best practice
这里提到的一个因素是,如果域模型发生变化,一组DTO将在Web服务的情况下保护消费者。
即使它似乎会为我的项目添加大量代码,但这种推理似乎很合理。
是否有一个好的设计模式可用于将Hibernate实体(实现接口)转换为实现相同接口的DTO?
因此假设以下两个实现'Book',我需要将BookEntity.class转换为BookDTO.class,以便我可以让JAXB序列化并返回。
同样,这整个前景对我来说似乎很可疑,但如果有很好的模式来帮助处理这种转换,我很乐意获得一些见解。
是否有一些有趣的方式通过反射进行转换?还是我没想到的“建设者”模式?
我应该忽略DTO模式并传递实体吗?
答案 0 :(得分:17)
我应该忽略DTO模式 并传递实体?
我的偏好通常是“是”。我不喜欢为了建筑或图层纯度而创建的并行层次结构的想法。
DTO模式的最初原因是当将实体EJB传递给视图层时,EJB 1.0和2.0应用程序中的过度干扰。解决方案是将实体bean状态放入DTO。
通常用于创建DTO的另一个原因是禁止视图层进行修改。在这种情况下,DTO是不可变对象,没有任何行为。他们什么都不做,只是将数据传送到视图层。
我认为DTO是一种核心J2EE模式,它已成为一种反模式。
我意识到有些人不同意。我只是提出我的意见。这不是唯一的方法,也不一定是“正确”的方式。这是我的偏好。
答案 1 :(得分:14)
在DTO的所有快乐踢中都需要有逆向观点。
tl; dr - 它有时仍然有用。
DTO的优势在于您无需为域类添加数百个注释。
你从@Entity开始。还不错。但是你需要JAXB,所以你要添加@XMLElement等 - 然后你需要JSON,所以你要添加像@JsonManagedReference这样的东西,让杰克逊做正确的事情与关系,然后你添加等等等无限的。
很快你的POJO就不那么明了了。有时阅读“域驱动设计”。
此外,您可以“过滤”一些您不希望视图了解的属性。
答案 2 :(得分:5)
我们不应忘记实体对象在处于托管状态时不易处理。这使得他们传递给GUI形式存在问题。更确切地说,急切地处理子对象。这不能在会话之外完成,因为会导致异常。因此,他们要么必须从实体经理被驱逐(分离),他们必须转换为适当的DTO。除非cource有一种我不知道的模式,否则我很高兴知道。
答案 3 :(得分:4)
为了快速创建“外观相似”的DTO,没有一堆重复的获取/设置代码,您可以使用BeanUtils.copyProperties。该功能可帮助您快速将数据从DAO复制到DTO类。请记住,有多个公共库支持BeanUtils.copyProperties,但它们的语法不一样。
答案 4 :(得分:2)
我知道这是一个老问题,但我想我会添加一个答案,提供一个框架来帮助以防其他人正在解决这个问题。
我们的项目具有JAXB注释的POJO,它们与JPA注释的POJO分开。我们的团队正在讨论如何在两个对象(实际上是数据结构)之间移动数据的最佳方式。
以下是供人们考虑的选项:
我们发现并正在试验Dozer处理(1)相同名称,(2)XML映射和(3)自定义转换作为在两个POJO之间复制数据的方法。
到目前为止,它一直很容易使用。