【发布时间】:2021-11-10 06:28:10
【问题描述】:
在通过 MapStruct 将实体映射到响应 DTO 时,我正在尝试寻找一种更好的解决方案来防止休眠代理初始化。
我一直在将我们的代码库转换为使用 ModelMapper 中的 MapStruct。如果我想用 ModelMapper 完成我的要求,我可以做一些简单的事情:
modelMapper
.createTypeMap(Entity.class, DTO.class)
.addMapping(Entity::customGetterMethod, Category::setNormalSetterHere);
那个自定义 getter 方法允许我检查一个字段是否已经从数据库中获取,以避免 N+1 初始化。
看起来像:
public Set<Entity> customGetterMethod() {
return Hibernate.isInitialized(this.entities) ? this.entities : null;
}
我不能简单地覆盖普通的 getter,因为在处理我们希望允许延迟初始化的实体时存在合理的情况。
我尝试覆盖默认命名策略以使用我自己的自定义 getter 命名,但由于我仍然需要访问大多数基本字段的普通 getter,我无法让它可靠地使用我的 customGetter 并忽略默认 getter当它存在时(即使我可以,它仍然似乎是一个混乱的解决方案,很难让队友跟上速度)。
目前的解决方案是使用expression,然后复制并修改为这些类型的字段生成的映射代码:
@Mapping(
target = "entities",
expression = "java( mapEntities( source.customGetterMethod(), context ) )")
public abstract ResponseDto toDto(Entity source, @Context CycleAvoidingContext context);
protected Set<ResponseDto> mapEntities(Set<Entity> set, CycleAvoidingContext context) {
/* a copy of the auto-generated code for this mapping essentially */
}
对于我们项目中的所有实体和关系,这几乎是不可持续的,因为我必须为每个字段添加一个带有表达式字符串的带注释的映射以及自定义(不是自定义,只是复制)映射逻辑。从可维护性和文档的角度来看,它增加了很多复杂性。
我希望有人可以向我指出其他一些 mapstruct 功能,以便以更简化的方式为特定字段使用自定义 getter。
【问题讨论】:
标签: mapstruct