在我们的 Restful 应用程序中,出于几个原因,我们决定使用 DTO 来屏蔽 Hibernate 域模型。
我们使用 DTOMappers
手动将 Hibernate 实体映射到 DTO,反之亦然。在 Service Layer
.
服务层示例:
@Transactional(readOnly=true)
public PersonDTO findPersonWithInvoicesById(Long id) {
Person person = personRepository.findById(id);
return PersonMapperDTOFactory.getInstance().toDTO(person);
}
主要概念可以这样解释:
JSON (Jackson parser) <-> Controller <-> Service Layer (uses Mapping Layer) <-> Repository
我们同意通过执行
HQL
来检索关联。 (或 Criteria
)使用 left join
.这主要是一种检索关系并避免
N+1 select issue
的高效方法。 .但是,仍然可以使用
N+1 select issue
当开发人员错误地忘记进行左连接时。仍然会获取关系,因为 PersonDTOMapper
将遍历 Invoices
的 Person
用于转换为 InvoiceDTOs
.所以数据仍然被提取,因为 DTOMapper
在 hibernate session 处于事件状态时执行(由 Spring
管理)有什么方法可以制作
Hibernate Session
我们的 DTOMappers
中的“未激活” ?我们将面临 LazyInitializationException
这应该会触发开发人员他没有像应该那样获取一些数据。我读过
@Transactional(propagation = Propagation.NOT_SUPPORTED)
暂停交易。但是,我不知道它是用于此类目的的。什么是实现这一目标的干净解决方案?替代品也非常受欢迎!
最佳答案
通常我在 Controller 层使用映射器。从我的角度来看,服务层管理应用程序的业务逻辑,如果你想以不同的方式将数据呈现给外部世界,dtos 非常有用。通过这种方式,您可能会得到您正在寻找的惰性初始化 excpetion。
我还有一个更喜欢这个解决方案的理由:只是图像,您需要在服务类的公共(public)方法中调用公共(public)方法:在这种情况下,您可能需要多次调用映射器。
关于spring - 在 Hibernate 实体上使用 DTO 映射避免 N+1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24192406/