maven - Spring Boot Dev Tools: Crash on hot reload with CommandLineRunners and Spring Data Repositories -
i'm developing project spring boot 1.3.2, spring data mongodb , spring security, using dev tools, intellij idea 15.0.3, using maven.
i did read spring boot developer tools documentation, , configured indicated, , hot reload worked fine.
then, since needed perform tasks during application startup, connecting database , perform validations, , insertions if needed, decided use commandlinerunner
beans this:
@configuration public class databaseinitializer { @bean commandlinerunner verifyconfiguration(configurationrepository repository) { return args -> { // id provided 1 , can't modify it. if (repository.findone(...) == null) { // offending line //perform tasks here } }; } // more commandlinerunners following same approach }
if restart application, works fine, no crashes, no errors, when trigger dev tools hot reload, fails, , throws stacktrace:
java.lang.illegalstateexception: failed execute commandlinerunner @ org.springframework.boot.springapplication.callrunner(springapplication.java:809) [spring-boot-1.3.2.release.jar:1.3.2.release] @ org.springframework.boot.springapplication.callrunners(springapplication.java:790) [spring-boot-1.3.2.release.jar:1.3.2.release] @ org.springframework.boot.springapplication.afterrefresh(springapplication.java:777) [spring-boot-1.3.2.release.jar:1.3.2.release] @ org.springframework.boot.springapplication.run(springapplication.java:308) [spring-boot-1.3.2.release.jar:1.3.2.release] @ org.springframework.boot.springapplication.run(springapplication.java:1191) [spring-boot-1.3.2.release.jar:1.3.2.release] @ org.springframework.boot.springapplication.run(springapplication.java:1180) [spring-boot-1.3.2.release.jar:1.3.2.release] @ com.adrisasws.gestor.cesteriaapariciapplication.main(cesteriaapariciapplication.java:15) [classes/:na] @ sun.reflect.nativemethodaccessorimpl.invoke0(native method) ~[na:1.8.0_72] @ sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:62) ~[na:1.8.0_72] @ sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:43) ~[na:1.8.0_72] @ java.lang.reflect.method.invoke(method.java:498) ~[na:1.8.0_72] @ org.springframework.boot.devtools.restart.restartlauncher.run(restartlauncher.java:49) [spring-boot-devtools-1.3.2.release.jar:1.3.2.release] caused by: org.springframework.data.mapping.model.mappinginstantiationexception: failed instantiate com.adrisasws.gestor.configuracion.api.outputs.configuracionfacturacion using constructor no_constructor arguments @ org.springframework.data.convert.reflectionentityinstantiator.createinstance(reflectionentityinstantiator.java:64) ~[spring-data-commons-1.11.2.release.jar:na] @ org.springframework.data.convert.classgeneratingentityinstantiator.createinstance(classgeneratingentityinstantiator.java:83) ~[spring-data-commons-1.11.2.release.jar:na] @ org.springframework.data.mongodb.core.convert.mappingmongoconverter.read(mappingmongoconverter.java:251) ~[spring-data-mongodb-1.8.2.release.jar:na] @ org.springframework.data.mongodb.core.convert.mappingmongoconverter.read(mappingmongoconverter.java:231) ~[spring-data-mongodb-1.8.2.release.jar:na] @ org.springframework.data.mongodb.core.convert.mappingmongoconverter.readvalue(mappingmongoconverter.java:1186) ~[spring-data-mongodb-1.8.2.release.jar:na] @ org.springframework.data.mongodb.core.convert.mappingmongoconverter.access$200(mappingmongoconverter.java:78) ~[spring-data-mongodb-1.8.2.release.jar:na] @ org.springframework.data.mongodb.core.convert.mappingmongoconverter$mongodbpropertyvalueprovider.getpropertyvalue(mappingmongoconverter.java:1134) ~[spring-data-mongodb-1.8.2.release.jar:na] @ org.springframework.data.mongodb.core.convert.mappingmongoconverter.getvalueinternal(mappingmongoconverter.java:870) ~[spring-data-mongodb-1.8.2.release.jar:na] @ org.springframework.data.mongodb.core.convert.mappingmongoconverter$1.dowithpersistentproperty(mappingmongoconverter.java:283) ~[spring-data-mongodb-1.8.2.release.jar:na] @ org.springframework.data.mongodb.core.convert.mappingmongoconverter$1.dowithpersistentproperty(mappingmongoconverter.java:271) ~[spring-data-mongodb-1.8.2.release.jar:na] @ org.springframework.data.mapping.model.basicpersistententity.dowithproperties(basicpersistententity.java:309) ~[spring-data-commons-1.11.2.release.jar:na] @ org.springframework.data.mongodb.core.convert.mappingmongoconverter.read(mappingmongoconverter.java:271) ~[spring-data-mongodb-1.8.2.release.jar:na] @ org.springframework.data.mongodb.core.convert.mappingmongoconverter.read(mappingmongoconverter.java:231) ~[spring-data-mongodb-1.8.2.release.jar:na] @ org.springframework.data.mongodb.core.convert.mappingmongoconverter.read(mappingmongoconverter.java:191) ~[spring-data-mongodb-1.8.2.release.jar:na] @ org.springframework.data.mongodb.core.convert.mappingmongoconverter.read(mappingmongoconverter.java:187) ~[spring-data-mongodb-1.8.2.release.jar:na] @ org.springframework.data.mongodb.core.convert.mappingmongoconverter.read(mappingmongoconverter.java:78) ~[spring-data-mongodb-1.8.2.release.jar:na] @ org.springframework.data.mongodb.core.mongotemplate$readdbobjectcallback.dowith(mongotemplate.java:2224) ~[spring-data-mongodb-1.8.2.release.jar:na] @ org.springframework.data.mongodb.core.mongotemplate.executefindoneinternal(mongotemplate.java:1855) ~[spring-data-mongodb-1.8.2.release.jar:na] @ org.springframework.data.mongodb.core.mongotemplate.dofindone(mongotemplate.java:1672) ~[spring-data-mongodb-1.8.2.release.jar:na] @ org.springframework.data.mongodb.core.mongotemplate.findbyid(mongotemplate.java:614) ~[spring-data-mongodb-1.8.2.release.jar:na] @ org.springframework.data.mongodb.repository.support.simplemongorepository.findone(simplemongorepository.java:119) ~[spring-data-mongodb-1.8.2.release.jar:na] @ sun.reflect.nativemethodaccessorimpl.invoke0(native method) ~[na:1.8.0_72] @ sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:62) ~[na:1.8.0_72] @ sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:43) ~[na:1.8.0_72] @ java.lang.reflect.method.invoke(method.java:498) ~[na:1.8.0_72] @ org.springframework.data.repository.core.support.repositoryfactorysupport$queryexecutormethodinterceptor.executemethodon(repositoryfactorysupport.java:483) ~[spring-data-commons-1.11.2.release.jar:na] @ org.springframework.data.repository.core.support.repositoryfactorysupport$queryexecutormethodinterceptor.doinvoke(repositoryfactorysupport.java:468) ~[spring-data-commons-1.11.2.release.jar:na] @ org.springframework.data.repository.core.support.repositoryfactorysupport$queryexecutormethodinterceptor.invoke(repositoryfactorysupport.java:440) ~[spring-data-commons-1.11.2.release.jar:na] @ org.springframework.aop.framework.reflectivemethodinvocation.proceed(reflectivemethodinvocation.java:179) ~[spring-aop-4.2.4.release.jar:4.2.4.release] @ org.springframework.data.projection.defaultmethodinvokingmethodinterceptor.invoke(defaultmethodinvokingmethodinterceptor.java:61) ~[spring-data-commons-1.11.2.release.jar:na] @ org.springframework.aop.framework.reflectivemethodinvocation.proceed(reflectivemethodinvocation.java:179) ~[spring-aop-4.2.4.release.jar:4.2.4.release] @ org.springframework.aop.interceptor.exposeinvocationinterceptor.invoke(exposeinvocationinterceptor.java:92) ~[spring-aop-4.2.4.release.jar:4.2.4.release] @ org.springframework.aop.framework.reflectivemethodinvocation.proceed(reflectivemethodinvocation.java:179) ~[spring-aop-4.2.4.release.jar:4.2.4.release] @ org.springframework.aop.framework.jdkdynamicaopproxy.invoke(jdkdynamicaopproxy.java:208) ~[spring-aop-4.2.4.release.jar:4.2.4.release] @ com.sun.proxy.$proxy160.findone(unknown source) ~[na:na] @ com.adrisasws.gestor.inicializacion.lambda$inicializacionconfiguracion$1(inicializacion.java:47) ~[classes/:na] @ org.springframework.boot.springapplication.callrunner(springapplication.java:806) [spring-boot-1.3.2.release.jar:1.3.2.release] ... 11 common frames omitted caused by: org.springframework.beans.beaninstantiationexception: failed instantiate [com.adrisasws.gestor.configuracion.api.outputs.configuracionfacturacion]: specified class interface @ org.springframework.beans.beanutils.instantiateclass(beanutils.java:101) ~[spring-beans-4.2.4.release.jar:4.2.4.release] @ org.springframework.data.convert.reflectionentityinstantiator.createinstance(reflectionentityinstantiator.java:61) ~[spring-data-commons-1.11.2.release.jar:na] ... 47 common frames omitted
i'm aware complains of configuracionfacturacion
being interface, 1 of properties of document declared interface, in code, instantiate concrete implementation, said, works fine on normal startup, , during execution.
so questions are:
- why work fails on hot reload?, bug , should submit issue?
- or bad practice use abstractions in entity classes annotated
@document
, should consider refactoring?
p.s. if need more information, ask it, , i'll update question.
update: first time commandlinerunner
runs, when element in database not present, findone()
call returns null, hot reload, not fail.
update2: avoiding findone()
, , using exists()
, count()
instead whenever possible, solves problem, doesn't seem definitive solution, since, fortunately, in use case don't need access data, check if present, or know how many records there are, in other use cases, data access mandatory, developers can't enjoy benefits of hot reload devtools.
if of help, here's more information particular issue:
in specific case of spring data mongodb, when field in @document
class declared interface, in database, in embedded document representing field, property named _class
, value of qualified class name of concrete implementation inserted, example:
public class addressdocument implements address { ... } @document public class persondocument { private address address; ... }
when performing following operation:
persondocument p = new persondocument(); p.setaddress(new addressdocument(...)); repository.save(p);
then mongo document stored in database have following form:
{ ... address : { "_class" : "package.addressdocument", ... } ... }
so obvious think spring data using _class
determine class use in order able instantiate class, , reason, devtools bypassing mechanism.
Thanks for the blog article.Much thanks again. Fantastic.
ReplyDeletepython online training
python training