Compound index does not currently support nested documents or arrays in Azure Cosmos MongoDB - mongodb

Connecting Javers API with Azure Cosmos MongoDB
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'JaversFromStarter' defined in class path resource [com/test/config/JaversMongoAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.javers.core.Javers]: Factory method 'javers' threw exception; nested exception is com.mongodb.MongoCommandException: Command failed with error 115 (CommandNotSupported): 'Compound index does not currently support nested documents or arrays.' on server azurecosommongo:10255. The full response is { "ok" : 0.0, "errmsg" : "Compound index does not currently support nested documents or arrays.", "code" : 115, "codeName" : "CommandNotSupported" }
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:627) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:456) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1305) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1144) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:593) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
... 22 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.javers.core.Javers]: Factory method 'javers' threw exception; nested exception is com.mongodb.MongoCommandException: Command failed with error 115 (CommandNotSupported): 'Compound index does not currently support nested documents or arrays.' on server azurecosommongo:10255. The full response is { "ok" : 0.0, "errmsg" : "Compound index does not currently support nested documents or arrays.", "code" : 115, "codeName" : "CommandNotSupported" }
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:622) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
... 35 common frames omitted
Caused by: com.mongodb.MongoCommandException: Command failed with error 115 (CommandNotSupported): 'Compound index does not currently support nested documents or arrays.' on server azurecosommongo:10255. The full response is { "ok" : 0.0, "errmsg" : "Compound index does not currently support nested documents or arrays.", "code" : 115, "codeName" : "CommandNotSupported" }
at com.mongodb.internal.connection.ProtocolHelper.getCommandFailureException(ProtocolHelper.java:179) ~[mongodb-driver-core-3.8.2.jar:na]
at com.mongodb.internal.connection.InternalStreamConnection.receiveCommandMessageResponse(InternalStreamConnection.java:293) ~[mongodb-driver-core-3.8.2.jar:na]
at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:255) ~[mongodb-driver-core-3.8.2.jar:na]
Below is Configuration which I added to support the connection. But I am getting an exception on app startup only. I am able to connect with simple MongoDB but with Cosmos API I am getting the
Compound index does not currently support nested documents or arrays.
#Autowired
private JaversMongoProperties javersMongoProperties;
#Autowired
private MongoDbFactory mongoDbFactory; //from spring-boot-starter-data-mongodb
#Autowired
#Qualifier("javersMongoClientOptions")
private Optional<MongoClientOptions> mongoClientOptions;
#Bean(name = "JaversFromStarter")
#ConditionalOnMissingBean
public Javers javers() {
logger.info("Starting javers-spring-boot-starter-mongo ...");
MongoDatabase mongoDatabase = initJaversMongoDatabase();
MongoRepository javersRepository = createMongoRepository(mongoDatabase);
return JaversBuilder.javers()
.registerJaversRepository(javersRepository)
.withProperties(javersMongoProperties)
.withObjectAccessHook(javersMongoProperties.createObjectAccessHookInstance())
.build();
}
private MongoDatabase initJaversMongoDatabase() {
if (!javersMongoProperties.isDedicatedMongodbConfigurationEnabled()) {
MongoDatabase mongoDatabase = mongoDbFactory.getDb();
logger.info("connecting Javers to Mongo database '{}' configured in spring.data.mongodb properties",
mongoDatabase.getName());
return mongoDatabase;
} else {
MongoDatabase mongoDatabase = JaversDedicatedMongoFactory.createMongoDatabase(javersMongoProperties, mongoClientOptions);
logger.info("connecting Javers to Mongo database '{}' configured in javers.mongodb properties",
mongoDatabase.getName());
return mongoDatabase;
}
}

You are using wrong method to create MongoRepository. You should use this one:
/**
* MongoRepository compatible with Amazon DocumentDB.
* <br/>
*
* Compound index on <code>commitProperties</code> isn't created.
* <br/><br/>
*
* See functional differences.
*/
public static MongoRepository mongoRepositoryWithDocumentDBCompatibility(MongoDatabase mongo, int cacheSize) {
return new MongoRepository(mongo, cacheSize, DOCUMENT_DB);
}

Related

ConfigurableMongoDbMessageStore Failed to instantiate [org.springframework.messaging.support.GenericMessage]

