在休眠实体和数据传输对象之间进行转换的好模式是什么?
对于如何在 Hibernate 实体和 Web 服务返回的数据传输对象之间进行转换,我也有类似的问题和担忧,如本问题中所述:
这里提到的因素之一是,如果域模型发生变化,一组 DTO 将在 Web 服务的情况下保护消费者。
尽管看起来它会向我的项目添加大量代码,但这个推理似乎是合理的。
是否有一个好的设计模式可以用来将 Hibernate 实体(实现接口)转换为实现相同接口的 DTO?
因此,假设以下两个实现“Book”,我需要将 BookEntity.class 转换为 BookDTO.class,以便我可以让 JAXB 序列化并返回。
同样,这整个前景对我来说似乎是可疑的,但如果有好的模式可以帮助处理这种转换,我很想获得一些见解。
也许有一些有趣的方式通过反射进行转换?或者我没有想到的“构建者”模式?
我应该忽略 DTO 模式并传递实体吗?
I have had similar questions and concerns as to how to convert between Hibernate entities and data transfer objects to be returned by a web service as are discussed in this question:
Is using data transfer objects in ejb3 considered best practice
One of the factors mentioned here is that if the domain model changes, a set of DTOs will protect consumers in the case of a web service.
Even though it seems like it will add a substantial amount of code to my project, this reasoning seems sound.
Is there a good design pattern that I can use to convert a Hibernate entity (which implements an interface) to a DTO that implements the same interface?
So assuming both of the following implement 'Book', I would need to convert a BookEntity.class to a BookDTO.class so that I can let JAXB serialize and return.
Again, this whole prospect seems dubious to me, but if there are good patterns out there for helping to deal with this conversion, I would love to get some insight.
Is there perhaps some interesting way to convert via reflection? Or a 'builder' pattern that I'm not thinking of?
Should I just ignore the DTO pattern and pass entities around?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我的偏好通常是“是”。我不喜欢仅仅为了架构或层纯度而创建并行层次结构的想法。
DTO 模式的最初原因是,在将实体 EJB 传递到视图层时,EJB 1.0 和 2.0 应用程序中的过多信息。解决方案是将实体 bean 状态放入 DTO 中。
创建 DTO 的另一个原因通常是禁止视图层进行修改。在这种情况下,DTO 是不可变的对象,没有任何行为。它们除了将数据传送到视图层之外什么也不做。
我认为 DTO 是一种核心 J2EE 模式,但它已成为一种反模式。
我意识到有些人会不同意。我只是提出我的意见。这不是唯一的方法,也不一定是“正确”的方法。这是我的偏好。
My preference is usually "yes". I don't like the idea of parallel hierarchies created just for the sake of architectural or layer purity.
The original reason for the DTO pattern was excessive chattiness in EJB 1.0 and 2.0 apps when passing entity EJBs to the view tier. The solution was to put the entity bean state into a DTO.
Another reason that's usually given for creating DTOs is to prohibit modification by the view layer. DTOs are immutable objects in that case, with no behavior. They do nothing but ferry data to the view layer.
I would argue that DTO is a Core J2EE pattern that's become an anti-pattern.
I realize that some people would disagree. I'm simply offering my opinion. It's not the only way to do it, nor necessarily the "right" way. It's my preference.
在 DTO 的所有欢乐踢动中,需要有一种逆向观点。
tl;dr - 有时仍然有用。
DTO 的优点是您不必向域类添加无数注释。
您从@Entity 开始。还不错。但是然后你需要 JAXB,所以你添加 @XMLElement 等 - 然后你需要 JSON,所以你添加像 @JsonManagedReference 这样的东西,让 Jackson 对关系做正确的事情,然后你无限地添加等等。
很快你的 POJO 就不再那么简单了。有时阅读“领域驱动设计”。
此外,您可以“过滤”一些您不希望视图知道的属性。
There needs to be a contrarian view amongst all the jolly kicking of the DTO.
tl;dr - It is sometimes still useful.
The advantage of the DTO is that you don't have to add a zillion annotations to your domain classes.
You start with @Entity. Not so bad. But then you need JAXB so you add @XMLElement etc - and then you need JSON so you add things like @JsonManagedReference for Jackson to do the right thing with relationships then you add etc. etc. etc. ad infinitum.
Pretty soon your POJO ain't so plain any more. Read about "domain driven design" sometime.
In addition you can "filter" some properties that you don't want the view to know about.
我们不应该忘记,当实体对象处于托管状态时,它们并不容易处理。这使得它们传递到 GUI 表单时出现问题。更准确地说,子对象是被急切处理的。这不能在会话外完成,排除例外情况。因此,它们要么必须从实体管理器中驱逐(分离),要么必须转换为适当的 DTO。除非有一种我不知道的模式,否则我会很高兴知道。
We should not forget that entity objects are not easy to handle when they are in managed state. This makes their passing to GUI forms problematic. To be more precise, child objects are handled eagerly. This cannot be done out of session, cousing exceptions. So, they either have to be evicted (detached) from the entity manager of they have to be converted to appropriate DTOs. Unless of cource there is a pattern, which I am not aware of, that I would be very glad to know.
为了快速创建一个“看起来相似”的 DTO,而不需要一堆重复的 get/set 代码,您可以使用 BeanUtils.copyProperties。该函数可以帮助您快速将数据从 DAO 复制到 DTO 类。请记住,有不止一个公共库支持 BeanUtils.copyProperties,但它们的语法并不相同。
For quickly create a "look-alike" DTO, without a bunch of duplicate get/set code, you can use BeanUtils.copyProperties. That function help you quickly copy the data from DAO to DTO class. Just remember that there are more than one common libraries support BeanUtils.copyProperties, but their syntax are not the same.
我知道这是一个老问题,但我想我会添加一个答案,提供一个框架来帮助防止其他人解决这个问题。
我们的项目具有 JAXB 带注释的 POJO,它们与 JPA 带注释的 POJO 是分开的。我们的团队正在讨论如何最好地在两个对象(实际上是数据结构)之间移动数据。
这是一个供人们考虑的选项:
我们发现并正在试验 Dozer ,它处理 (1) 相同的名称、(2) XML 映射和 (3) 自定义转换作为在两个 POJO 之间复制数据的方法。
到目前为止,它非常容易使用。
I know this is an old question, but thought I would add an answer offering a framework to help in case someone else is tackling this problem.
Our project has JAXB annotated POJOs that are separate from the JPA annotated POJOs. Our team was debating how best to move data between the two objects (actually data structures).
Here is an option for people to consider:
We found and are experimenting with Dozer which handles (1) same name, (2) XML mapping and (3) custom conversions as ways to copy data between two POJOs.
It has been very easy to use so far.