spring - 在 Hibernate 实体上使用 DTO 映射避免 N+1

标签 spring hibernate jpa transactions dto

在我们的 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将遍历 InvoicesPerson用于转换为 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/

相关文章:

java - tomcat catalina.out 的实时网络日志查看器

如果我在 sql 中使用 'or' 而不是 'in',则 Java 堆空间不足错误

hibernate - Hibernate 5.2.2 中 createCriteria() 方法的替代代码

hibernate - QueryBuilder 中的 Lucene 条件 AND

java - JPA 获取连接实体返回递归获取循环

java - 从 Spring Security 访问 Spring MVC 服务

java - Spring CamelContext 无法解析占位符

java - 配置 JPA 将所有枚举映射到字符串?

java - 当 VARCHARS 转向 CLOB 时,JPA 持久化不会与关系发生

java - 数据未使用 Spring DATA 持久保存到数据库中