【问题标题】:JPA manually load collectionsJPA 手动加载集合
【发布时间】:2016-02-01 13:04:26
【问题描述】:

我有一个实体持有一个延迟加载的集合 (@OneToMany)。到现在为止还挺好。如果我加载整个实体对象列表 (findAll()),我根本不希望加载集合。我不访问该集合,因此我认为在从 REST 端点返回它之前不会加载它,但似乎 Jackson 在将其解析为 JSON 时会访问它。

目前我遍历整个实体列表并将集合设置为NULL。这似乎是一种非常糟糕的做法,有没有办法只用专门准备的@Query 手动加载集合,而不是自动加载它(懒惰没有 EAGER)? @JsonViews 是正确的方法还是应该删除 @OneToMany 注释(我想我会丢失实际加载集合的查询的映射)?还有其他建议吗?

示例代码

@实体

@Entity
public class Entity {
  @OneToMany(targetEntity = Child.class)
  private List<Child> children;

}

球衣资源

@GET
@Produces({MediaType.APPLICATION_JSON})
public List<Entity> getAllEntities() {
  List<Entity> entities = entityService.findAll();

  entities.forEach(e-> e.setChildren(null));

  return entities ;
}

Repository = JpaRepository,默认实现 findAll()

谢谢

【问题讨论】:

  • 有几个想法 - 不要使用相同的 java 类来抽象数据库表和 JSON 响应实体。引入一个新对象 - EntityResponseDto 或其他任何东西并在您的 Resoruce 中使用它。让杰克逊“控制”你的实体类的行为是很糟糕的。我认为引入新类将使您能够控制传递给 Jackson 序列化程序的内容。在那个新类上使用 JsonViews 没问题。
  • 这是最佳实践吗?如果与原始实体或端点非常相似或相同,我发现为每个实体或端点创建特殊对象有点不必要。
  • 取决于您要构建什么以及您的重点是什么。如果您想拥有独立/可重用的层,最好将它们分开。在您的情况下,您赋予 1 个对象 2 个职责,并且以这种方式混合 2 个层 - DAO 和 REST 层。大多数情况下,这被认为是不好的做法。当然,如果您不关心分层架构,那么您的数据库模型很简单,并且您想节省时间......好吧,您可以做任何必要的事情。如果您遇到必须大量使用 Jackson 和 JPA 注释的复杂情况会发生什么?这在同一个班级会很麻烦。
  • 我猜你和@yugo 是对的。你有一个例子来说明如何最好地将 DTO 解析为 DAO 对象,反之亦然?使用彼此的构造函数似乎是另一个紧密耦合。我应该实现特殊的解析器吗?谢谢
  • 我不会太担心这一点。这是一个可重复/无聊的代码块。如果需要,您可以编写自己的 ObjectMapper。最初我会在每个 Entity 类中引入一个方法 - smth like - asEntityResponseDto() 它将简单地将 Entity 类的字段设置到 Dto 类中并返回它。

标签: java hibernate jpa jackson spring-data-jpa


【解决方案1】:

既然您提到了“建议”,我自己也遇到了同样的问题,因此我决定实现自定义 DTO,以便在 API 响应中发送。所以我省略了这些集合字段和所有其他我不希望 json 处理器接触的字段。 我确实实现了一组镜像实际持久实体的 DTO,但可能还有其他一些映射器可以完成这项工作

【讨论】:

  • 就是这样!
  • 顺便说一句,我什至没有应用实体和 DTO 之间的依赖关系。我创建了一个 util 类,在公共静态方法中执行实体和 DTO 之间的值复制,反之亦然。
【解决方案2】:

前段时间,我问了一个关于designing model classes REST API 的问题。那里可能有一些对您有用的信息。

我意识到最好的方法是创建不同的模型,而不是重复使用相同的模型类来实现持久性和 REST API。在某些情况下,您不希望持久性模型与您在 API 中使用的模型相同。所以,定义不同的模型是要走的路。

我选择了MapStruct 从一个模型映射到另一个模型。

【讨论】:

    猜你喜欢
    • 2016-12-21
    • 2020-01-23
    • 2015-07-10
    • 2013-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-12
    • 1970-01-01
    相关资源
    最近更新 更多