miércoles, 18 de mayo de 2016

Custom behavior for embedded documents using Spring Data Mongo repositories

One of the most common tasks when working with entity-relation models is create relations between tables N to M. This involves creating three tables in the relational model. Sometimes, this behavior is also necessary to apply it for non-relational models like mongodb. In this case, we could have a main document which it contains an embedded document with (N to M) relational information. An example could be, when we want save the orders references into users document, all in the same document of users, using mongo embedded documents.

Of course, do something like this is very easy with Spring Data MongoDB. The problem is when we want to add or update items in the embedded document. Imagine the following scenario, a user make an order and adds the order reference to the users document, and before saving, his brother with the same account, adds another order reference to the basket, (the order reference is saved into user document with the same key of user). When some of them save the user document with order references, one of these two references will be lost. The problem is that when we save the document with Spring Data Mongo is saved according what we have previously read, so it could have concurrency problems.


To solve this problem, I thing that we should perform the operations to add or update items of a embedded document, using addToSet and set mongo operators. In this way,  we can add or update items partially to the embedded documents, without affecting others items, because we work directly with database and not with the memory.


¿How does it work?


We configure repositoryFactoryBeanClass for spring data repository can use the new feature.



We create the document that we will embed into the main document. Carful !!, the embedded document must have an identifier for each item, we must mark the identifier property with the attribute @Id



We create the main document that contain the embedded document. In our case, the embedded document is TestMongoEmbedeedEntity type.

 
We create the repository class that reference to TestMongoEntity document.



 
We are ready to perform the operations to add and update items in embedded document.

Steps:

1) We wire repository.

 

2) We call mergeEmbeddedRelation method of the repository that will insert or update in the collection for each embedded item. The function know whether can insert or update depending of if the item exists or don't exist in mongodb collection.

 

Parameters of mergeEmbeddedRelation:

testMongoEntity: Main document. Main document contains the embedded items that will be insert or update.

"embeddedEntities" : Define the property to get the embedded document items

 


To see all code click here.