I am new to Spring data and mongodb. I have a JSON object which represents a JSON Schema and I need to store that in mongodb using spring data. But the issue with JSON schema is the structure of JSON Schema is dynamic; for example below are two valid JSON schema with completely different structure.
{
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 10
},
"age": {
"type": "integer"
}
},
"required": [
"name",
"age"
]
}
{
"type": "array",
"items": {
"type": "object",
"properties": {
"abc": {
"type": "boolean"
},
"xyz": {
"$ref": "#/definitions/"
},
"asd": {
"type": "null"
}
},
"required": [
"abc",
"xyz"
]
}
}
How can I define a JAVA POJO Class so that I can map the above JSON with the defined class and store it in mongodb. Or is it possible to do CURD operation in spring without mapping it to a POJO class?
To store raw json object/array, all you have to do is to declare the type as "Object" in the Pojo and/or DTO level on your server side. The "Object" type will work with Spring Data and MapStruct too. Then on the client side, you can send your json data as a json data.
Does MongoDB use BSON or JSON? MongoDB stores data in BSON format both internally, and over the network, but that doesn't mean you can't think of MongoDB as a JSON database. Anything you can represent in JSON can be natively stored in MongoDB, and retrieved just as easily in JSON.
Yes, DataNucleus JPA allows it, as well as to many other databases. You make compromises by using the JPA API for other types of datastores, but it makes it easy to investigate them.
Spring Boot is the easiest way to spin a spring project quickly and MongoDB is the most popular NoSQL database. Let's see how to integrate spring with MongoDB database.
I would recommend using MongoTemplate and serialize and deserailize using Gson/Jackson.
Mongo Template have CRUD methods which takes collection name and DBObject entity which is very similar to if you were to directly use mongo java driver.
So you will have json payload and using one of the mapper library to convert them into Map
.
Something like
Deserialise
ObjectMapper mapper = new ObjectMapper();
TypeReference<HashMap<String,Object>> typeRef
= new TypeReference<HashMap<String,Object>>() {};
HashMap<String,Object> map = mapper.readValue(jsonpayload, typeRef);
DBObject
DBObject dbObject = new BasicDBObject(map);
MongoTemplate
mongoTemplate.save(dbObject, "collectionname");
You can do something similar for all other CRUD operations.
Please find here the necessary code.
@lombok.Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class Bounty {
String type;
Map<String, Object> items;
Map<String, Object> properties;
List<Object> required;
}
Here is my repository class
public interface BountyRepository extends MongoRepository<Bounty, String> {
}
And here is a controller snippet which u can use to try it out
@GetMapping("/insert/{number}")
public void insert(@PathVariable int number){
bountyRepository.save(getBounty(number));
}
public Bounty getBounty(int number){
ObjectMapper objectMapper = new ObjectMapper();
String jsonString1 = "{\n" +
" \"type\": \"object\",\n" +
" \"properties\": {\n" +
" \"name\": {\n" +
" \"type\": \"string\",\n" +
" \"minLength\": 10\n" +
" },\n" +
" \"age\": {\n" +
" \"type\": \"integer\"\n" +
" }\n" +
" },\n" +
" \"required\": [\n" +
" \"name\",\n" +
" \"age\"\n" +
" ]\n" +
"}";
String jsonString2 = "{\n" +
" \"type\": \"array\",\n" +
" \"items\": {\n" +
" \"type\": \"object\",\n" +
" \"properties\": {\n" +
" \"abc\": {\n" +
" \"type\": \"boolean\"\n" +
" },\n" +
" \"xyz\": {\n" +
" \"$ref\": \"#/definitions/\"\n" +
" },\n" +
" \"asd\": {\n" +
" \"type\": \"null\"\n" +
" }\n" +
" },\n" +
" \"required\": [\n" +
" \"abc\",\n" +
" \"xyz\"\n" +
" ]\n" +
" }\n" +
"}";
try {
Bounty bounty1 = objectMapper.readValue(jsonString1, Bounty.class);
Bounty bounty2 = objectMapper.readValue(jsonString2, Bounty.class);
if (number == 1) return bounty1;
if (number == 2) return bounty2;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
This is how it looks like in Mongo after save.
/* 1 */
{
"_id" : ObjectId("58da2390fde4f133178499fa"),
"_class" : "pani.kiran.sumne.model.Bounty",
"type" : "object",
"properties" : {
"name" : {
"type" : "string",
"minLength" : 10
},
"age" : {
"type" : "integer"
}
},
"required" : [
"name",
"age"
]
}
/* 2 */
{
"_id" : ObjectId("58da23adfde4f133178499fb"),
"_class" : "pani.kiran.sumne.model.Bounty",
"type" : "array",
"items" : {
"type" : "object",
"properties" : {
"abc" : {
"type" : "boolean"
},
"xyz" : {
"$ref" : "#/definitions/"
},
"asd" : {
"type" : "null"
}
},
"required" : [
"abc",
"xyz"
]
}
}
In my project I had a very dynamic structure of my models and I mapped them by using a java.util.Map
object
this is how my mondo document model has been implemented:
@Document(collection = "e_form_data")
public class FormDataModel extends AbstractModel
{
private static final long serialVersionUID = -1733975205300782871L;
@Field
@Indexed(name = "e_form_id_idx")
private String eFormId;
@Field
private Map<String, Object> eFormData;
public FormDataModel()
{
super();
}
public FormDataModel(String id, String creatoDa, String modificatoDa, Date dataCreazione, Date dataModifica, String eFormId, Map<String, Object> eFormData)
{
super(id, creatoDa, modificatoDa, dataCreazione, dataModifica);
this.eFormData = eFormData;
this.eFormId = eFormId;
}
public FormDataModel(Map<String, Object> eFormData)
{
super();
this.eFormData = eFormData;
}
public Map<String, Object> geteFormData()
{
return eFormData;
}
public void seteFormData(Map<String, Object> eFormData)
{
this.eFormData = eFormData;
}
public String geteFormId()
{
return eFormId;
}
public void seteFormId(String eFormId)
{
this.eFormId = eFormId;
}
public String getDataInserimento()
{
return Utils.formatDateTime(new DateTime(this.dataCreazione.getTime()), "dd/MM/yyyy");
}
@Override
public String toString()
{
return "FormDataModel [eFormId=" + eFormId + ", eFormData=" + eFormData + "]";
}
}
By using this all works pretty good
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With