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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4558233/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 06:57:23  来源:igfitidea点击:

what is a good pattern for converting between hibernate entities and data transfer objects?

javahibernatedesign-patternsentitydata-transfer-objects

提问by D Parsin

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:

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

Is using data transfer objects in ejb3 considered best practice

在 ejb3 中使用数据传输对象被认为是最佳实践

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.

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

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?

是否有一个很好的设计模式可以用来将 Hibernate 实体(它实现一个接口)转换为一个实现相同接口的 DTO?

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.

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

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?

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

采纳答案by duffymo

Should I just ignore the DTO pattern and pass entities around?

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

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.

DTO 模式的最初原因是在将实体 EJB 传递到视图层时,EJB 1.0 和 2.0 应用程序中的过度喋喋不休。解决方案是将实体 bean 状态放入 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.

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

I would argue that DTO is a Core J2EE pattern that's become an anti-pattern.

我认为 DTO 是一种已成为反模式的核心 J2EE 模式。

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.

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

回答by Gene De Lisa

There needs to be a contrarian view amongst all the jolly kicking of the DTO.

在 DTO 的所有快活中,需要有一种逆向观点。

tl;dr - It is sometimes still useful.

tl;dr - 它有时仍然有用。

The advantage of the DTO is that you don't have to add a zillion annotations to your domain classes.

DTO 的优点是您不必向域类添加无数注释。

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 Hymanson to do the right thing with relationships then you add etc. etc. etc. ad infinitum.

你从@Entity 开始。没那么糟糕。但是随后您需要 JAXB,因此您添加 @XMLElement 等 - 然后您需要 JSON,因此您为 Hymanson 添加诸如 @JsonManagedReference 之类的内容,以便对关系做正确的事情,然后添加等等等等。

Pretty soon your POJO ain't so plain any more. Read about "domain driven design" sometime.

很快你的 POJO 就不再那么简单了。有时阅读“领域驱动设计”。

In addition you can "filter" some properties that you don't want the view to know about.

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

回答by unixorn

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.

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

回答by Hoàng Long

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.

为了快速创建一个“相似”的 DTO,没有一堆重复的 get/set 代码,你可以使用BeanUtils.copyProperties。该功能可帮助您快速将数据从 DAO 复制到 DTO 类。请记住,有不止一个公共库支持 BeanUtils.copyProperties,但它们的语法并不相同。

回答by Mike Barlotta

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).

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

Here is an option for people to consider:

这是供人们考虑的选项:

We found and are experimenting with Dozerwhich handles (1) same name, (2) XML mapping and (3) custom conversions as ways to copy data between two POJOs.

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

It has been very easy to use so far.

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