使用 Spring boot 1.5.6.RELEASE。
我有以下 mongo 文档基类:
@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 接口(interface)中有一个使用 Tier1 类的 Tier1 主管(Spring Boot 应用程序):
public interface Tier1Repository extends MongoRepository<Tier1,String>{}
用于检索和保存 - 没问题。
然后我有一个使用 Tier1 存储库(用于检索 Tier1 文档和 Tier2 存储库用于保存 Tier2 文档)的 Tier2 Supervisor(Spring Boot 应用程序):
@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 时,出现以下错误:
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:检测到不明确的字段映射! private final java.lang.reflect.Type org.springframework.data.util.TypeDiscoverer.type 和 private final java.lang.Class org.springframework.data.util.ClassTypeInformation.type 映射到相同的字段名称类型!使用@Field 注释消除歧义!
我不确定问题是否出在第 2 层扩展第 1 层(尝试将 @Document 标记放在第 1 层和第 2 层之上,没有任何变化)。我想我已经标记了相关领域所以不明白需要消除歧义。我认为问题是有 2 个存储库(Spring Boot 不知道要 DI 哪个)所以删除了 Tier1Repository - 没有用。尝试更好地限定存储库,但仍然出现相同的错误。我制作了 Tier1 和 Tier2 @Transient,这消除了消息,但也删除了 mongo 文档中的 tier1 部分 - 所以错误更正。
认为这是一个注释修复但没有看到它......
请指教 - 谢谢。
最佳答案
抱歉耽搁了(我被拉去处理其他事情)并感谢那些回复的人。
问题是我的层级程序中有一个 MongoTemplate,例如 Spring Boot 试图 Autowiring 的 Tier2Programs(子库)。
通过将 Mongo (CRUD) 要求移到主管级别(我还用一个 MongoTemplate 替换了存储库以简化),我消除了歧义。 (我还删除了服务类)。
代码包含在 RaBidNetReciever 类中
@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;
}
}
谢谢,
关于spring-data-mongodb - 映射异常 : Ambiguous field mapping detected,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46120786/