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

时间:2016-12-14 10:20:53

标签: java spring hibernate jpa service-layer

我想编写一个JPA应用程序,但是我在理解存储库和服务概念时遇到了问题:

考虑我们有3个实体: A,B和C.

实体A需要设置B和C:A.setB(B),A.setC(C)才能保存。

另外,对于阅读,我想只返回DTO,因为他们会将我从LazyInitializationExceptionOpen Session In View Anti-Pattern等中解​​放出来,而对于修改数据,我会使用实体(这些指南也会在本书中介绍) High-Performance Java Persistence)。

首先,用户将使用一些数据进行HTTP POST,这些数据将转换为ABCGuiObject。 REST控制器将调用serviceA.save(ABCGuiObject)。

坚持选项:

选项#1 - 该服务将创建3个对象A,B,C并将它们传递给repositoryA.save(A,B,C)。 repositoryA将在a.setB和a.setC。

中进行

选项#2 - 该服务将创建3个对象A,B,C,执行a.setB和a.setC并调用repositoryA.save(A)。

DTO检索

我想编写一个JPQL查询来获取一些DTO。我不想将实体转换为DTO,而是直接使用JPQL检索它们。

选项#1 - repositoryA将直接返回DTO。

选项#2 - 该服务将JPQL查询传递给repositoryA,后者将有一个返回DTO的通用查询方法。

您推荐什么方法?

4 个答案:

答案 0 :(得分:1)

这是一个主观的事情,但我会分享我的意见。 对于Persist Options,我建议选项#2。理想情况下,存储库应该只执行“存储库”职责,服务或者如果太复杂,您可以委托工厂来构建A实体。

对于DTO检索,我会发出查询以检索实体(因此存储库将始终返回实体),并将它们转换为DTO。有人可能需要相同的存储库功能,他们可以选择转换为DTO,而不是使用DTO查询编写另一个JPQL。

答案 1 :(得分:0)

坚持

服务层应该构造实体A,B和C的图形并相应地连接它们(a.setB和a.setC)并将A,B和C传递给存储库。如果您有一对多关联,则可以cascade entity state transitions

检索

如果要返回DTO,则必须将适当的方法添加到Spring Data Repository。

为此,您有以下几种选择:

  • 您可以使用JPQL构造函数表达式
  • 您可以使用特定于Hibernate的ResultTransformer

答案 2 :(得分:0)

坚持选项2。

DTO对象通常加载惰性字段。如果不为不同的用例编写单独的查询/映射,这可能会损害性能。不要使用DTO,而是根据用例初始化惰性字段以避免LazyIntializationException。此外,它还可以节省大量工作,从实体映射到实体进行保存。

答案 3 :(得分:0)

关于持久性,我会选择选项2但不适用于所有与服务相关的操作。如果您有简单的操作,例如addComment,启用/禁用然后最好只传递id并让服务将它交给实体本身。

对于DTO,我建议您查看Blaze-Persistence Entity Views,了解DTO模式的实现有多容易。关于开始使用它,这是一个很好的article

相关问题