Nomin自动映射会导致无限循环 [英] Nomin automap causes infinite loop
问题描述
我使用Nomin进行绘图任务。从 Nomin 的文档中可以看出,它应该能够自行映射同名的字段如果自动映射已被激活。在激活它时,会导致无限循环异常。
我有以下内容:
mappingFor a:CoinsOnMarketPlace,b:Coin
// automap()//当被激活时,它可以正常工作,当激活无限循环时
a.coin.name = b。名称
a.coin.rank = b.rank
a.priceUSD = b.priceUSD //可以自动映射
a.priceBTC = b.priceBTC //可以自动映射
...
例外:
org.nomin.core.NominException:./net/hemisoft/ccm/repository/coinmarketcap2coin.groovy:递归映射规则a = b导致无限循环!
code>递归映射规则a = b导致无限循环!抛出异常,因为您使用 groovy 类的问题。 Nomin使用 ReflectionIntrospector
以及什么是重要的:
它使用访问器方法执行获取/设置属性通过Java反射机制调用。 ReflectionIntrospector使用提供的NamingPolicy实例来确定访问器方法。默认情况下使用JbNamingPolicy,这个实现符合JavaBeans约定。它的名为ReflectionInstanceCreator的InstanceCreator使用Class.newInstance()实例化对象。
$ b来源: http://nomin.sourceforge.net/introspectors.html
一个简单的Groovy类,如:
class实体{
字符串名称
字符串somethingElse
$ / code>
被编译为一个实现了 GroovyObject
提供以下内容方法:
$ b $ pre $ 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);
在这种情况下 ReflectionInstanceCreator
结合 automap()
解决以下映射:
a.property = b.property
和
a = b
其中 a = b 映射来自
MetaClass getMetaClass()
getter方法我想,因为没有像 a.metaClass = b这样的映射。 metaClass
已解决。 a.property = b.property
由于 Object getProperty(String var1)
方法而得到解决。
解决方案
这个问题可以通过明确指定 ExplodingIntrospector
为您的映射脚本即:
它通过Java反射机制立即通过类字段执行获取/设置属性,并且在域对象不要为其属性提供访问器。提供的实例创建者是ReflectionInstanceCreator。
源: http://nomin.sourceforge.net/introspectors.html
您只需要do是添加
introspector exploding
右下方 mappingFor a:...,b:...
标题。例如:
import mypackage.Entity
import mypackage.EntityDto
mappingFor a:实体b:EntityDto
introspector爆炸
automap()
a.test2 = b.test1
测试两个Groovy类,像魅力一样工作。希望它有帮助。
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!
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().
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.
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.
这篇关于Nomin自动映射会导致无限循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!