使用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;
}
}
有一个Tier1 Supervisor(Spring Boot Application)在MongoRepository接口中使用Tier1类:
public interface Tier1Repository extends MongoRepository<Tier1,String>{}
用于检索和保存 - 没问题。
然后我有一个使用Tier1存储库的Tier2 Supervisor(Spring Boot应用程序)(用于检索Tier1文档和用于保存Tier2文档的Tier2存储库:
@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;
}
}
最后是app:
@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:
Error creating bean with name 'tierService' defined in URL
[jar:file:/opt/java-commandline/tier2supervisor-1.0.jar!/BOOT-INF/classes!/com/k12commercial/tier2supervisor/service/TierService.class]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tier2Repository': Invocation of init method failed; nested exception is org.springframework.data.mapping.model.MappingException: Ambiguous field mapping detected! Both private final java.lang.reflect.Type org.springframework.data.util.TypeDiscoverer.type and private final java.lang.Class org.springframework.data.util.ClassTypeInformation.type map to the same field name type! Disambiguate using @Field annotation!
我不确定问题是否是Tier2扩展Tier1(确实尝试将@Document标记放在Tier1和Tier2之上而没有变化)。我想我已经标记了相关领域,所以不了解消除歧义的必要性。我认为这个问题有2个存储库(Spring Boot不知道哪个存储器到DI)所以删除了Tier1Repository - 没有工作。尝试更好地限定存储库但仍然得到相同的错误。我制作了Tier1和Tier2 @Transient并删除了该消息,但也删除了mongo文档中的tier1部分 - 所以错误的更正。
认为这是一个注释修复但没有看到它......
请指教 - 谢谢。
答案 0 :(得分:0)
对不起延迟(我被拉开去处理其他事情)并感谢那些回复的人。
问题是我在我的Tier级程序中有一个MongoTemplate,例如Spring Boot试图自动装配的Tim2Programs(子库)。
通过将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;
}
}
谢谢,