I am trying to use the ConfigurableMongoDbMessageStore as a message-store in my spring-integration aggregator component. For some reason the following exception is thrown:
Caused by: org.springframework.data.mapping.model.MappingInstantiationException: Failed to instantiate org.springframework.messaging.support.GenericMessage using constructor NO_CONSTRUCTOR with arguments
at org.springframework.data.convert.ReflectionEntityInstantiator.createInstance(ReflectionEntityInstantiator.java:67)
at org.springframework.data.convert.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:84)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:272)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:245)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readValue(MappingMongoConverter.java:1491)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$MongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1389)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$AssociationAwareMongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1438)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$AssociationAwareMongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1401)
at org.springframework.data.mapping.model.PersistentEntityParameterValueProvider.getParameterValue(PersistentEntityParameterValueProvider.java:71)
at org.springframework.data.mapping.model.SpELExpressionParameterValueProvider.getParameterValue(SpELExpressionParameterValueProvider.java:49)
at org.springframework.data.convert.ClassGeneratingEntityInstantiator$EntityInstantiatorAdapter.extractInvocationArguments(ClassGeneratingEntityInstantiator.java:250)
at org.springframework.data.convert.ClassGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(ClassGeneratingEntityInstantiator.java:223)
at org.springframework.data.convert.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:84)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:272)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:245)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:194)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:190)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:78)
at org.springframework.data.mongodb.core.MongoTemplate$ReadDocumentCallback.doWith(MongoTemplate.java:3017)
at org.springframework.data.mongodb.core.MongoTemplate.executeFindMultiInternal(MongoTemplate.java:2673)
at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:2404)
at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:2387)
at org.springframework.data.mongodb.core.MongoTemplate.find(MongoTemplate.java:823)
at org.springframework.data.mongodb.core.MongoTemplate.findOne(MongoTemplate.java:772)
at org.springframework.integration.mongodb.store.ConfigurableMongoDbMessageStore.getMessageGroup(ConfigurableMongoDbMessageStore.java:115)
at org.springframework.integration.mongodb.store.ConfigurableMongoDbMessageStore.addMessageToGroup(ConfigurableMongoDbMessageStore.java:138)
at org.springframework.integration.aggregator.AbstractCorrelatingMessageHandler.store(AbstractCorrelatingMessageHandler.java:757)
at org.springframework.integration.aggregator.AbstractCorrelatingMessageHandler.handleMessageInternal(AbstractCorrelatingMessageHandler.java:479)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:162)
... 83 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.messaging.support.GenericMessage]: No default constructor found; nested exception is java.lang.NoSuchMethodException: org.springframework.messaging.support.GenericMessage.<init>()
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:129)
at org.springframework.data.convert.ReflectionEntityInstantiator.createInstance(ReflectionEntityInstantiator.java:64)
... 111 common frames omitted
Caused by: java.lang.NoSuchMethodException: org.springframework.messaging.support.GenericMessage.<init>()
at java.base/java.lang.Class.getConstructor0(Class.java:3350)
at java.base/java.lang.Class.getDeclaredConstructor(Class.java:2554)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:122)
... 112 common frames omitted
The bean is created and used as follows:
In SpringIntegrationBeans.java
#Autowired
private MongoTemplate mongoTemplate;
#Bean(name = "configurableMongoDbMessageStore")
public ConfigurableMongoDbMessageStore configurableMongoDbMessageStore() {
return new ConfigurableMongoDbMessageStore(mongoTemplate);
}
In spring-integration.xml
<int:aggregator id="myAggregator"
ref="testingAggregator"
message-store="configurableMongoDbMessageStore"/>
I am using the following spring-integration-mongodb package:
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-mongodb</artifactId>
<version>5.1.2.RELEASE</version>
</dependency>
I found similar q&a in Spring Integration Aggregator with MongoDbMessageStore: Failed to instantiate GenericMessage: No default constructor found but that seems to be applicable for MongoDbMessageStore rather than ConfigurableMongoDbMessageStore
I would appreciate any help/advice.
The mongo template needs a suitably configured converter; inject the db factory instead and the store will create an appropriate template.
#Autowired
private MongoDbFactory dbFactory;
#Bean(name = "configurableMongoDbMessageStore")
public ConfigurableMongoDbMessageStore configurableMongoDbMessageStore() {
return new ConfigurableMongoDbMessageStore(dbFactory);
}

Exception in querying mongodb using spring boot

