Nomin automap causes infinite loop

北城余情 提交于 2019-12-02 01:42:48

问题


I am using Nomin for mapping tasks. As taken from the documentation of Nomin it should be able to map fields with the same name by itself in case automapping has been activated. When activating it, it causes an infinite loop exception.

I have the following:

mappingFor a: CoinsOnMarketPlace, b: Coin
// automap() // when deactivated it works fine, when activated infinite loop

a.coin.name         =       b.name
a.coin.rank         =       b.rank
a.priceUSD          =       b.priceUSD  // Could be automapped
a.priceBTC          =       b.priceBTC  // Could be automapped

... 

Exception:

org.nomin.core.NominException: ./net/hemisoft/ccm/repository/coinmarketcap2coin.groovy: Recursive mapping rule a = b causes infinite loop!

回答1:


One thing worth adding regarding your use case - this Recursive mapping rule a = b causes infinite loop! exception is thrown because you use groovy classes in your mapping rule. Nomin uses ReflectionIntrospector and what's important:

It performs getting/setting properties using accessor methods which are called through the Java reflection mechanism. ReflectionIntrospector uses supplied NamingPolicy instance to determine accessor methods. JbNamingPolicy is used by default, this implementation cerresponds the JavaBeans convention. Its InstanceCreator named ReflectionInstanceCreator instantiates objects using Class.newInstance().

Source: http://nomin.sourceforge.net/introspectors.html

A simple Groovy class like:

class Entity {
    String name
    String somethingElse
}

gets compiled to a Java class that implements GroovyObject providing following methods:

public interface GroovyObject {
    Object invokeMethod(String var1, Object var2);

    Object getProperty(String var1);

    void setProperty(String var1, Object var2);

    MetaClass getMetaClass();

    void setMetaClass(MetaClass var1);
}

In this case ReflectionInstanceCreator combined with automap() resolves following mappings:

a.property = b.property

and

a = b

where a = b mapping comes from MetaClass getMetaClass() getter method I suppose, because there is no mapping like a.metaClass = b.metaClass resolved. a.property = b.property gets resolved because of Object getProperty(String var1) method.

Solution

This problem can be solved by specifying explicitly ExplodingIntrospector for your mapping script that:

It performs getting/setting properties using a class field immediately through through the Java reflection mechanism and may be useful in case when domain object don't provide accessors for their properties. Supplied instance creator is ReflectionInstanceCreator.

Source: http://nomin.sourceforge.net/introspectors.html

All you have to do is to add

introspector exploding

right below mappingFor a: ..., b: ... header. For example:

import mypackage.Entity
import mypackage.EntityDto

mappingFor a: Entity,  b: EntityDto
introspector exploding
automap()

a.test2 = b.test1

Tested with two Groovy classes, worked like a charm. Hope it helps.



来源:https://stackoverflow.com/questions/48234524/nomin-automap-causes-infinite-loop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!