java - Spring Batch with two different datasource issue -
i have simple spring batch application that's pulling records database , printing rows screen. simple poc application.
the application works fine spring boot 1.2.1.release when updated 1.2.3.release error message "no qualifying bean of type [javax.sql.datasource] defined"
i'm not sure if spring boot issue or spring batch issue.
is there way define datasource explicitly spring batch repository?
full stack trace.
org.springframework.beans.factory.beancreationexception: error creating bean name 'org.springframework.batch.core.configuration.annotation.simplebatchconfiguration': injection of autowired dependencies failed; nested exception org.springframework.beans.factory.beancreationexception: not autowire field: private java.util.collection org.springframework.batch.core.configuration.annotation.abstractbatchconfiguration.datasources; nested exception org.springframework.beans.factory.beancreationexception: error creating bean name 'datasource' defined in class path resource [demo/batchconfiguration.class]: initialization of bean failed; nested exception org.springframework.beans.factory.beancreationexception: error creating bean name 'datasourceinitializer': invocation of init method failed; nested exception org.springframework.beans.factory.nouniquebeandefinitionexception: no qualifying bean of type [javax.sql.datasource] defined: expected single matching bean found 2: datasource,consumerappointmentdatasource @ org.springframework.beans.factory.annotation.autowiredannotationbeanpostprocessor.postprocesspropertyvalues(autowiredannotationbeanpostprocessor.java:334) @ org.springframework.beans.factory.support.abstractautowirecapablebeanfactory.populatebean(abstractautowirecapablebeanfactory.java:1210) @ org.springframework.beans.factory.support.abstractautowirecapablebeanfactory.docreatebean(abstractautowirecapablebeanfactory.java:537) @ org.springframework.beans.factory.support.abstractautowirecapablebeanfactory.createbean(abstractautowirecapablebeanfactory.java:476) @ org.springframework.beans.factory.support.abstractbeanfactory$1.getobject(abstractbeanfactory.java:303) @ org.springframework.beans.factory.support.defaultsingletonbeanregistry.getsingleton(defaultsingletonbeanregistry.java:230) @ org.springframework.beans.factory.support.abstractbeanfactory.dogetbean(abstractbeanfactory.java:299) @ org.springframework.beans.factory.support.abstractbeanfactory.getbean(abstractbeanfactory.java:194) @ org.springframework.beans.factory.support.defaultlistablebeanfactory.preinstantiatesingletons(defaultlistablebeanfactory.java:755) @ org.springframework.context.support.abstractapplicationcontext.finishbeanfactoryinitialization(abstractapplicationcontext.java:757) @ org.springframework.context.support.abstractapplicationcontext.refresh(abstractapplicationcontext.java:480) @ org.springframework.boot.springapplication.refresh(springapplication.java:686) @ org.springframework.boot.springapplication.run(springapplication.java:320) @ org.springframework.boot.springapplication.run(springapplication.java:957) @ org.springframework.boot.springapplication.run(springapplication.java:946) @ demo.application.main(application.java:13) caused by: org.springframework.beans.factory.beancreationexception: not autowire field: private java.util.collection org.springframework.batch.core.configuration.annotation.abstractbatchconfiguration.datasources; nested exception org.springframework.beans.factory.beancreationexception: error creating bean name 'datasource' defined in class path resource [demo/batchconfiguration.class]: initialization of bean failed; nested exception org.springframework.beans.factory.beancreationexception: error creating bean name 'datasourceinitializer': invocation of init method failed; nested exception org.springframework.beans.factory.nouniquebeandefinitionexception: no qualifying bean of type [javax.sql.datasource] defined: expected single matching bean found 2: datasource,consumerappointmentdatasource @ org.springframework.beans.factory.annotation.autowiredannotationbeanpostprocessor$autowiredfieldelement.inject(autowiredannotationbeanpostprocessor.java:561) @ org.springframework.beans.factory.annotation.injectionmetadata.inject(injectionmetadata.java:88) @ org.springframework.beans.factory.annotation.autowiredannotationbeanpostprocessor.postprocesspropertyvalues(autowiredannotationbeanpostprocessor.java:331) ... 15 common frames omitted caused by: org.springframework.beans.factory.beancreationexception: error creating bean name 'datasource' defined in class path resource [demo/batchconfiguration.class]: initialization of bean failed; nested exception org.springframework.beans.factory.beancreationexception: error creating bean name 'datasourceinitializer': invocation of init method failed; nested exception org.springframework.beans.factory.nouniquebeandefinitionexception: no qualifying bean of type [javax.sql.datasource] defined: expected single matching bean found 2: datasource,consumerappointmentdatasource @ org.springframework.beans.factory.support.abstractautowirecapablebeanfactory.docreatebean(abstractautowirecapablebeanfactory.java:547) @ org.springframework.beans.factory.support.abstractautowirecapablebeanfactory.createbean(abstractautowirecapablebeanfactory.java:476) @ org.springframework.beans.factory.support.abstractbeanfactory$1.getobject(abstractbeanfactory.java:303) @ org.springframework.beans.factory.support.defaultsingletonbeanregistry.getsingleton(defaultsingletonbeanregistry.java:230) @ org.springframework.beans.factory.support.abstractbeanfactory.dogetbean(abstractbeanfactory.java:299) @ org.springframework.beans.factory.support.abstractbeanfactory.getbean(abstractbeanfactory.java:194) @ org.springframework.beans.factory.support.defaultlistablebeanfactory.findautowirecandidates(defaultlistablebeanfactory.java:1120) @ org.springframework.beans.factory.support.defaultlistablebeanfactory.doresolvedependency(defaultlistablebeanfactory.java:996) @ org.springframework.beans.factory.support.defaultlistablebeanfactory.resolvedependency(defaultlistablebeanfactory.java:942) @ org.springframework.beans.factory.annotation.autowiredannotationbeanpostprocessor$autowiredfieldelement.inject(autowiredannotationbeanpostprocessor.java:533) ... 17 common frames omitted caused by: org.springframework.beans.factory.beancreationexception: error creating bean name 'datasourceinitializer': invocation of init method failed; nested exception org.springframework.beans.factory.nouniquebeandefinitionexception: no qualifying bean of type [javax.sql.datasource] defined: expected single matching bean found 2: datasource,consumerappointmentdatasource @ org.springframework.beans.factory.annotation.initdestroyannotationbeanpostprocessor.postprocessbeforeinitialization(initdestroyannotationbeanpostprocessor.java:136) @ org.springframework.beans.factory.support.abstractautowirecapablebeanfactory.applybeanpostprocessorsbeforeinitialization(abstractautowirecapablebeanfactory.java:408) @ org.springframework.beans.factory.support.abstractautowirecapablebeanfactory.initializebean(abstractautowirecapablebeanfactory.java:1566) @ org.springframework.beans.factory.support.abstractautowirecapablebeanfactory.docreatebean(abstractautowirecapablebeanfactory.java:539) @ org.springframework.beans.factory.support.abstractautowirecapablebeanfactory.createbean(abstractautowirecapablebeanfactory.java:476) @ org.springframework.beans.factory.support.abstractbeanfactory$1.getobject(abstractbeanfactory.java:303) @ org.springframework.beans.factory.support.defaultsingletonbeanregistry.getsingleton(defaultsingletonbeanregistry.java:230) @ org.springframework.beans.factory.support.abstractbeanfactory.dogetbean(abstractbeanfactory.java:299) @ org.springframework.beans.factory.support.abstractbeanfactory.getbean(abstractbeanfactory.java:217) @ org.springframework.beans.factory.support.defaultlistablebeanfactory.getbean(defaultlistablebeanfactory.java:350) @ org.springframework.beans.factory.support.defaultlistablebeanfactory.getbean(defaultlistablebeanfactory.java:331) @ org.springframework.boot.autoconfigure.jdbc.datasourceinitializerpostprocessor.postprocessafterinitialization(datasourceinitializerpostprocessor.java:62) @ org.springframework.beans.factory.support.abstractautowirecapablebeanfactory.applybeanpostprocessorsafterinitialization(abstractautowirecapablebeanfactory.java:422) @ org.springframework.beans.factory.support.abstractautowirecapablebeanfactory.initializebean(abstractautowirecapablebeanfactory.java:1579) @ org.springframework.beans.factory.support.abstractautowirecapablebeanfactory.docreatebean(abstractautowirecapablebeanfactory.java:539) ... 26 common frames omitted caused by: org.springframework.beans.factory.nouniquebeandefinitionexception: no qualifying bean of type [javax.sql.datasource] defined: expected single matching bean found 2: datasource,consumerappointmentdatasource @ org.springframework.beans.factory.support.defaultlistablebeanfactory.getbean(defaultlistablebeanfactory.java:365) @ org.springframework.beans.factory.support.defaultlistablebeanfactory.getbean(defaultlistablebeanfactory.java:331) @ org.springframework.context.support.abstractapplicationcontext.getbean(abstractapplicationcontext.java:968) @ org.springframework.boot.autoconfigure.jdbc.datasourceinitializer.init(datasourceinitializer.java:67) @ sun.reflect.nativemethodaccessorimpl.invoke0(native method) @ sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:57) @ sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:43) @ java.lang.reflect.method.invoke(method.java:606) @ org.springframework.beans.factory.annotation.initdestroyannotationbeanpostprocessor$lifecycleelement.invoke(initdestroyannotationbeanpostprocessor.java:349) @ org.springframework.beans.factory.annotation.initdestroyannotationbeanpostprocessor$lifecyclemetadata.invokeinitmethods(initdestroyannotationbeanpostprocessor.java:300) @ org.springframework.beans.factory.annotation.initdestroyannotationbeanpostprocessor.postprocessbeforeinitialization(initdestroyannotationbeanpostprocessor.java:133) ... 40 common frames omitted
sample code
@configuration @enablebatchprocessing public class batchconfiguration { @bean @configurationproperties(prefix = "datasource") public datasource datasource() { return datasourcebuilder.create().build(); } @bean @configurationproperties(prefix = "datasource.consumerappointment") public datasource consumerappointmentdatasource() { return datasourcebuilder.create().build(); } @bean public job importuserjob(jobbuilderfactory jobs, step s1) { return jobs.get("importuserjob") .incrementer(new runidincrementer()) .flow(s1) .end() .build(); } @bean public step step1(stepbuilderfactory stepbuilderfactory, itemreader<appointmentverification> reader, itemprocessor<appointmentverification, appointmentverification> processor) { return stepbuilderfactory.get("step1") .<appointmentverification, appointmentverification> chunk(10) .reader(reader) .processor(processor) .build(); } @bean public itemprocessor<appointmentverification, appointmentverification> processorappointmentverification() { return new appointmentverificationitemprocessor(); } @bean public itemreader<appointmentverification> appointmentverificationreader(datasource consumerappointmentdatasource) { jdbccursoritemreader<appointmentverification> reader = new jdbccursoritemreader<appointmentverification>(); string sql = "select * test"; reader.setsql(sql); reader.setdatasource(consumerappointmentdatasource); reader.setrowmapper(rowmapper()); return reader; } private rowmapper<appointmentverification> rowmapper() { return new rowmapper<appointmentverification>() { @override public appointmentverification maprow(resultset rs, int i) throws sqlexception { appointmentverification appointmentverification = new appointmentverification(); appointmentverification.setemail(rs.getstring("cnsm_eml_adr")); return appointmentverification; } }; } }
edited fix: updated main datasource primary created batchconfigurer bean. add @qualifier itemreader
@configuration @enablebatchprocessing public class batchconfiguration { @primary @bean @configurationproperties(prefix = "datasource.batch") public datasource batchdatasource() { return datasourcebuilder.create().build(); } @bean @configurationproperties(prefix = "datasource.consumerappointment") public datasource consumerappointmentdatasource() { return datasourcebuilder.create().build(); } @bean public batchconfigurer configurer(datasource batchdatasource){ return new defaultbatchconfigurer(batchdatasource); } @bean public job importuserjob(jobbuilderfactory jobs, step s1) { return jobs.get("importuserjob") .incrementer(new runidincrementer()) .flow(s1) .end() .build(); } @bean public step step1(stepbuilderfactory stepbuilderfactory, itemreader<appointmentverification> reader, itemwriter<appointmentverification> messagewriter) { return stepbuilderfactory.get("step1") .<appointmentverification, appointmentverification> chunk(10) .reader(reader) .writer(messagewriter) .build(); } @bean public itemreader<appointmentverification> appointmentverificationreader(@qualifier(value = "consumerappointmentdatasource") datasource consumerappointmentdatasource) { jdbccursoritemreader<appointmentverification> reader = new jdbccursoritemreader<appointmentverification>(); string sql = "select * test"; reader.setsql(sql); reader.setdatasource(consumerappointmentdatasource); reader.setrowmapper(rowmapper()); return reader; } private rowmapper<appointmentverification> rowmapper() { return new rowmapper<appointmentverification>() { @override public appointmentverification maprow(resultset rs, int i) throws sqlexception { appointmentverification appointmentverification = new appointmentverification(); appointmentverification.setemail(rs.getstring("cnsm_eml_adr")); return appointmentverification; } }; }
mark 1 of beans primary
@primary @bean @configurationproperties(prefix = "datasource.consumerappointment") public datasource consumerappointmentdatasource() { return datasourcebuilder.create().build(); }
then create batchconfigurer it
@bean batchconfigurer configurer(datasource datasource){ return new defaultbatchconfigurer(datasource); }
Comments
Post a Comment