I am trying to query MongoDB with the following code. Though as per documentation it seems correct I am still getting runtime exception at the time of execution of the query. Please let me know if there is anything wrong.
#Repository
public interface UserRepository extends MongoRepository<User, String> {
#Query("{'mobileNumber': ?0, 'password': ?1 }")
User findByLogin(String mobileNumber, String password);
}
Exception:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.bson.json.JsonParseException: JSON reader was expecting ':' but found 'password'.] with root cause
org.bson.json.JsonParseException: JSON reader was expecting ':' but found 'password'.
at org.bson.json.JsonReader.readBsonType(JsonReader.java:132) ~[bson-3.6.3.jar!/:na]
at org.bson.codecs.DocumentCodec.decode(DocumentCodec.java:149) ~[bson-3.6.3.jar!/:na]
at org.bson.codecs.DocumentCodec.decode(DocumentCodec.java:45) ~[bson-3.6.3.jar!/:na]
at org.bson.Document.parse(Document.java:105) ~[bson-3.6.3.jar!/:na]
at org.bson.Document.parse(Document.java:90) ~[bson-3.6.3.jar!/:na]
at org.springframework.data.mongodb.core.query.BasicQuery.<init>(BasicQuery.java:67) ~[spring-data-mongodb-2.0.6.RELEASE.jar!/:2.0.6.RELEASE]
at org.springframework.data.mongodb.repository.query.StringBasedMongoQuery.createQuery(StringBasedMongoQuery.java:136) ~[spring-data-mongodb-2.0.6.RELEASE.jar!/:2.0.6.RELEASE]
at org.springframework.data.mongodb.repository.query.AbstractMongoQuery.execute(Abstra

Spring Cloud Config Zookeeper Exception

I am trying to use Spring cloud config with zookeeper for configuration management.
My build.gradle looks like:
dependencies {
compile('org.springframework.boot:spring-boot-starter-actuator')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.cloud:spring-cloud-starter-zookeeper-config')
compile('org.springframework.cloud:spring-cloud-config-server')
}
Here is my bootstrap.properties file:
spring.application.name = myapp
spring.cloud.zookeeper.connectString: localhost:2181
This is the application class:
#SpringBootApplication
#EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
But the application fails to launch and gives an exception:
Error starting Tomcat context.
Exception: org.springframework.beans.factory.BeanCreationException.
Message: Error creating bean with name 'servletEndpointRegistrar'
defined in class path resource
[org/springframework/boot/actuate/autoconfigure/endpoint/web/ServletEndpointManagementContextConfiguration.class]
: Bean instantiation via factory method failed;
nested exception is org.springframework.beans.BeanInstantiationException
: Failed to instantiate [org.springframework.boot.actuate.endpoint.web.ServletEndpointRegistrar]
: Factory method 'servletEndpointRegistrar' threw exception;
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'healthEndpoint'
defined in class path
resource [org/springframework/boot/actuate/autoconfigure/health/HealthEndpointConfiguration.class]
: Bean instantiation via factory method failed;
nested exception is org.springframework.beans.BeanInstantiationException
: Failed to instantiate [org.springframework.boot.actuate.health.HealthEndpoint]
: Factory method 'healthEndpoint' threw exception;
nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException
: Error creating bean with name 'configServerHealthIndicator'
defined in class path resource
[org/springframework/cloud/config/server/config/EnvironmentRepositoryConfiguration.class]
: Unsatisfied dependency expressed through
method 'configServerHealthIndicator' parameter 0;
nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException
: Error creating bean with name 'org.springframework.cloud.config.server.config.CompositeConfiguration'
: Unsatisfied dependency expressed through method 'setEnvironmentRepos' parameter 0;
nested exception is org.springframework.beans.factory.BeanCreationException
: Error creating bean with name
'defaultEnvironmentRepository' defined in class path
resource [org/springframework/cloud/config/server/config/DefaultRepositoryConfiguration.class]
: Bean instantiation via factory method failed;
nested exception is org.springframework.beans.BeanInstantiationException
: Failed to instantiate
[org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentRepository]
: Factory method 'defaultEnvironmentRepository' threw exception;
nested exception is java.lang.NullPointerException
What could be the reason behind this? Seems like it is searching for git repository even after specifying zookeeper.

"invalid hexadecimal representation" for spring mongo data repository interface

I have a repository interface as follows:
public interface ExcursionAttendeeRepository extends MongoRepository<ExcursionAttendee, String> {
ExcursionAttendee findByWorkflowItemId(String workflowItemId);
#Query("{ 'excursionEvent._id' : { '$oid' : ?0 } }")
List<ExcursionAttendee> findByExcursionId(String excursionId);
#Query("{ 'student._id' : {'$oid' : ?0} , 'excursionEvent._id' : { '$oid' : ?1 } }")
ExcursionAttendee findByStudentIdAndEventId(String studentId, String excursionId);
#Query("{ 'student._id' : { '$oid' : ?0 } }")
List<ExcursionAttendee> findByStudentId(String studentId);
}
While Bean creation spring throws following exception.
Context initialization failed: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer#0.1':
Cannot create inner bean '(inner bean)#5172829b' of type [org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter] while setting bean property 'messageListener';
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#5172829b':
Cannot resolve reference to bean 'productDetailsEventConsumer' while setting bean property 'delegate';
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'productDetailsEventConsumer': Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.cinglevue.veip.service.excursion.ExcursionAttendeeService com.cinglevue.veip.service.erp.impl.ProductDetailsEventConsumer.excursionAttendeeService;
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'excursionAttendeeServiceImpl': Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.cinglevue.veip.repository.excursion.ExcursionAttendeeRepository com.cinglevue.veip.service.excursion.impl.ExcursionAttendeeServiceImpl.excursionAttendeeRepository;
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'excursionAttendeeRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: invalid hexadecimal representation of an ObjectId: [_param_0]
Ideally this exceptions should get thrown when trying to initialise a ObjectId with an invalid string. [ code ]. I'm wondering how the class gets initialised in order for an exception to get thrown while bean creation. Any tips on this?
I ran into the same question and following should work.
#Query("{ 'student' : { '$id': ?0 } }")
List<ExcursionAttendee> findByStudentId(String studentId);
If it is a DBRef it should be like this, (This is what im using after the same issue, I have a DBRef in my case)
#Query("{ 'student': {'$ref': 'user', '$id': ?0} }")
List<ExcursionAttendee> findByStudentId(String studentId);
For DBRef this should work as well,
List<ExcursionAttendee> findByStudentId(String studentId);
I found the answer from here.
#Query("{ 'student._id' : {'$oid' : ?0} , 'excursionEvent._id' : { '$oid' : ?1 } }")
ExcursionAttendee findByStudentIdAndEventId(String studentId, String excursionId);
You don't need to specify #Query if you follow spring-data method naming conventions.
The query should work with
#Query("{ 'student._id' : ?0} , 'excursionEvent._id' : ?1 } }")
Reference: https://jira.spring.io/si/jira.issueviews:issue-html/DATAMONGO-1070/DATAMONGO-1070.html

mongoDB async driver java - unable to connect with authentication

Recently we've updated our mongoDB with port 35489 and also with authentication and roles to the database.
I've granted readWrite and readWriteAnyDatabase roles for a user and can successfully connect from our c# coding from mentioning it from the web.config
My web.config:
<add key="MongoConnectionString" value="mongodb://readWriteUser:********#192.168.1.225:35489/admin" />
Now, my problem is I'm uanble to connect to mongoDB from java async driver and it is throwing an exception like
Exception
Exception in monitor thread while connecting to server localhost:35489 com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=null, userName='AdminAllDatabases', source='admin', password=, mechanismProperties={}} at com.mongodb.connection.SaslAuthenticator.authenticate(SaslAuthenticator.java:61) at com.mongodb.connection.DefaultAuthenticator.authenticate(DefaultAuthenticator.java:32) at com.mongodb.connection.InternalStreamConnectionInitializer.authenticateAll(InternalStreamConnectionInitializer.java:99) at com.mongodb.connection.InternalStreamConnectionInitializer.initialize(InternalStreamConnectionInitializer.java:44) at com.mongodb.connection.InternalStreamConnection.open(InternalStreamConnection.java:115) at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:127) at java.lang.Thread.run(Unknown Source) Caused by: com.mongodb.MongoCommandException: Command failed with error 18: 'Authentication failed.' on server localhost:35489. The full response is { "ok" : 0.0, "code" : 18, "errmsg" : "Authentication failed." } at com.mongodb.connection.CommandHelper.createCommandFailureException(CommandHelper.java:170) at com.mongodb.connection.CommandHelper.receiveCommandResult(CommandHelper.java:123) at com.mongodb.connection.CommandHelper.executeCommand(CommandHelper.java:32) at com.mongodb.connection.SaslAuthenticator.sendSaslContinue(SaslAuthenticator.java:99) at com.mongodb.connection.SaslAuthenticator.authenticate(SaslAuthenticator.java:58) ... 6 common frames omitted
My async java driver code:
public static final String DEFAULT_URI = "mongodb://readWriteUser:******#localhost:35489/";
public static synchronized ConnectionString getConnectionString()
{
if (connectionString == null)
{
connectionString = new ConnectionString(DEFAULT_URI);
}
return connectionString;
}
public static synchronized MongoClient getMongoClient()
{
if (mongoClient == null)
{
mongoClient = MongoClients.create(getConnectionString());
}
return mongoClient;
}
we've tried with both localhost and ip address, but nothing seems to work.
Can anyone suggest me the right way to do this?