【发布时间】:2021-08-10 23:21:52
【问题描述】:
假设我有一个带有控制器、服务和数据层的简单 REST 应用程序。在我的控制器层中,我执行以下操作:
@PostMapping("/items")
void save(ItemDTO dto){
Item item = map(dto, Item.class);
service.validate(item);
service.save(item);
}
但后来我收到错误,因为我的服务层如下所示:
public void validate(Item item) {
if(item.getCategory().getCode().equals(5)){
throw new IllegalArgumentException("Items with category 5 are not currently permitted");
}
}
我在 .equals(5) 处收到 NullPointerException,因为 Item 实体是从仅包含 category_id 的 DTO 反序列化的,没有其他内容(除 id 外,所有内容都是 null)。
我们已经找到并尝试过的解决方案是:
-
制作一个特殊的反序列化器,它采用
ids 并自动获取所需的实体。当然,这会导致大量性能问题,类似于将所有关系标记为FetchType.EAGER时会遇到的问题。 -
让控制器层获取服务层需要的所有实体。问题是,Controller 需要知道底层服务是如何工作的,以及它需要什么。
-
让服务层在运行任何验证之前验证对象是否需要获取。问题是,我们找不到确定对象是否需要获取的可靠方法。我们最终会得到像这样的丑陋代码无处不在:
(样本)
if(item.getCategory().getCode() == null)
item.setCategory(categoryRepo.findById(item.getCategory().getId()));
您还会采取哪些其他方式来使服务易于使用?每次我们想要使用相关实体时都必须进行检查,这确实违反直觉。
请注意,这个问题不是要找到解决这个问题的任何方法。更多的是寻找更好的方法来解决它。
【问题讨论】:
标签: java spring-boot hibernate objectmapper modelmapper