MapStruct在没有任何反向配置的情况下生成错误的映射代码



我有一个@MapperConfig,看起来像这样。

@MapperConfig(componentModel = "spring")
public interface SomeEntityTypeMapperConfig {
@Mapping(target = PROPERTY_NAME_ENTITY)
@Mapping(source = SomeEntity.ATTRIBUTE_NAME_ID, target = SomeEntityType.PROPERTY_NAME_ID)
@Mapping(source = SomeEntity.PROPERTY_NAME_CREATED_AT, target = SomeEntityType.PROPERTY_NAME_CREATED_AT)
@Mapping(source = SomeEntity.PROPERTY_NAME_UPDATED_AT, target = SomeEntityType.PROPERTY_NAME_UPDATED_AT)
@Mapping(source = SomeEntity.PROPERTY_NAME_CREATED_BY, target = SomeEntityType.PROPERTY_NAME_CREATED_BY)
@Mapping(source = SomeEntity.PROPERTY_NAME_UPDATED_BY, target = SomeEntityType.PROPERTY_NAME_UPDATED_BY)
SomeEntityType<?, ?> fromEntity(SomeEntity entity);
// No @Mapping
void toEntity(SomeEntityType<?, ?> type, @MappingTarget SomeEntity entity);
}

这是我的基本映射器接口。

public interface SomeEntityTypeMapper<T extends SomeEntityType<?, U>, U extends SomeEntity> {
T fromEntity(U entity);
void toEntity(T type, @MappingTarget U entity);
}

我真正的地图绘制者来了。

@Mapper(config = SomeEntityTypeMapperConfig.class)
public interface UserTypeMapper extends SomeEntityTypeMapper<UserType, User> {
@Mapping(source = User.ATTRIBUTE_NAME_NAME, target = UserType.PROPERTY_NAME_NAME)
@Override
UserType fromEntity(User entity);
@Mapping(source = UserType.PROPERTY_NAME_NAME, target = User.ATTRIBUTE_NAME_NAME)
@Override
void toEntity(UserType type, @MappingTarget User entity);
}

MapStruct生成下面的impl类,其中包含不需要的映射

public class UserTypeMapperImpl implements UserTypeMapper {
@Override
public UserType fromEntity(User entity) {
if ( entity == null ) {
return null;
}
UserType userType = new UserType();
userType.setName( entity.getName() );           // explicitly configured
userType.setId( entity.getId() );               // inherited from the config
userType.setCreatedAt( entity.getCreatedAt() ); // inherited from the config
userType.setUpdatedAt( entity.getUpdatedAt() ); // inherited from the config
userType.setCreatedBy( entity.getCreatedBy() ); // inherited from the config
userType.setUpdatedBy( entity.getUpdatedBy() ); // inherited from the config
return userType;
}
@Override
public void toEntity(UserType type, User entity) {
if ( type == null ) {
return;
}
entity.setName( type.getName() );           // explicitly configured
entity.setCreatedAt( type.getCreatedAt() ); // UNWANTED!!!
entity.setUpdatedAt( type.getUpdatedAt() ); // UNWANTED!!!
entity.setUpdatedBy( type.getUpdatedBy() ); // UNWANTED!!!
entity.setId( type.getId() );               // UNWANTED!!!
entity.setCreatedBy( type.getCreatedBy() ); // UNWANTED!!!
}
}

我做错了什么?我该怎么解决?

您所说的不需要任何注释的反向映射实际上是MapStruct生成映射的正常方式。如果源bean和目标bean具有相同的属性(在您的案例中是这样(,MapStruct将为其创建一个映射

如果您不想映射某些属性,您可以逐个忽略这些属性,也可以使用@BeanMapping( ignoreByDefault = true)。使用第二个选项,MapStruct将只为定义的@Mapping创建映射。

我正在分享我的发现。

我需要用@BeanMapping(ignoreByDefault = true)对该方法进行注释。

有趣的是,注释必须与叶映射器接口一起定位。

@BeanMapping(ignoreByDefault = true) // WORKS!!!
@Mapping(source = UserType.PROPERTY_NAME_NAME, target = User.ATTRIBUTE_NAME_NAME)
@Override
void toEntity(UserType type, @MappingTarget User entity);

既不适用于配置,也不适用于父接口。

public interface SomeEntityTypeMapperConfig {
@BeanMapping(ignoreByDefault = true) // Doesn't work!
void toEntity(SomeEntityType<?, ?> type, @MappingTarget SomeEntity entity);
}
public interface SomeEntityTypeMapper<T extends SomeEntityType<?, U>, U extends SomeEntity> {
@BeanMapping(ignoreByDefault = true) // Doesn't work!
void toEntity(T type, @MappingTarget U entity);
}

相关内容

最新更新