java - Exception while creating index - Spring Data MongoDB -


i'm using spring-data spring-data mongodb map entity class using @compoundindexes annotation in i'm specifying indexes both names , definitions. in production environment, decided needed change of attributes of index based on actual data. every time application starts up, fails load because failure create index matching specification in annotation results , exception thrown during initialization process (as seen below).

is there anyway of configuring spring data , mongodb these exceptions logged not fail start of container?

exception while creating index ! com.mongodb.mongocommandexception: command failed error 86: 'trying create index same name event_source_link_type_at_id_idx different key spec **** vs existing spec *****' on server 127.0.0.1:27017. full response { "ok" : 0.0, "errmsg" : "trying create index same name event_source_link_type_at_id_idx different key spec **** vs existing spec *****", "code" : 86 } ! @ com.mongodb.connection.protocolhelper.getcommandfailureexception(protocolhelper.java:115) ~[mongodb-driver-core-3.2.2.jar:na] ! @ com.mongodb.connection.commandprotocol.execute(commandprotocol.java:114) ~[mongodb-driver-core-3.2.2.jar:na] ! @ com.mongodb.connection.defaultserver$defaultserverprotocolexecutor.execute(defaultserver.java:159) ~[mongodb-driver-core-3.2.2.jar:na] ! @ com.mongodb.connection.defaultserverconnection.executeprotocol(defaultserverconnection.java:286) ~[mongodb-driver-core-3.2.2.jar:na] ! @ com.mongodb.connection.defaultserverconnection.command(defaultserverconnection.java:173) ~[mongodb-driver-core-3.2.2.jar:na] ! @ com.mongodb.operation.commandoperationhelper.executewrappedcommandprotocol(commandoperationhelper.java:215) ~[mongodb-driver-core-3.2.2.jar:na] ! @ com.mongodb.operation.commandoperationhelper.executewrappedcommandprotocol(commandoperationhelper.java:198) ~[mongodb-driver-core-3.2.2.jar:na] ! @ com.mongodb.operation.commandoperationhelper.executewrappedcommandprotocol(commandoperationhelper.java:170) ~[mongodb-driver-core-3.2.2.jar:na] ! @ com.mongodb.operation.createindexesoperation$1.call(createindexesoperation.java:116) ~[mongodb-driver-core-3.2.2.jar:na] ! @ com.mongodb.operation.createindexesoperation$1.call(createindexesoperation.java:111) ~[mongodb-driver-core-3.2.2.jar:na] ! @ com.mongodb.operation.operationhelper.withconnectionsource(operationhelper.java:230) ~[mongodb-driver-core-3.2.2.jar:na] ! @ com.mongodb.operation.operationhelper.withconnection(operationhelper.java:221) ~[mongodb-driver-core-3.2.2.jar:na] ! @ com.mongodb.operation.createindexesoperation.execute(createindexesoperation.java:111) ~[mongodb-driver-core-3.2.2.jar:na] ! @ com.mongodb.operation.createindexesoperation.execute(createindexesoperation.java:66) ~[mongodb-driver-core-3.2.2.jar:na] ! @ com.mongodb.mongo.execute(mongo.java:781) ~[mongodb-driver-3.2.2.jar:na] ! @ com.mongodb.mongo$2.execute(mongo.java:764) ~[mongodb-driver-3.2.2.jar:na] ! @ com.mongodb.dbcollection.createindex(dbcollection.java:1541) ~[mongodb-driver-3.2.2.jar:na] ! @ org.springframework.data.mongodb.core.index.mongopersistententityindexcreator.createindex(mongopersistententityindexcreator.java:142) [spring-data-mongodb-1.8.4.release.jar:na] 

turns out isn't easy thought can done few classes.

first need override class creates indexes , overwrite method creates indexes, trapping exceptions match , logging them.

unfortunately package protected need create class in same package class we're extending.

