Java 在hibernate实体和数据传输对象之间转换的好模式是什么?

Java 在hibernate实体和数据传输对象之间转换的好模式是什么?,java,hibernate,design-patterns,entity,data-transfer-objects,Java,Hibernate,Design Patterns,Entity,Data Transfer Objects,对于如何在Hibernate实体和web服务返回的数据传输对象之间进行转换,我有过类似的问题和顾虑,如本问题所述: 这里提到的一个因素是,如果域模型发生变化,一组DTO将在web服务的情况下保护消费者 尽管它似乎会为我的项目添加大量代码,但这种推理似乎是合理的 有没有一种好的设计模式可以用来将Hibernate实体(实现接口)转换为实现相同接口的DTO 因此,假设下面两个都实现了“Book”,我需要将BookEntity.class转换为BookDTO.class,以便让JAXB序列化并返回

对于如何在Hibernate实体和web服务返回的数据传输对象之间进行转换,我有过类似的问题和顾虑,如本问题所述:

这里提到的一个因素是,如果域模型发生变化,一组DTO将在web服务的情况下保护消费者

尽管它似乎会为我的项目添加大量代码,但这种推理似乎是合理的

有没有一种好的设计模式可以用来将Hibernate实体(实现接口)转换为实现相同接口的DTO

因此,假设下面两个都实现了“Book”,我需要将BookEntity.class转换为BookDTO.class,以便让JAXB序列化并返回

再一次,整个前景对我来说似乎是可疑的,但如果有好的模式来帮助处理这种转换,我很想得到一些见解

是否有一些有趣的方法可以通过反射进行转换?还是一个我没想到的“建设者”模式

我应该忽略DTO模式并传递实体吗

我应该忽略DTO模式吗 并传递实体

我的偏好通常是“是”。我不喜欢仅仅为了架构或层纯度而创建并行层次结构的想法

DTO模式的最初原因是EJB1.0和2.0应用程序在将实体EJB传递到视图层时存在过多的聊天。解决方案是将实体bean状态放入DTO中

创建DTO通常给出的另一个原因是禁止视图层进行修改。在这种情况下,DTO是不可变的对象,没有任何行为。它们只将数据传送到视图层

我认为DTO是一种核心J2EE模式,它已经成为一种反模式


我知道有些人会不同意。我只是提出我的意见。这不是唯一的方法,也不一定是“正确”的方法。这是我的偏好。

在DTO的所有快乐踢腿中,需要有一种相反的观点

tl;博士-它有时仍然有用

DTO的优点是不必向域类添加大量注释

您可以从@Entity开始。还不错。但是接下来你需要JAXB,所以你需要添加@XMLElement等,然后你需要JSON,所以你需要为Jackson添加@JsonManagedReference等东西,以便对关系做正确的处理,然后你无限期地添加等等

很快你的POJO就不再那么简单了。找个时间读一下“领域驱动设计”


此外,您可以“过滤”一些不希望视图知道的属性。

我们不应该忘记,实体对象处于托管状态时不容易处理。这使得它们传递到GUI表单有问题。更准确地说,子对象被急切地处理。这不能在会话外完成,因此会出现异常。因此,它们要么必须从实体管理器中逐出(分离),要么必须转换为适当的DTO。除非有一个我不知道的模式,否则我很乐意知道。

要快速创建“相似”的DTO,而不需要大量重复的get/set代码,您可以使用。该函数帮助您快速地将数据从DAO复制到DTO类。请记住,支持BeanUtils.copyProperties的公共库不止一个,但它们的语法不同。

我知道这是一个老问题,但我想我会添加一个答案,提供一个框架以帮助其他人解决此问题

我们的项目有JAXB注释的POJO,它与JPA注释的POJO是分开的。我们的团队正在讨论如何最好地在两个对象(实际上是数据结构)之间移动数据

以下是供人们考虑的一个选项:

我们发现并正在试验哪些方法可以处理(1)相同的名称,(2)XML映射和(3)自定义转换,作为在两个POJO之间复制数据的方法


到目前为止,它非常容易使用

我通常也拒绝实现DTO——这还不够。我确实实现了DAO类,并使用Hibernate的工具从数据库生成/反向工程模型类。这是一个好东西。我发帖的最初希望是,有一种有趣或有见地的方法可以在共享我以前从未遇到过的接口的实体和dto之间进行转换。但我确信,我不应该为了保持层与层之间的分离而为我的服务增加复杂性。谢谢我认为,如果您对整个堆栈拥有完全控制权,那么是的,这是有效的。然而,让两个或多个UI使用您的服务并且不分离层是危险的。如果您去更改发送给他们的对象,将中断他们对您的服务的调用。您不能期望服务的所有实现者在您更改层时更新其代码。因此,层分离的核心原因是,但每个上下文都是不同的。您需要首先了解这一点。@duffymo:DTO对象将使您更容易更改接口。当然,如果您的接口和相关应用程序的数量很少,您可以管理它,并且没有足够的理由进行更改。但是,如果您有许多接口。。。幸运的是,您的转换将花费大量时间。不传递Hibernate对象的另一个原因(如问题中所述)是您可以仅使用所需的属性简化对象。它将有助于节省一些带宽,在某些情况下还可以减少解析请求/响应的工作量。当然,也不必在“帮助”周围传输Hibernate属性。