Orika Mapper - 初始化MapperFacade后无法注册转换器

Jav*_*per 7 mapping java-8 orika spring-boot

我在Spring启动应用程序中创建了一个使用Orika Mapper API复制bean属性的类,如下所示:

public class ObjectMapper {

    private static MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();

    public static ClientEntity toClientEntity(ClientDTO clientDTO) {
        BoundMapperFacade<ClientDTO, ClientEntity> boundMapper = mapperFactory.getMapperFacade(ClientDTO.class, ClientEntity.class);
        return boundMapper.map(clientDTO);
    }   

    public static UserEntity toUserEntity(UserDTO userDTO) {
        mapperFactory.getConverterFactory().registerConverter(new PassThroughConverter(LocalDate.class));
        mapperFactory.getConverterFactory().registerConverter(new PassThroughConverter(LocalTime.class));
        BoundMapperFacade<UserDTO, UserEntity> boundMapper = mapperFactory.getMapperFacade(UserDTO.class, UserEntity.class);
        return boundMapper.map(userDTO);
    }
}
Run Code Online (Sandbox Code Playgroud)

UserEntity和UserDTO POJO类具有JAVA 8 LocalDate和LocalTime属性,因此具有mapperFactory的registeredConverters.这在第一次工作正常,但在连续调用时抛出以下异常:

java.lang.IllegalStateException: Cannot register converters after MapperFacade has been initialized
    at ma.glasnost.orika.converter.DefaultConverterFactory.registerConverter(DefaultConverterFactory.java:192) ~[orika-core-1.4.6.jar:na]
    at ma.glasnost.orika.impl.DefaultMapperFactory$ConverterFactoryFacade.registerConverter(DefaultMapperFactory.java:1614) ~[orika-core-1.4.6.jar:na]
Run Code Online (Sandbox Code Playgroud)

我理解这是因为在MapperFacade初始化之后正在注册转换器.如何解决这个问题?如何在初始化之前注册转换器?

Ana*_*mov 3

在提供的代码片段中,您尝试在每次toUserEntity()调用时注册转换器。因此,第一个调用会起作用,但第二个调用会失败,因为MapperFacade在第一次调用期间已经初始化了。

您可以将转换器注册从映射方法移动到静态块,如下所示:

private static MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
static {
    mapperFactory.getConverterFactory().registerConverter(new PassThroughConverter(LocalDate.class));
    mapperFactory.getConverterFactory().registerConverter(new PassThroughConverter(LocalTime.class));
}
Run Code Online (Sandbox Code Playgroud)

此外,您可能更愿意将BoundMapperFacade' 移至静态字段以避免不必要的getMapperFacade调用,如下所示:

private static BoundMapperFacade<ClientDTO, ClientEntity> clientBoundMapper 
                     = mapperFactory.getMapperFacade(ClientDTO.class, ClientEntity.class);
private static BoundMapperFacade<UserDTO, UserEntity> userBoundMapper 
                     = mapperFactory.getMapperFacade(UserDTO.class, UserEntity.class);
Run Code Online (Sandbox Code Playgroud)

因此映射方法将变成简单的一行:

public static ClientEntity toClientEntity(ClientDTO clientDTO) {
    return clientBoundMapper.map(clientDTO);
}   

public static UserEntity toUserEntity(UserDTO userDTO) {
    return userBoundMapper.map(userDTO);
}
Run Code Online (Sandbox Code Playgroud)