简体   繁体   English

JPA 实体和 DTO 属于 Service 还是 Spring Repository 层

[英]Do JPA entities and DTOs belong to Service or Spring Repository layer

I want to write a JPA application, but I have problems understanding the repository and service concepts:我想编写一个 JPA 应用程序,但我在理解存储库和服务概念时遇到了问题:

Consider we have 3 entities: A, B and C.考虑我们有 3 个实体:A、B 和 C。

Entity A needs to have B and C set: A.setB(B), A.setC(C) before it is saved.实体A在保存之前需要设置B和C:A.setB(B), A.setC(C)。

Also for read, I want to return only DTOs since they will free me from LazyInitializationException ,Open Session In View Anti-Pattern , etc, and for modifying data I will use entities ( these guidelines are also described in this book High-Performance Java Persistence ).同样对于阅读,我只想返回 DTO,因为它们将使我摆脱LazyInitializationExceptionOpen Session In View Anti-Pattern等,并且为了修改数据,我将使用实体(这些指南也在本书High-Performance Java Persistence 中进行了描述) )。

First of all, the user will make a HTTP POST with some data which will be converted into ABCGuiObject.首先,用户将使用一些将转换为 ABCGuiObject 的数据进行 HTTP POST。 The REST controller will call serviceA.save(ABCGuiObject). REST 控制器将调用 serviceA.save(ABCGuiObject)。

Persist options:坚持选项:

Option #1 - The service will create 3 objects A, B ,C and pass them to repositoryA.save(A,B,C).选项 #1 - 该服务将创建 3 个对象 A、B、C,并将它们传递给 repositoryA.save(A,B,C)。 The repositoryA will do inside a.setB and a.setC. repositoryA 将在 a.setB 和 a.setC 中执行。

Option #2 - The service will create 3 objects A, B ,C, do a.setB and a.setC and call repositoryA.save(A).选项#2 - 该服务将创建 3 个对象 A、B、C,执行 a.setB 和 a.setC 并调用 repositoryA.save(A)。

DTO retrieval DTO检索

I would like to write a JPQL query to get some DTO.我想编写一个 JPQL 查询来获取一些 DTO。 I do not want to convert entities to DTO, but retrieve them directly with JPQL.我不想将实体转换为 DTO,而是直接使用 JPQL 检索它们。

Option #1 - repositoryA will return directly a DTO.选项 #1 - repositoryA 将直接返回一个 DTO。

Option #2 - the service will pass a JPQL query to the repositoryA, which will have a general query method which returns a DTO.选项#2 - 该服务将一个 JPQL 查询传递给 repositoryA,它将有一个返回 DTO 的通用查询方法。

What approaches do you recommend?你推荐什么方法?

Write data写入数据

The Service layer should construct the graph of entities A , B and C and connect them accordingly ( a.setB and a.setC ) and pass A , B and C to the Repository.服务层应该构建实体ABC并相应地连接它们( a.setBa.setC )并将ABC传递给存储库。 If you have one-to-many associations, you can cascade entity state transitions .如果你有一对多的关联,你可以级联实体状态转换

Read data读取数据

If you want to return DTOs, you are better off fetching DTOs directly from JPA and Hibernate.如果您想返回 DTO,最好直接从 JPA 和 Hibernate 获取 DTO。 So, you have two options:所以,你有两个选择:

This is a subjective thing but I'll share my opinion.这是一个主观的事情,但我会分享我的观点。 For Persist Options, I recommend Option #2.对于持久选项,我推荐选项 #2。 The repository ideally should just do "repository" duties, the service or if too complex you can delegate to a factory to build the A entity.理想情况下,存储库应该只执行“存储库”职责、服务,或者如果太复杂,您可以委托给工厂来构建 A 实体。

For the DTO retrieval, I would issue queries to retrieve the entities(so the repository would always return entities), and transform them to DTO.对于 DTO 检索,我会发出查询来检索实体(因此存储库将始终返回实体),并将它们转换为 DTO。 Someone may need the same repository feature and they can choose to transform to DTO, instead of writing another JPQL with DTO query.有人可能需要相同的存储库功能,他们可以选择转换为 DTO,而不是使用 DTO 查询编写另一个 JPQL。

Persist option 2.坚持选项2。

DTO objects are usually loading lazy fields. DTO 对象通常加载惰性字段。 This can harm performance if you don't write separate query/mapping for different use cases.如果您不为不同的用例编写单独的查询/映射,这可能会损害性能。 DO NOT USE DTO, instead initialize lazy fields per use case to avoid LazyIntializationException.不要使用 DTO,而是为每个用例初始化惰性字段以避免 LazyIntializationException。 Also it will save you lot work with mapping from and into entity for saving.此外,它还可以为您节省大量从实体映射到实体的工作以进行保存。

Regarding the persisting, I'd go with option 2 but not for all service related actions.关于坚持,我会选择选项 2,但不是所有与服务相关的操作。 If you have simple actions like eg addComment, enable/disable then it might be better to only pass ids and let the service get it's hands on the entity itself.如果您有简单的操作,例如 addComment、启用/禁用,那么最好只传递 id 并让服务处理实体本身。

For DTOs I suggest you give Blaze-Persistence Entity Views a look to see how easy the DTO pattern can be implemented.对于 DTO,我建议您查看 Blaze-Persistence Entity Views,看看实现 DTO 模式有多容易。 Here is a nice article about getting started with it.这是一篇关于开始使用它的好文章

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM