Spring Data documentation describes how to create collection with given $jsonSchema, and how to perform a validation query.
Is there a way to update $jsonSchema for an existing collection? MongoTemplate.createCollection() for an existing one results in MongoCommandException with error code 48 (collection exists), schema is not being updated.
Ok, looks like there is no ready-to-use method in Spring Data, but it is pretty simple to implement:
<T> void updateSchema(MongoTemplate template, Class<T> entityClazz, MongoJsonSchema schema) {
template.executeCommand(new Document(Map.of(
"collMod", template.getCollectionName(entityClazz),
"validator", schema.toDocument()
)));
}
Also keep in mind that default readWrite role is not enough, user needs to have collMod privilege.
Related
I want to create an ETL process using Spring Batch, the steps will be read from a DB(s) and insert in one DB so basically I'm collecting similar information from different DB and inserting them in one DB, I have a large complex query that I need to run on those DBs and the result will be inserted in the so called one DB for later processing, my main concert is that I want to reference this query in the JpaPagingItemReader for example, it there a way I can for example add this query in my project as .sql file and then reference it in the reader?
Or any other solution I can follow?
Thank you
it there a way I can for example add this query in my project as .sql file and then reference it in the reader? Or any other solution I can follow?
You can put your query in a properties file and inject in your reader, something like:
#Configuration
#EnableBatchProcessing
#PropertySource("classpath:application.properties")
public class MyJob {
#Bean
public JpaPagingItemReader itemReader(#Value("${query}") String query) {
return new JpaPagingItemReaderBuilder<>()
.queryString(query)
// set other reader properties
.build();
}
// ...
}
In this example, you should have a property query=your sql query in application.properties. This is actually the regular Spring property injection mechanism, nothing Spring Batch specific here.
Service
session.startTransaction();
DAO
db.getCollection("test").withWriteConcern(WriteConcern.MAJORITY);
target.insertOne(session,contents);
Service
session.commitTransaction();
how to
MongoTemplate withWriteConcern???
I'm curious how to withWriteConcern from mongotemplate.
You can use the MongoTemplate's method setWriteConcern
to specify the write concern for your write action on the MongoDB collection.
From Spring-Data MongoDB documentation on WriteConcern:
10.4.3.
WriteConcern:
If it has not yet been specified through the driver at a higher level
(such as com.mongodb.MongoClient), you can set the
com.mongodb.WriteConcern property that the MongoTemplate uses for
write operations. If the WriteConcern property is not set, it defaults
to the one set in the MongoDB driver’s DB or Collection setting.
Another way of configuring the write concern on MongoTemplate is by using the WriteConcernResolver interface.
From Spring-Data MongoDB documentation on WriteConcernResolver:
10.4.4.
WriteConcernResolver:
For more advanced cases where you want to set different WriteConcern
values on a per-operation basis (for remove, update, insert, and save
operations), a strategy interface called WriteConcernResolver can be
configured on MongoTemplate. Since MongoTemplate is used to persist
POJOs, the WriteConcernResolver lets you create a policy that can map
a specific POJO class to a WriteConcern value...
MongoTemplate#setWriteConcernResolver
WriteConcernResolver
I am using Spring Data with MongoDB to store very dynamic config data in a toolkit. These Config objects consist of a few organizational fields, along with a data field of type Object. On some instances of Config, the data object refers to a more deeply nested subdocument (such as "data.foo.bar" within the database. – this field name is set by getDataField() below). These Config objects are manipulated as they're sent to the database, so the storage code looks something like this:
MongoTemplate template; // This is autowired into the class.
Query query; // This is the same query which (successfully) finds the object.
Config myConfig; // The config to create or update in Mongo
Update update = new Update()
.set(getDataField(), myConfig.getData())
.set(UPDATE_TIME_FIELD, new Date())
.setOnInsert(CREATE_TIME_FIELD, new Date())
.setOnInsert(NAME_FIELD, myConfig.getName());
template.upsert(query, update, Config.class);
Spring recursively converts the data object into a DBObject correctly, but neither the data document nor any of its subdocuments have "_class" fields in the database. Consequentially, they do not deserialize correctly.
These issues seem quite similar to those previously reported in DATAMONGO-392 , DATAMONGO-407, and DATAMONGO-724. Those, however, have all been fixed. (I am using spring-data-mongodb 1.4.2.RELEASE)
Am I doing something incorrectly? Is there a possibility that this is a Spring issue?
Came across a similar issue. One solution is to write your own Converter for Config.class.
spring-data-mongodb. How can i dynamically create a database in mongo using spring-data-mongodb library?
I am trying to use Spring-Mongodb-Data module for CRUD operations against Mongo database and going through examples and articles my assumption is that databasename should be pre-defined in spring context xml when defining MongoTemplate bean.
In my case I have an multi-tenant application that will accept requests over http and my application should create the mongodatabase on-the-fly and use the name provided in the input http request to create the database and then load the data into collection in the newly created database.
I am trying to figure out if there is a way to dynamically populate the databasename in MongoTemplate or MongoRepository without having to provide it in spring context.xml?
Please help me.
Thanks
-RK
Have you tried the following instead of going through the pre-defined spring context configuration.
MongoTemplate getMongoTemplate(Mongo mongo, String database) {
return new MongoTemplate(mongo, database);
}
I have 2 entities that needed to be persisted in two different DB's:
1) MyClassMetaData - persisted on mysql via jpa+hibernate in spring (entityManager)
2) MyClassRawData - persisted on mongoDB via spring data (mongoTemplate)
There is a one To one Relation between the two entities:
There is no meaning for only one entitiesto be persisted without the other.
there will always be a metadata AND rawdata for each save.
My service for saving these 2 entities looks like this
#Transactional
public void saveMyClass(metadata, rawdata){
// Do Something here
this.entityManager.persist(metadata);
this.mongoTemplate.save(rawData);
}
My question is: how do i make sure that if an error occurs on this save method - a rollback will take place and for both classes?
thanks
This might be what you want to achieve: http://static.springsource.org/spring-data/mongodb/docs/current/reference/html/mongo.cross.store.html
However it ties the two entities strictly together.