我希望将我的映射过程标准化,使其遵循特定的方案。因此,我引入了一些通用接口,它们有助于减少为新类型编写新映射器的工作量。以下是针对类型的接口:
import lombok.NonNull;
public interface MappableCyclic<IN extends MappableCyclic<IN, OUT>, OUT extends MappableCyclic<OUT, IN>>
{
void beforeMapping(@NonNull IN in, @NonNull OUT out, @NonNull ReferenceCycleTracking context);
void afterMapping(@NonNull IN in, @NonNull OUT out, @NonNull ReferenceCycleTracking context);
}
ReferenceCycleTracking
是 mapstruct 上下文的典型实现,用于避免在映射具有循环依赖关系的对象时出现无限递归。此外,还有一个用于映射器的通用父接口:
public interface MappableCyclicMapper<IN extends MappableCyclic<IN, OUT>, OUT extends MappableCyclic<OUT, IN>>
{
@NonNull OUT map(@NonNull IN in, @NonNull @Context ReferenceCycleTracking context);
@BeforeMapping default void beforeMapping(
@NonNull IN in,
@NonNull @MappingTarget OUT out,
@NonNull @Context ReferenceCycleTracking context)
{
out.beforeMapping(out, in, context);
}
@AfterMapping default void afterMapping(
@NonNull IN in,
@NonNull @MappingTarget OUT out,
@NonNull @Context ReferenceCycleTracking context)
{
out.afterMapping(out, in, context);
}
@NonNull Class<OUT> outType();
@NonNull OUT create(IN in);
/**
* object factory should be called by mapstruct during generated {@link #map(MappableCyclic, ReferenceCycleTracking)}
* implementation
*/
@ObjectFactory default @NonNull OUT lookupOrCreate(@NonNull IN in, @NonNull ReferenceCycleTracking context)
{
OUT out = context.get(in, outType());
if (out == null)
{
out = create(in);
context.put(in, out);
}
return out;
}
}
最后,这是我的两个可映射类型的映射器接口:
@Mapper interface Map_TaskGroup_EntityDTO_EntityJPA extends MappableCyclicMapper<TaskGroupEntityDTO, TaskGroupEntityJPA>
{
Map_TaskGroup_EntityDTO_EntityJPA INSTANCE = Mappers.getMapper(Map_TaskGroup_EntityDTO_EntityJPA.class);
@NonNull TaskGroupEntityJPA map(@NonNull TaskGroupEntityDTO input, @NonNull @Context ReferenceCycleTracking context);
@Override default @NonNull Class<TaskGroupEntityJPA> outType() { return TaskGroupEntityJPA.class; }
@Override default @NonNull TaskGroupEntityJPA create(TaskGroupEntityDTO in) { return new TaskGroupEntityJPA(in.name()); }
@ObjectFactory
@Override default @NonNull TaskGroupEntityJPA lookupOrCreate(
@NonNull TaskGroupEntityDTO taskGroupEntityDTO, @NonNull ReferenceCycleTracking context)
{
return MappableCyclicMapper.super.lookupOrCreate(taskGroupEntityDTO, context);
}
}
我预期 mapstruct 会使用@ObjectFactory
父接口中提供的方法,但实际上并没有。因此,我尝试在上面的子接口中添加一个对象工厂方法来帮助 mapstruct。然而,mapstruct 生成的该接口的实现忽略了我的对象工厂方法:
@Override
public TaskGroupEntityJPA map(TaskGroupEntityDTO input, ReferenceCycleTracking context) {
TaskGroupEntityJPA target = context.get( input, TaskGroupEntityJPA.class );
if ( target != null ) {
return target;
}
if ( input == null ) {
return null;
}
String name = null;
TaskGroupEntityJPA taskGroupEntityJPA = new TaskGroupEntityJPA( name );
context.put( input, taskGroupEntityJPA );
beforeMapping( input, taskGroupEntityJPA, context );
afterMapping( input, taskGroupEntityJPA, context );
return taskGroupEntityJPA;
}
我如何确保我的对象工厂方法不再被忽略?