MappingException:检测到不明确的字段映射 [英] MappingException: Ambiguous field mapping detected

查看:48
本文介绍了MappingException:检测到不明确的字段映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 Spring Boot 1.5.6.RELEASE.

Using Spring boot 1.5.6.RELEASE.

我有以下 mongo 文档基类:

I have the following mongo document base class:

@Document(collection="validation_commercial")
public abstract class Tier {
    @Id
    private String id;
    @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
    private Date created;
    @Field("tran")
    private Tran tran;

    public Tier() {
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Date getCreated() {
        return created;
    }

    public void setCreated(Date created) {
        this.created = created;
    }

    public Tran getTran() {
        return tran;
    }

    public void setTran(Tran tran) {
        this.tran = tran;
    }
}

然后扩展:

public class Tier1 extends Tier {

    @Field("tier1")
    private Tier1Programs tier1;

    public Tier1() {
        this.tier1 = new Tier1Programs();
    }

    public Tier1Programs getTier1() {
        return tier1;
    }

    public void setTier1(Tier1Programs tier1) {
        this.tier1 = tier1;
    }
}

依次扩展:

public class Tier2 extends Tier1 {

    @Field("tier2")
    private Tier2Programs tier2;

    public Tier2() {
        this.tier2 = new Tier2Programs();
    }

    public Tier2Programs getTier2() {
        return tier2;
    }

    public void setTier2(Tier2Programs tier2) {
        this.tier2 = tier2;
    }
}

在 MongoRepository 接口中有一个使用 Tier1 类的 Tier1 Supervisor(Spring Boot 应用程序):

There is a Tier1 Supervisor (Spring Boot Application) that uses the Tier1 class within the MongoRepository interface:

public interface Tier1Repository extends MongoRepository<Tier1,String>{}

用于检索和保存 - 没问题.

for retrieving and saving - no issue.

然后我有一个使用 Tier1 存储库(用于检索 Tier1 文档和用于保存 Tier2 文档的 Tier2 存储库)的 Tier2 Supervisor(Spring Boot 应用程序):

I then have a Tier2 Supervisor (Spring Boot Application) that uses a Tier1 Repository (for retrieving the Tier1 document and a Tier2 Repository for saving the Tier2 document:

@Repository("tier1Repository")
public interface Tier1Repository extends MongoRepository<Tier1,String>{}

@Repository("tier2Repository")
public interface Tier2Repository extends MongoRepository<Tier2,String>{}

我的服务是:

@Service
public class TierService {
    @Qualifier("tier1Repository")
    @Autowired
    private final Tier1Repository tier1Repository;
    @Qualifier("tier2Repository")
    @Autowired
    private final Tier2Repository tier2Repository;

    public TierService(@Qualifier("tier1Repository") Tier1Repository tier1Repository, @Qualifier("tier2Repository") Tier2Repository tier2Repository) {
        this.tier1Repository = tier1Repository;
        this.tier2Repository = tier2Repository;
    }

    public Tier1 findOne(String id) {
        return tier1Repository.findOne(id);
    }

    public void SaveTier(Tier2 tier) {
        tier2Repository.save(tier);
    }

    public Tier1Repository getTier1Repository() {
        return tier1Repository;
    }

    public Tier2Repository getTier2Repository() {
        return tier2Repository;
    }
}

最后是应用程序:

@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class,
    DataSourceTransactionManagerAutoConfiguration.class, JdbcTemplateAutoConfiguration.class})
@Configuration
@ComponentScan(basePackages = {"com.k12commercial.tier2supervisor"})
@ImportResource("classpath:application-context.xml")
public class Application implements CommandLineRunner {

    @Autowired
    private IReceiver raBidNetPriceReceiver;

    @Autowired
    private UdyDataSourceFactory udyDSRegistry;

