【发布时间】: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