JAX-RS 中的 LazyInitializationException 和 DTO

LazyInitializationException and DTO in JAX-RS

在我的 RESTful 后端应用程序中有两个实体(A 和 B)具有以下关系:一个实体 A 可以与许多实体 B 相关联,因此在 A 中我们有一组 B 实体注释@OneToMany.

实现 MVC 模式,我有:

我在资源层中检索 A 实体时出现 LazyInitializationException。四处搜索,我了解到问题源于这样一个事实,即当服务层 return 是实体 A 时,它将它与持久层分离,并且由于默认情况下集合是延迟加载的,如果我试图让它们进入资源层,我收到异常。

网络上引用最多的解决方案之一是使用 DTO 对象并在服务层将实体转换为 DTO。

我的第一个问题与最后一段有关: 这种方法只是使用实体的“获取”方法并因此强制 ORM 加载集合的技巧吗? 我这么说是因为当我们将 Entity 映射到 DTO 时,我们做了以下操作:

objectADTO.setB(objectAEntity.getB());

使用这个操作,我们是从DB中取出B的集合,我们可以在服务层简单的写一行这样的代码:objectAEntity.getB(),然后直接return 到服务层 objectAEntity,它不会引发异常,因为我们使用 .getB() 来检索实际值。

现在,您可以说:DTO 对象可以让您拥有更多功能,但是 我的第二个问题 是: 我是否必须根据我需要的服务层中的方法在实体 A 和 DTO A 之间定义不同的映射? 换句话说,如果我有两种方法 return 的 A 的不同信息,我应该处理两种 DTO 映射吗? (例如,考虑 A 包含两个不同的图像集合,方法 1 想要第一个集合,而第二个方法想要第二个。我不能使用为这两种方法提供所有集合的相同 DTO 映射,因为它会 return 一个太重的物体)

我希望我在描述我的问题时是清楚的。

提前感谢您的回答

您可以通过仅映射 Java 属性并在转换期间触发延迟加载的方式实现 DTO,但这可能会导致您遇到臭名昭著的 N + 1 延迟加载问题。如果只加载 DTO 真正需要的数据,性能会好很多。

DTO 并不总是实体的子集,有时还包含转换后的信息或关于间接相关实体的信息。因此,每个用例都有一个专用类型绝对是 IMO 所希望的。

do I have to define a different mapping between entity A and DTO A, based on the methods in the service layer that I need? In other words, if I have two methods that returns different info of A, should I handle two kinds of DTO mapping?

是的,每个用例都应该有自己的 DTO。如果需要,您可以通过继承或组合实现可重用性。

这是 Blaze-Persistence Entity Views 的完美用例。

我创建了库以允许在 JPA 模型和自定义接口或抽象 class 定义的模型之间轻松映射,类似于 Spring 类固醇数据投影。这个想法是您按照自己喜欢的方式定义目标结构(领域模型),并通过 JPQL 表达式将属性(getter)映射到实体模型。

您的用例的 DTO 模型可能如下所示 Blaze-Persistence Entity-Views:

@EntityView(A.class)
public interface ADto {
    @IdMapping
    Long getId();
    String getName();
    @Mapping("bCollection")
    Set<BDto> getBs();

    @EntityView(B.class)
    interface BDto {
        @IdMapping
        Long getId();
        String getName();
    }
}

查询就是将实体视图应用于查询,最简单的就是通过 id 进行查询。

ADto a = entityViewManager.find(entityManager, ADto.class, id);

Spring 数据集成让您几乎可以像 Spring 数据投影一样使用它:https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features