    public static void main(String[] args) throws InterruptedException {
        try {
            SpringApplication.run(Application.class, args);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }    

    @Override
    public void run(String... args) throws Exception {
        raBidNetPriceReceiver.processTierMessages();
        exit(0);
    }
}

当我从命令行运行 Tier2 Supervisor 时,出现以下错误:

When I run the Tier2 Supervisor from the command line I get the following error:

org.springframework.beans.factory.UnsatisfiedDependencyException:使用 URL 中定义的名称tierService"创建 bean 时出错[jar:file:/opt/java-commandline/tier2supervisor-1.0.jar!/BOOT-INF/classes!/com/k12commercial/tier2supervisor/service/TierService.class]:通过构造函数参数1表示的不满足的依赖;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为tier2Repository"的 bean 时出错:调用 init 方法失败;嵌套异常是 org.springframework.data.mapping.model.MappingException: Ambiguous field mapping detected!private final java.lang.reflect.Type org.springframework.data.util.TypeDiscoverer.type 和 private final java.lang.Class org.springframework.data.util.ClassTypeInformation.type 映射到相同的字段名称类型!使用@Field 注释消除歧义!

我不确定问题是否是 Tier2 扩展 Tier1(尝试将 @Document 标签放在 Tier1 和 Tier2 之上,没有任何变化).我想我已经标记了相关领域,所以不明白消除歧义的必要性.我认为问题是有 2 个存储库(Spring Boot 不知道要 DI 哪个)所以删除了 Tier1Repository - 没有用.尝试更好地限定存储库,但仍然出现相同的错误.我将 Tier1 和 Tier2 @Transient 设置为删除了消息,但也删除了 mongo 文档中的 tier1 部分 - 所以错误更正.

I am not sure if the issue is Tier2 extending Tier1 (did try putting @Document tag above Tier1 and Tier2 with no change). I think I have marked the relevant fields so don't understand the need to disambiguate. I thought the issue was having 2 repositories (Spring Boot not knowing which one to DI) so removed the Tier1Repository - didn't work. Tried better qualifying the repositories but still got the same error. I made Tier1 and Tier2 @Transient and that got rid of the message but also removed the tier1 section in the mongo document - so wrong correction.

认为这是一个注释修复,但没有看到...

Thinking it is an annotation fix but not seeing it...

请指教 - 谢谢.

推荐答案

很抱歉耽搁了(我被拉去做其他事情)并感谢回复的人.

Sorry for the delay (I got pulled away to work on something else) and thank you to those who responded.

问题是我的层级程序中有一个 MongoTemplate,例如 Spring Boot 试图自动装配的 Tier2Programs(子库).

The issue was I had a MongoTemplate in my Tier level programs e.g.Tier2Programs (sub library) which Spring Boot was trying to autowire.

通过将 Mongo (CRUD) 要求移至主管级别(为了简化,我还用一个 MongoTemplate 替换了存储库),我消除了歧义.(我还删除了 Service 类).

By moving the Mongo (CRUD) requirements to the supervisor level (I also replaced the Repositories with one MongoTemplate to simplify) I removed the ambiguity. (I also removed the Service class).

代码包含在 RaBidNetReciever 类中

The code is contained with the RaBidNetReciever class

    @Component
public class RaBidNetPriceReceiver extends BaseReceiver implements IReceiver, ApplicationEventPublisherAware {
    private static final Logger LOGGER = LoggerFactory.getLogger(RaBidNetPriceReceiver.class);
    private final RabbitTemplate raBidNetPriceRabbitTemplate;

    public RaBidNetPriceReceiver(MongoTemplate mongoTemplate, RabbitTemplate raBidNetPriceRabbitTemplate) {
    super(mongoTemplate);
    this.raBidNetPriceRabbitTemplate = raBidNetPriceRabbitTemplate;
    }

    @Transactional
    public void processTierMessages() {
    try {
        while (true) {
            gson = getGsonBuilder().create();
            byte[] body = (byte[]) raBidNetPriceRabbitTemplate.receiveAndConvert();
            if (body == null) {
                setFinished(true);
                break;
            }
            tier1Message = gson.fromJson(new String(body), Tier1Message.class);
            // document a 'Tier1' type so retrieve Tier1 first...
            Tier1 tier1 = mongoTemplate.findById(tier1Message.getId(), Tier1.class);

            Tier2Message tier2Message = new Tier2Message(tier1Message.getTran(), tier1Message.getId());
            Tier2Process tierProcess = getTierProcess(tier2Message.getTran().getK12ArchitectureId());

            Tier2 tier2 = new Tier2();
            tier2.setId(tier1.getId());
            tier2.setTier1Programs(tier1.getTier1Programs());
            tier2.setCreated(tier1.getCreated());
            tier2.setTran(tier1.getTran());

            tierProcess.setTier(tier2);
            tier2 = tier2.getTier2Programs().getRaBidNetPriceProgram().process(tierProcess);
            mongoTemplate.save(tier2);

            if (tier2.getTier2Programs().getRaBidNetPriceProgram().isFinished()) {
                // publish event
                publisher.publishEvent(new ProgramEvent(this, "FINISHED", tier2Message));
            }
        }

     } catch (Exception e) {
        LOGGER.error("id: " + tier1Message.getId() + " " + e.getMessage());
     }
    }

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
    this.publisher = applicationEventPublisher;
    }
}

谢谢,

这篇关于MappingException:检测到不明确的字段映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