在下面的示例中,我有一个单独的域层和一个单独的持久化层。我使用Mapstruct进行映射,在从域到实体或从实体到域的映射中,由于双向引用总是在->无限循环场景中被调用,所以我得到了StackOverflow。在这种情况下,我如何使用Mapstruct?
class User {
private UserProfile userProfile;
}
class UserProfile {
private User user;
}
@Entity
class UserEntity {
@OneToOne
@PrimaryKeyJoinColumn
private UserProfileEntity userProfile;
}
@Entity
class UserProfileEntity {
@OneToOne(mappedBy = "userProfile")
private UserEntity userEntity;
}用于映射的类非常基础
@Mapper
interface UserMapper {
UserEntity mapToEntity(User user);
User mapToDomain(UserEntity userEntity);
}发布于 2020-01-25 04:59:54
查看Mapstruct mapping with cycles示例。
您的问题的解决方案也演示了in the documentation for Context annotation。
示例
一个完整的例子: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);
}
}映射器使用(映射单个对象):
UserEntity mappedUserEntity = mapper.mapToEntity(user, new CycleAvoidingMappingContext());您还可以在映射器上添加默认方法:
@Mapper
public interface UserMapper {
// (...)
default UserEntity mapToEntity(User user) {
return mapToEntity(user, new CycleAvoidingMappingContext());
}
// (...)
}https://stackoverflow.com/questions/59895166
复制相似问题