启用Nomin automap触发无限循环异常的技术问询
我来帮你拆解下这个问题的根源和可行的解决办法:
问题本质
你启用automap()后,Nomin会自动扫描两个映射类的所有同名字段并尝试匹配。但你的CoinsOnMarketPlace类里有一个coin字段(类型是Coin),而目标对象b正好也是Coin类型。这时候Nomin会尝试把a.coin和b进行自动映射,相当于在CoinsOnMarketPlace -> Coin的映射过程中,又触发了Coin -> Coin的递归映射,直接导致无限循环,所以抛出了Recursive mapping rule a = b causes infinite loop!的异常。
而禁用automap()时,只有你手动编写的映射规则生效,Nomin不会自动处理a.coin这个嵌套字段,自然不会触发递归,所以运行正常。
解决方案
这里有几个实用的处理方式,你可以根据业务场景选择:
显式排除递归字段
启用automap()的同时,明确告诉Nomin不要处理a.coin这个会引发递归的字段,剩下的同名字段依然可以自动映射。修改后的代码如下:mappingFor a: CoinsOnMarketPlace, b: Coin automap() exclude a.coin // 排除嵌套的coin字段,避免递归 a.coin.name = b.name a.coin.rank = b.rank // priceUSD、priceBTC这类同名字段不用手动写了,automap会自动处理限定automap的字段范围
如果你不需要全局自动映射,只针对特定字段开启自动映射功能,也能避免触发递归。比如只对价格相关的字段启用自动映射:mappingFor a: CoinsOnMarketPlace, b: Coin a.coin.name = b.name a.coin.rank = b.rank automap a.priceUSD, a.priceBTC // 仅对指定字段自动映射重构类结构(可选)
如果业务逻辑允许,你可以考虑调整CoinsOnMarketPlace的类结构,比如把coin里的字段直接平级放到CoinsOnMarketPlace中,从根源上消除嵌套递归的可能。不过这个方案需要结合你的业务需求来评估是否可行。
验证建议
优先试试第一种方案,排除a.coin后,Nomin的自动映射只会处理priceUSD、priceBTC这类平级的同名字段,而a.coin下的字段依然用你手动编写的规则映射,这样既保留了automap的便利,又避免了递归循环。
内容的提问来源于stack exchange,提问作者Michael Hegner

