请查看Mapstruct映射循环的示例。
文档中Context注解也提供了解决方案。
示例
完整的示例:https://github.com/jannis-baratheon/stackoverflow--mapstruct-mapping-graph-with-cycles。
参考
映射器:
@Mapper
public interface UserMapper {
@Mapping(target = "userProfileEntity", source = "userProfile")
UserEntity mapToEntity(User user,
@Context CycleAvoidingMappingContext cycleAvoidingMappingContext);
@InheritInverseConfiguration
User mapToDomain(UserEntity userEntity,
@Context CycleAvoidingMappingContext cycleAvoidingMappingContext);
@Mapping(target = "userEntity", source = "user")
UserProfileEntity mapToEntity(UserProfile userProfile,
@Context CycleAvoidingMappingContext cycleAvoidingMappingContext);
@InheritInverseConfiguration
UserProfile mapToDomain(UserProfileEntity userProfileEntity,
@Context CycleAvoidingMappingContext cycleAvoidingMappingContext);
}
CycleAvoidingMappingContext
用于跟踪已映射的对象并重复使用它们,从而避免堆栈溢出。
public class CycleAvoidingMappingContext {
private final Map<Object, Object> knownInstances = new IdentityHashMap<>();
@BeforeMapping
public <T> T getMappedInstance(Object source,
@TargetType Class<T> targetType) {
return targetType.cast(knownInstances.get(source));
}
@BeforeMapping
public void storeMappedInstance(Object source,
@MappingTarget Object target) {
knownInstances.put(source, target);
}
}
使用Mapper(映射单个对象):
UserEntity mappedUserEntity = mapper.mapToEntity(user, new CycleAvoidingMappingContext());
你可以在mapper上添加一个默认方法:
您还可以在mapper上添加一个默认方法:
@Mapper
public interface UserMapper {
default UserEntity mapToEntity(User user) {
return mapToEntity(user, new CycleAvoidingMappingContext());
}
}
return mapToEntity(user, new CycleAvoidingMappingContext());
的默认方法。然而,这导致了一个模棱两可的错误消息。我不得不像这里所描述的那样添加了一个@Qualifier
。我在所有新的默认方法中添加了@DoIgnore
。之后一切都没问题了。 - Avec