首页 > 解决方案 > 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

解决方案


您所说的没有任何注释的不需要的反向映射实际上是 MapStruct 生成映射的正常方式。如果源 bean 和目标 bean 具有相同的属性(在您的情况下它们具有相同的属性),则 MapStruct 将为它创建一个映射。

如果您不想映射某些属性,您可以一一忽略这些属性或使用@BeanMapping( ignoreByDefault = true). 使用第二个选项 MapStruct 只会为定义的@Mapping.


推荐阅读