package org.springframework.data.mongodb.core.index;  import org.slf4j.logger; import org.slf4j.loggerfactory; import org.springframework.data.mongodb.mongodbfactory; import org.springframework.data.mongodb.core.mapping.mongomappingcontext;  public class exceptionignoringindexcreator extends mongopersistententityindexcreator {      //assuming slf4j logger otherwise, put logger here     private static final logger log = loggerfactory.getlogger(exceptionignoringindexcreator.class);      public exceptionignoringindexcreator(mongomappingcontext mappingcontext, mongodbfactory mongodbfactory) {         super(mappingcontext, mongodbfactory);     }      @override     void createindex(mongopersistententityindexresolver.indexdefinitionholder indexdefinition) {         try {             super.createindex(indexdefinition);         } catch (final runtimeexception exp) {             final runtimeexception trans = translate(exp);             if (trans != null) {                 throw trans;             } else {                 log.warn("exception while creating index", exp);             }         }     }      protected runtimeexception translate(final runtimeexception exp) {         if (exp == null || exp.getmessage().contains("cannot create index")) {             return null;         }         return exp;     } } 

the index creation triggered event published mongomappingcontext using applicationeventpublisherinterface. need class can lazily set applicationeventpublisher delegate 2 methods of interface delegate calls to.

public class delegatingpublisher implements applicationeventpublisher {          private applicationeventpublisher delegate;          @override         public void publishevent(applicationevent event) {             delegate.publishevent(event);         }          @override         public void publishevent(object event) {             delegate.publishevent(event);         }          public void setdelegate(applicationeventpublisher delegate) {             this.delegate = delegate;         }  } 

normally configure spring data mongodb using class extends abstractmongoconfig , overrides "mongo()" method.

the component responsible publishing message initializes indexes 1 returned "mongomappingcontext()" you'll need override method , extend default mongomappingcontext overriding method sets event publisher , passing our new delegate publisher in place.

@configuration @enablemongorepositories("com.my.company") public class mymongoconfig extends abstractmongoconfiguration { ...     @override     @bean     public mongomappingcontext mongomappingcontext() throws classnotfoundexception {         final delegatingpublisher dep = new delegatingpublisher();         final mongomappingcontext mappingcontext = new mongomappingcontext() {             @override             public void setapplicationeventpublisher(applicationeventpublisher applicationeventpublisher) {                 super.setapplicationeventpublisher(dep);             }         };         mappingcontext.setinitialentityset(getinitialentityset());         mappingcontext.setsimpletypeholder(customconversions().getsimpletypeholder());         mappingcontext.setfieldnamingstrategy(fieldnamingstrategy());          try {             final mongopersistententityindexcreator indexcreator = new exceptionignoringindexcreator(mappingcontext, mongodbfactory());             dep.setdelegate(new mongomappingeventpublisher(indexcreator));             return mappingcontext;         } catch (exception exp) {             throw new runtimeexception(exp);         }     } ... } 

if use xml based configuration, you'll need 1 more class , specified configuration

public class eventdelegatingmongomappingcontext extends mongomappingcontext {      private applicationeventpublisher publisher;      public eventdelegatingmongomappingcontext(applicationeventpublisher publisher) {         this.publisher = publisher;         }      @override     public void setapplicationeventpublisher(applicationeventpublisher applicationeventpublisher) {         super.setapplicationeventpublisher(publisher);     } } 
<mongo:db-factory id="mongodbfactory"                   host="localhost"                   port="27017"                   dbname="database"                   username="mycompany"                   password="secret"/>  <bean id="delegatingpublisher" class="com.my.company.delegatingpublisher">     <property name="delegate" ref="mappingeventpublisher" /> </bean>  <!-- must named 'mongomappingcontext' recognized --> <bean id="mongomappingcontext" class="com.my.company.eventdelegatingmongomappingcontext">     <constructor-arg>         <bean ref="delegatingpublisher" />     </constructor-arg> </bean>  <bean id="mongoindexcreator" class="org.springframework.data.mongodb.core.index.exceptionignoringindexcreator">     <constructor-arg>         <bean ref="mongomappingcontext"/>     </constructor-arg>     <constructor-arg>         <bean ref="mongodbfactory"/>     </constructor-arg> </bean>  <bean id="mappingeventpublisher" class="org.springframework.data.mongodb.core.index.mongomappingeventpublisher">     <constructor-arg>         <bean ref="mongoindexcreator"/>     </constructor-arg> </bean> 

Comments

Popular posts from this blog

php - How to display all orders for a single product showing the most recent first? Woocommerce -

asp.net - How to correctly use QUERY_STRING in ISAPI rewrite? -

angularjs - How restrict admin panel using in backend laravel and admin panel on angular? -