Spring Data Mongodb DBRef联级存储
来源:互联网 发布:数据库编辑软件 编辑:程序博客网 时间:2024/06/09 01:05
Spring Data MongoDB by default does not support cascade operations on referenced objects with @DBRef annotations as reference says:
The mapping framework does not handle cascading saves. If you change an Account object that is referenced by a Person object, you mustsave the Account object separately. Calling save on the Person object will not automatically save the Account objects in the property accounts.
That’s quite problematic because in order to achieve saving child objects you need to override save method in repository in parent or create additional service
methods like it is presented in here.
In this article I will show you how it can be achieved for all documents using generic implementation of AbstractMongoEventListener.
@CascadeSave annotation
Because we can’t change @DBRef annotation by adding cascade property lets create new annotation @CascadeSave that will be used to mark which fields should be saved when parent object is saved.
CascadingMongoEventListener
Next part is to implement handler for this annotation. We will use for that powerful Spring Application Event mechanism. In particular we will extendAbstractMongoEventListener to catch saved object before it is converted to Mongo’s DBObject.
How does it work? When object MongoTemplate#save method is called, before object is actually saved it is being converted into DBObject from MongoDB api. CascadingMongoEventListener implemented below provides hook that catches object before its converted and:
- goes through all its fields to check if there are fields annotated with @DBRef and @CascadeSave at once.
- when field is found it checks if @Id annotation is present
- child object is being saved
Mapping requirements
As you can see in order to make thing work you need to follow some rules:
- parent’s class child property has to be mapped with @DBRef and @CascadeSave
- child class needs to have property annotated with @Id and if that id is supposed to be autogenerated it should by type of ObjectId
Usage
In order to use cascade saving in your project you need just to register CascadingMongoEventListener in Spring Context:
Let’s test it
In order to show an example I made two document classes:
In test there is one user with address created and then user is saved. Test will cover only positive scenario and its just meant to show that it actually works (applcationContext-tests.xml
contains only default Spring Data MongoDB beans and CascadingMongoEventListener registered):
We can check that also in Mongo console:
Summary
With this simple solution we can finally save child objects with one method call without implementing anything special for each document class.
I believe that we will find this functionality together with cascade delete as part Spring Data MongoDB release in the future. Solution presented here works but:
- it requires to use additional annotation
- uses reflection API to iterate through fields which is not the fastest way to do it (but feel free to implement caching if needed)
If that could be part of Spring Data MongoDB instead of additional annotation @DBRef could have additional property cascade
. Instead of reflection we could useMongoMappingContext together with MongoPersistentEntity. I’ve started already to prepare pull request with those changes. We will see if it will be accepted by Spring Source team.
- Spring Data Mongodb DBRef联级存储
- spring-data-mongodb 对象关联 @DBRef学习 之疑问
- spring-mongodb-DBRef的运用
- spring-mongodb-data存储文件
- mongoDB中的DBRef
- mongodb数据库引用DBRef
- Mongo DBRef 存储
- MongoDB 通过 DBRef关联查询
- spring-data 集成mongodb
- Spring-data集成mongodb
- MongoDB集成Spring Data
- Spring Data for Mongodb
- MongoDB集成Spring Data
- spring data MongoDB分页
- Spring data MongoDB
- Spring data Mongodb
- Spring Data MongoDB
- mongodb spring-data 使用
- 如何使用Word
- linux中$#、$?、$$[脚本运行时当前进程的id号]、$@、$*、$0、$1、$2、$-[上一个命令的最后一个参数]
- Android之ExpandableListView的属性(Group不展开)
- 动态列核心代码
- #ifdef,#else,#if,#endif (转载)
- Spring Data Mongodb DBRef联级存储
- 嵌入式系统之常用接口技术
- iOS推送技术
- Elasticsearch:检索篇
- 常用meta整理
- 控制层SpringMVC和Struts2的区别
- android 学习之json数据的解析与创建
- stmp 邮件发送
- Java多线程的好文章