Null pointer exception occurred after upgrading orika-mapper to latest [1.5.4] while mapping list of object by passing mappingContext

huangapple go评论57阅读模式
英文:

Null pointer exception occurred after upgrading orika-mapper to latest [1.5.4] while mapping list of object by passing mappingContext

问题

问题出现在将orika-mapper从1.4.6升级到1.5.4后。

以下是具有为源对象和目标对象注册自定义映射器的自定义映射器类:

@Component
public class CustomMapper extends ConfigurableMapper implements Imapper {

  @Override
  public void configure(MapperFactory mapperFactory) {
    mapperFactory.registerClassMap(mapperFactory.classMap(A.class, B.class)
        .byDefault().customize(getAtoBMapper()).toClassMap());
  }

  private CustomMapper<A, B> getAtoBMapper() {
    return new CustomMapper<A, B>() {
      @Override
      public void mapAtoB(A a, B b, MappingContext context) {
      
      };
    };
  }
}

以下是调用者:

MappingContext mappingContext = new MappingContext(map);
List<B> bList =
       customMapper.mapAsList(aList, B.class,
            mappingContext);
// aList是对象a的列表

发生异常:

ma.glasnost.orika.MappingException: java.lang.NullPointerException
        at ma.glasnost.orika.impl.generator.MapperGenerator.build(MapperGenerator.java:104) ~[orika-core-1.5.4.jar:?]
        at ma.glasnost.orika.impl.DefaultMapperFactory.buildMapper(DefaultMapperFactory.java:1478) ~[orika-core-1.5.4.jar:?]
        at ma.glasnost.orika.impl.DefaultMapperFactory.lookupMapper(DefaultMapperFactory.java:738) ~[orika-core-1.5.4.jar:?]
        at ma.glasnost.orika.impl.MapperFacadeImpl.resolveMapper(MapperFacadeImpl.java:568) ~[orika-core-1.5.4.jar:?]
        at ma.glasnost.orika.impl.MapperFacadeImpl.resolveMappingStrategy(MapperFacadeImpl.java:178) ~[orika-core-1.5.4.jar:?]
        at ma.glasnost.orika.impl.DefaultBoundMapperFacade$BoundStrategyCache.getStrategy(DefaultBoundMapperFacade.java:259) ~[orika-core-1.5.4.jar:?]
        at ma.glasnost.orika.impl.DefaultBoundMapperFacade.mapReverse(DefaultBoundMapperFacade.java:152) ~[orika-core-1.5.4.jar:?]
        at ma.glasnost.orika.generated.Orika_B_A_Mapper113184950754086$47.mapBtoA(Orika_B_A_Mapper113184950754086$47.java) ~[orika-core-1.5.4.jar:?]
英文:

