Nomin 自动映射导致无限循环
Nomin automap causes infinite loop
我正在使用 Nomin 进行映射任务。从 Nomin 的文档中获取,如果自动映射已被激活,它应该能够自己映射具有相同名称的字段。激活时,引发无限循环异常
我有以下内容:
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
...
异常:
org.nomin.core.NominException: ./net/hemisoft/ccm/repository/coinmarketcap2coin.groovy: Recursive mapping rule a = b causes infinite loop!
关于您的用例值得添加的一件事 - 此 Recursive mapping rule a = b causes infinite loop!
异常被抛出是因为您使用 groovy classes in your mapping rule. Nomin uses ReflectionIntrospector
重要的是:
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().
一个简单的Groovy class喜欢:
class Entity {
String name
String somethingElse
}
被编译为 Java class 实现 GroovyObject
提供以下方法:
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
为您的映射脚本来解决:
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.
你所要做的就是添加
introspector exploding
mappingFor a: ..., b: ...
header 正下方。例如:
import mypackage.Entity
import mypackage.EntityDto
mappingFor a: Entity, b: EntityDto
introspector exploding
automap()
a.test2 = b.test1
经过两个 Groovy class 测试,效果非常好。希望对你有帮助。
我正在使用 Nomin 进行映射任务。从 Nomin 的文档中获取,如果自动映射已被激活,它应该能够自己映射具有相同名称的字段。激活时,引发无限循环异常
我有以下内容:
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
...
异常:
org.nomin.core.NominException: ./net/hemisoft/ccm/repository/coinmarketcap2coin.groovy: Recursive mapping rule a = b causes infinite loop!
关于您的用例值得添加的一件事 - 此 Recursive mapping rule a = b causes infinite loop!
异常被抛出是因为您使用 groovy classes in your mapping rule. Nomin uses ReflectionIntrospector
重要的是:
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().
一个简单的Groovy class喜欢:
class Entity {
String name
String somethingElse
}
被编译为 Java class 实现 GroovyObject
提供以下方法:
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
为您的映射脚本来解决:
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.
你所要做的就是添加
introspector exploding
mappingFor a: ..., b: ...
header 正下方。例如:
import mypackage.Entity
import mypackage.EntityDto
mappingFor a: Entity, b: EntityDto
introspector exploding
automap()
a.test2 = b.test1
经过两个 Groovy class 测试,效果非常好。希望对你有帮助。