`Issue is occurring after upgrading the orika-mapper 1.4.6 to 1.5.4

Here is the custom Mapper class with registering custom mapper for source object and destination object.'

@Component
public class CustomMapper extends ConfigurableMapper implements Imapper {
@Override
public void configure(MapperFactory mapperFactory) {
mapperFactory.registerClassMap(mapperFactory.classMap(A.class,B.class)
.byDefault().customize(getAtoBMapper()).toClassMap());
}
private CustomMapper&lt;A,B&gt; getAtoBMapper() {
return new CustomMapper&lt;A,B&gt;() {
@Override
public void mapAtoB(A a,B b, MappingContext context) {
};
}

Here is caller:

MappingContext mappingContext = new MappingContext(map);
List&lt;B&gt;bList =
customMapper.mapAsList(aList,B.class,
mappingContext);
//aList is a list of object a

Exception occurred:

ma.glasnost.orika.MappingException: java.lang.NullPointerException
at ma.glasnost.orika.impl.generator.MapperGenerator.build(MapperGenerator.java:104) ~[orika-core-1.5.4.jar:?]
at ma.glasnost.orika.impl.DefaultMapperFactory.buildMapper(DefaultMapperFactory.java:1478) ~[orika-core-1.5.4.jar:?]
at ma.glasnost.orika.impl.DefaultMapperFactory.lookupMapper(DefaultMapperFactory.java:738) ~[orika-core-1.5.4.jar:?]
at ma.glasnost.orika.impl.MapperFacadeImpl.resolveMapper(MapperFacadeImpl.java:568) ~[orika-core-1.5.4.jar:?]
at ma.glasnost.orika.impl.MapperFacadeImpl.resolveMappingStrategy(MapperFacadeImpl.java:178) ~[orika-core-1.5.4.jar:?]
at ma.glasnost.orika.impl.DefaultBoundMapperFacade$BoundStrategyCache.getStrategy(DefaultBoundMapperFacade.java:259) ~[orika-core-1.5.4.jar:?]
at ma.glasnost.orika.impl.DefaultBoundMapperFacade.mapReverse(DefaultBoundMapperFacade.java:152) ~[orika-core-1.5.4.jar:?]
at ma.glasnost.orika.generated.Orika_B_A_Mapper113184950754086$47.mapBtoA(Orika_B_A_Mapper113184950754086$47.java) ~[orika-core-1.5.4.jar:?]

答案1

得分: 1

以下是您提供的内容的翻译:

似乎 Orika 已被废弃,并且迄今为止没有修复。因此,我实施了一种解决方法,并希望对于其他面临相同问题的人有所帮助。

我们需要获得由 Orika 本身创建的正确的 ma.glasnost.orika.MappingContext,以便 mappingContext.getProperty(Properties.CAPTURE_FIELD_CONTEXT) 不为 null。为了实现这一点,我们必须创建一个实用程序类。

package org.test;

import ma.glasnost.orika.MappingContext;
import ma.glasnost.orika.MappingContextFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;

/**
 * 用于获取由 Orika 配置并准备好供 {@link ma.glasnost.orika.MapperFacade#map(java.lang.Object, java.lang.Class)} 使用的 {@link MappingContext} 的实用程序类。
 */
public final class MappingContextUtils {

    private static final MappingContextFactory MAPPING_CONTEXT_FACTORY;

    static {
        MAPPING_CONTEXT_FACTORY = new CustomDefaultMapperFactory.Builder().build().getContextFactory();
    }

    /**
     * 获取由 {@link ma.glasnost.orika.MapperFacade#map(java.lang.Object, java.lang.Class)} 使用的 {@link MappingContext}。
     * 手动创建 {@link MappingContext} 不起作用。请参阅下面的链接。
     *
     * @return {@link MappingContext}
     * @see &lt;a href=&quot;https://github.com/orika-mapper/orika/issues/354&quot;&gt;https://github.com/orika-mapper/orika/issues/354&lt;/a&gt;
     */
    public static MappingContext getMappingContext() {
        return MAPPING_CONTEXT_FACTORY.getContext();
    }

    /**
     * 用于暴露 {@link MappingContextFactory} 的 getter,以便创建带有预填充全局属性的 {@link MappingContext}。
     */
    private static class CustomDefaultMapperFactory extends DefaultMapperFactory {

        /**
         * 构造 DefaultMapperFactory 的新实例。
         *
         * @param builder {@link MapperFactoryBuilder}
         */
        protected CustomDefaultMapperFactory(MapperFactoryBuilder<?, ?> builder) {
            super(builder);
        }

        /**
         * 获取 {@link MappingContextFactory}。
         *
         * @return {@link MappingContextFactory}
         */
        public MappingContextFactory getContextFactory() {
            return contextFactory;
        }

        public static class Builder extends DefaultMapperFactory.MapperFactoryBuilder<CustomDefaultMapperFactory, Builder> {

            @Override
            public CustomDefaultMapperFactory build() {
                return new CustomDefaultMapperFactory(this);
            }

            @Override
            protected CustomDefaultMapperFactory.Builder self() {
                return this;
            }

        }

    }

}

现在它可以像这样使用:

MappingContext mappingContext = MappingContextUtils.getMappingContext(); // 在这里我们获取了由 Orika 创建的映射上下文
List<B> bList = customMapper.mapAsList(aList, B.class, mappingContext);
英文:

It seems Orika is abandoned and there is no fix so far. So I implemented a workaround and hope it will be useful for others facing the same issue.

We need to get a proper ma.glasnost.orika.MappingContext created by Orika itself, so mappingContext.getProperty(Properties.CAPTURE_FIELD_CONTEXT) is not null. To achieve this we have to create a utility class.

package org.test;
import ma.glasnost.orika.MappingContext;
import ma.glasnost.orika.MappingContextFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;
/**
* The utility class to get {@link MappingContext} configured by Orika
* and ready to be used by {@link ma.glasnost.orika.MapperFacade#map(java.lang.Object, java.lang.Class)}.
*/
public final class MappingContextUtils {
private static final MappingContextFactory MAPPING_CONTEXT_FACTORY;
static {
MAPPING_CONTEXT_FACTORY = new CustomDefaultMapperFactory.Builder().build().getContextFactory();
}
/**
* Gets {@link MappingContext} ready to be used by {@link ma.glasnost.orika.MapperFacade#map(java.lang.Object, java.lang.Class)}.
* Manual creation of {@link MappingContext} does not work. Please see the link below.
*
* @return {@link MappingContext}
* @see &lt;a href=&quot;https://github.com/orika-mapper/orika/issues/354&quot;&gt;https://github.com/orika-mapper/orika/issues/354&lt;/a&gt;
*/
public static MappingContext getMappingContext() {
return MAPPING_CONTEXT_FACTORY.getContext();
}
/**
* The custom {@link DefaultMapperFactory} to expose getter
* for {@link MappingContextFactory} so {@link MappingContext} with prefilled globalProperties can be created.
*
* @author Dmitry Lebedko (dmitry.lebedko@t-systems.com)
*/
private static class CustomDefaultMapperFactory extends DefaultMapperFactory {
/**
* Constructs a new instance of DefaultMapperFactory
*
* @param builder {@link MapperFactoryBuilder}
*/
protected CustomDefaultMapperFactory(MapperFactoryBuilder&lt;?, ?&gt; builder) {
super(builder);
}
/**
* Gets {@link MappingContextFactory}.
*
* @return {@link MappingContextFactory}
*/
public MappingContextFactory getContextFactory() {
return contextFactory;
}
public static class Builder extends DefaultMapperFactory.MapperFactoryBuilder&lt;CustomDefaultMapperFactory, Builder&gt; {
@Override
public CustomDefaultMapperFactory build() {
return new CustomDefaultMapperFactory(this);
}
@Override
protected CustomDefaultMapperFactory.Builder self() {
return this;
}
}
}
}

Now it may be used like that

MappingContext mappingContext = MappingContextUtils.getMappingContext(); // here we get a mapping context created by Orika
List bList = customMapper.mapAsList(aList, B.class, mappingContext);

huangapple
  • 本文由 发表于 2020年7月30日 17:17:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/63169999.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定