{"id":19258,"date":"2013-11-29T13:00:33","date_gmt":"2013-11-29T11:00:33","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=19258"},"modified":"2013-11-29T08:34:35","modified_gmt":"2013-11-29T06:34:35","slug":"spring-data-mongodb-cascade-save-on-dbref-objects","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2013\/11\/spring-data-mongodb-cascade-save-on-dbref-objects.html","title":{"rendered":"Spring Data MongoDB cascade save on DBRef objects"},"content":{"rendered":"<p><strong>Spring Data MongoDB<\/strong> by default does not support cascade operations on referenced objects with <a href=\"http:\/\/static.springsource.org\/spring-data\/data-mongodb\/docs\/current\/api\/org\/springframework\/data\/mongodb\/core\/mapping\/DBRef.html\">@DBRef<\/a> annotations as <a href=\"http:\/\/static.springsource.org\/spring-data\/data-document\/docs\/current\/reference\/html\/#mapping-usage-references\">reference says<\/a>:<\/p>\n<blockquote>\n<p>The mapping framework <strong>does not handle cascading saves<\/strong>. If you change an Account object that is referenced by a Person object, you must <strong>save<\/strong> the Account object <strong>separately<\/strong>. Calling save on the Person object <strong>will not automatically<\/strong> save the Account objects in the property accounts.<\/p>\n<\/blockquote>\n<p>That\u2019s quite problematic because in order to achieve saving child objects you need to override save method in repository in parent or create additional \u00e2\u20ac\u0153service\u00e2\u20ac\u009d methods like it is presented in <a href=\"http:\/\/krams915.blogspot.com\/2012\/01\/spring-mvc-31-implement-crud-with_7897.html\">here<\/a>.<\/p>\n<p>In this article I will show you <strong>how it can be achieved<\/strong> for all documents using generic implementation of <a href=\"http:\/\/static.springsource.org\/spring-data\/data-mongo\/docs\/1.0.1.RELEASE\/api\/org\/springframework\/data\/mongodb\/core\/mapping\/event\/AbstractMongoEventListener.html\">AbstractMongoEventListener<\/a>.<\/p>\n<h2>@CascadeSave annotation<\/h2>\n<p>Because we can\u2019t change <a href=\"http:\/\/static.springsource.org\/spring-data\/data-mongodb\/docs\/current\/api\/org\/springframework\/data\/mongodb\/core\/mapping\/DBRef.html\">@DBRef<\/a> 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.<\/p>\n<pre class=\" brush:java\">package pl.maciejwalkowiak.springdata.mongodb;\r\n\r\nimport java.lang.annotation.ElementType;\r\nimport java.lang.annotation.Retention;\r\nimport java.lang.annotation.RetentionPolicy;\r\nimport java.lang.annotation.Target;\r\n\r\n@Retention(RetentionPolicy.RUNTIME)\r\n@Target({ ElementType.FIELD })\r\npublic @interface CascadeSave {\r\n\r\n}<\/pre>\n<h2>CascadingMongoEventListener<\/h2>\n<p>Next part is to implement handler for this annotation. We will use for that powerful <a href=\"http:\/\/static.springsource.org\/spring\/docs\/3.1.x\/spring-framework-reference\/html\/beans.html#context-functionality-events\">Spring Application Event mechanism<\/a>. In particular we will extend <a href=\"http:\/\/static.springsource.org\/spring-data\/data-mongo\/docs\/1.0.1.RELEASE\/api\/org\/springframework\/data\/mongodb\/core\/mapping\/event\/AbstractMongoEventListener.html\">AbstractMongoEventListener<\/a> to catch saved object before it is converted to Mongo\u00e2\u20ac\u2122s <a href=\"http:\/\/api.mongodb.org\/java\/2.6\/com\/mongodb\/DBObject.html\">DBObject<\/a>.<\/p>\n<p>How does it work? When object <a href=\"http:\/\/static.springsource.org\/spring-data\/data-mongodb\/docs\/current\/api\/org\/springframework\/data\/mongodb\/core\/MongoTemplate.html\">MongoTemplate<\/a>#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:<\/p>\n<ul>\n<li>goes through all its fields to check if there are fields annotated with <a href=\"http:\/\/static.springsource.org\/spring-data\/data-mongodb\/docs\/current\/api\/org\/springframework\/data\/mongodb\/core\/mapping\/DBRef.html\">@DBRef<\/a> and @CascadeSave at once.<\/li>\n<li>when field is found it checks if <a href=\"http:\/\/static.springsource.org\/spring-data\/data-commons\/docs\/current\/api\/org\/springframework\/data\/annotation\/Id.html\">@Id<\/a> annotation is present<\/li>\n<li>child object is being saved<\/li>\n<\/ul>\n<pre class=\" brush:java\">package pl.maciejwalkowiak.springdata.mongodb;\r\n\r\nimport org.bson.types.ObjectId;\r\nimport org.springframework.beans.factory.annotation.Autowired;\r\nimport org.springframework.data.annotation.Id;\r\nimport org.springframework.data.mapping.model.MappingException;\r\nimport org.springframework.data.mongodb.core.MongoOperations;\r\nimport org.springframework.data.mongodb.core.mapping.DBRef;\r\nimport org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener;\r\nimport org.springframework.stereotype.Component;\r\nimport org.springframework.util.ReflectionUtils;\r\n\r\nimport java.lang.reflect.Field;\r\n\r\npublic class CascadingMongoEventListener extends AbstractMongoEventListener {\r\n  @Autowired\r\n  private MongoOperations mongoOperations;\r\n\r\n  @Override\r\n  public void onBeforeConvert(final Object source) {\r\n      ReflectionUtils.doWithFields(source.getClass(), new ReflectionUtils.FieldCallback() {\r\n\r\n          public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {\r\n              ReflectionUtils.makeAccessible(field);\r\n\r\n              if (field.isAnnotationPresent(DBRef.class) &amp;&amp; field.isAnnotationPresent(CascadeSave.class)) {\r\n                  final Object fieldValue = field.get(source);\r\n\r\n                  DbRefFieldCallback callback = new DbRefFieldCallback();\r\n\r\n                  ReflectionUtils.doWithFields(fieldValue.getClass(), callback);\r\n\r\n                  if (!callback.isIdFound()) {\r\n                      throw new MappingException(\"Cannot perform cascade save on child object without id set\");\r\n                  }\r\n\r\n                  mongoOperations.save(fieldValue);\r\n              }\r\n          }\r\n      });\r\n  }\r\n\r\n  private static class DbRefFieldCallback implements ReflectionUtils.FieldCallback {\r\n      private boolean idFound;\r\n\r\n      public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {\r\n          ReflectionUtils.makeAccessible(field);\r\n\r\n          if (field.isAnnotationPresent(Id.class)) {\r\n              idFound = true;\r\n          }\r\n      }\r\n\r\n      public boolean isIdFound() {\r\n          return idFound;\r\n      }\r\n  }\r\n}<\/pre>\n<h2>Mapping requirements<\/h2>\n<p>As you can see in order to make thing work you need to follow some rules:<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<ul>\n<li>parent\u2019s class child property has to be mapped with <a href=\"http:\/\/static.springsource.org\/spring-data\/data-mongodb\/docs\/current\/api\/org\/springframework\/data\/mongodb\/core\/mapping\/DBRef.html\">@DBRef<\/a> and @CascadeSave<\/li>\n<li>child class needs to have property annotated with <a href=\"http:\/\/static.springsource.org\/spring-data\/data-commons\/docs\/current\/api\/org\/springframework\/data\/annotation\/Id.html\">@Id<\/a> and if that id is supposed to be autogenerated it should by type of <a href=\"http:\/\/api.mongodb.org\/java\/2.6\/org\/bson\/types\/ObjectId.html\">ObjectId<\/a><\/li>\n<\/ul>\n<h2>Usage<\/h2>\n<p>In order to use cascade saving in your project you need just to register CascadingMongoEventListener in Spring Context:<\/p>\n<pre class=\" brush:xml\">&lt;bean class=\"pl.maciejwalkowiak.springdata.mongodb.CascadingMongoEventListener\" \/&gt;<\/pre>\n<h2>Let\u2019s test it<\/h2>\n<p>In order to show an example I made two document classes:<\/p>\n<pre class=\" brush:java\">@Document\r\npublic class User {\r\n  @Id\r\n  private ObjectId id;\r\n  private String name;\r\n\r\n  @DBRef\r\n  @CascadeSave\r\n  private Address address;\r\n\r\n  public User(String name) {\r\n      this.name = name;\r\n  }\r\n\r\n  \/\/ ... getters, setters, equals hashcode\r\n}<\/pre>\n<pre class=\" brush:java\">@Document\r\npublic class Address {\r\n  @Id\r\n  private ObjectId id;\r\n  private String city;\r\n\r\n  public Address(String city) {\r\n      this.city = city;\r\n  }\r\n\r\n  \/\/ ... getters, setters, equals hashcode\r\n}<\/pre>\n<p>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 (<code>applcationContext-tests.xml<\/code> contains only default Spring Data MongoDB beans and CascadingMongoEventListener registered):<\/p>\n<pre class=\" brush:java\">@RunWith(SpringJUnit4ClassRunner.class)\r\n@ContextConfiguration(locations = {\"classpath:applcationContext-tests.xml\"})\r\npublic class CascadingMongoEventListenerTest {\r\n\r\n  @Autowired\r\n  private MongoOperations mongoOperations;\r\n\r\n  \/**\r\n  * Clean collections before tests are executed\r\n  *\/\r\n  @Before\r\n  public void cleanCollections() {\r\n      mongoOperations.dropCollection(User.class);\r\n      mongoOperations.dropCollection(Address.class);\r\n  }\r\n\r\n  @Test\r\n  public void testCascadeSave() {\r\n      \/\/ given\r\n      User user = new User(\"John Smith\");\r\n      user.setAddress(new Address(\"London\"));\r\n\r\n      \/\/ when\r\n      mongoOperations.save(user);\r\n\r\n      \/\/ then\r\n      List&lt;User&gt; users = mongoOperations.findAll(User.class);\r\n      assertThat(users).hasSize(1).containsOnly(user);\r\n\r\n      User savedUser = users.get(0);\r\n      assertThat(savedUser.getAddress()).isNotNull().isEqualTo(user.getAddress());\r\n\r\n      List&lt;Address&gt; addresses = mongoOperations.findAll(Address.class);\r\n      assertThat(addresses).hasSize(1).containsOnly(user.getAddress());\r\n  }\r\n}<\/pre>\n<p>We can check that also in Mongo console:<\/p>\n<pre class=\" brush:java\">&gt; db.user.find()\r\n{ \"_id\" : ObjectId(\"4f9d1bab1a8854250a5bf13e\"), \"_class\" : \"pl.maciejwalkowiak.springdata.mongodb.domain.User\", \"name\" : \"John Smith\", \"address\" : { \"$ref\" : \"address\", \"$id\" : ObjectId(\"4f9d1ba41a8854250a5bf13d\") } }\r\n&gt; db.address.find()\r\n{ \"_id\" : ObjectId(\"4f9d1ba41a8854250a5bf13d\"), \"_class\" : \"pl.maciejwalkowiak.springdata.mongodb.domain.Address\", \"city\" : \"London\" }<\/pre>\n<h2>Summary<\/h2>\n<p>With this simple solution we can finally save child objects with one method call without implementing anything special for each document class.<\/p>\n<p>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:<\/p>\n<ul>\n<li>it requires to use additional annotation<\/li>\n<li>uses reflection API to iterate through fields which is not the fastest way to do it (but feel free to implement caching if needed)<\/li>\n<\/ul>\n<p>If that could be part of Spring Data MongoDB instead of additional annotation <a href=\"http:\/\/static.springsource.org\/spring-data\/data-mongodb\/docs\/current\/api\/org\/springframework\/data\/mongodb\/core\/mapping\/DBRef.html\">@DBRef<\/a> could have additional property <code>cascade<\/code>. Instead of reflection we could use <a href=\"http:\/\/static.springsource.org\/spring-data\/data-mongodb\/docs\/current\/api\/org\/springframework\/data\/mongodb\/core\/mapping\/MongoMappingContext.html\">MongoMappingContext<\/a> together with <a href=\"http:\/\/static.springsource.org\/spring-data\/data-mongodb\/docs\/current\/api\/org\/springframework\/data\/mongodb\/core\/mapping\/MongoPersistentEntity.html\">MongoPersistentEntity<\/a>. I\u2019ve started already to prepare pull request with those changes. We will see if it will be accepted by Spring Source team.<br \/>\n&nbsp;<\/p>\n<div style=\"border: 1px solid #D8D8D8; background: #FAFAFA; width: 100%; padding-left: 5px;\"><b><i>Reference: <\/i><\/b><a href=\"http:\/\/maciejwalkowiak.pl\/blog\/2012\/04\/30\/spring-data-mongodb-cascade-save-on-dbref-objects\/\">Spring Data MongoDB cascade save on DBRef objects<\/a> from our <a href=\"http:\/\/www.javacodegeeks.com\/jcg\">JCG partner<\/a> Maciej Walkowiak at the <a href=\"http:\/\/maciejwalkowiak.pl\/blog\/\">Software Development Journey<\/a> blog.<\/div>\n","protected":false},"excerpt":{"rendered":"<p>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 must save the Account object separately. Calling save on the Person object will not &hellip;<\/p>\n","protected":false},"author":245,"featured_media":187,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[112,113,30,321],"class_list":["post-19258","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-mongodb","tag-nosql","tag-spring","tag-spring-data"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Spring Data MongoDB cascade save on DBRef objects<\/title>\n<meta name=\"description\" content=\"Spring Data MongoDB by default does not support cascade operations on referenced objects with @DBRef annotations as reference says: The mapping framework\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2013\/11\/spring-data-mongodb-cascade-save-on-dbref-objects.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Spring Data MongoDB cascade save on DBRef objects\" \/>\n<meta property=\"og:description\" content=\"Spring Data MongoDB by default does not support cascade operations on referenced objects with @DBRef annotations as reference says: The mapping framework\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2013\/11\/spring-data-mongodb-cascade-save-on-dbref-objects.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2013-11-29T11:00:33+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/mongodb-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Maciej Walkowiak\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Maciej Walkowiak\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/11\\\/spring-data-mongodb-cascade-save-on-dbref-objects.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/11\\\/spring-data-mongodb-cascade-save-on-dbref-objects.html\"},\"author\":{\"name\":\"Maciej Walkowiak\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/918c1b6d9d8de83830e5b24c0f0f4419\"},\"headline\":\"Spring Data MongoDB cascade save on DBRef objects\",\"datePublished\":\"2013-11-29T11:00:33+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/11\\\/spring-data-mongodb-cascade-save-on-dbref-objects.html\"},\"wordCount\":557,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/11\\\/spring-data-mongodb-cascade-save-on-dbref-objects.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/mongodb-logo.jpg\",\"keywords\":[\"MongoDB\",\"NoSQL\",\"Spring\",\"Spring Data\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/11\\\/spring-data-mongodb-cascade-save-on-dbref-objects.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/11\\\/spring-data-mongodb-cascade-save-on-dbref-objects.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/11\\\/spring-data-mongodb-cascade-save-on-dbref-objects.html\",\"name\":\"Spring Data MongoDB cascade save on DBRef objects\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/11\\\/spring-data-mongodb-cascade-save-on-dbref-objects.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/11\\\/spring-data-mongodb-cascade-save-on-dbref-objects.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/mongodb-logo.jpg\",\"datePublished\":\"2013-11-29T11:00:33+00:00\",\"description\":\"Spring Data MongoDB by default does not support cascade operations on referenced objects with @DBRef annotations as reference says: The mapping framework\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/11\\\/spring-data-mongodb-cascade-save-on-dbref-objects.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/11\\\/spring-data-mongodb-cascade-save-on-dbref-objects.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/11\\\/spring-data-mongodb-cascade-save-on-dbref-objects.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/mongodb-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/mongodb-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/11\\\/spring-data-mongodb-cascade-save-on-dbref-objects.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Spring Data MongoDB cascade save on DBRef objects\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/918c1b6d9d8de83830e5b24c0f0f4419\",\"name\":\"Maciej Walkowiak\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/897c85e1c7fe1b9b9ed640f6ff04c5f2141980d6c5c2b933034783495c8e8db5?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/897c85e1c7fe1b9b9ed640f6ff04c5f2141980d6c5c2b933034783495c8e8db5?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/897c85e1c7fe1b9b9ed640f6ff04c5f2141980d6c5c2b933034783495c8e8db5?s=96&d=mm&r=g\",\"caption\":\"Maciej Walkowiak\"},\"sameAs\":[\"http:\\\/\\\/maciejwalkowiak.pl\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/Maciej-Walkowiak\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Spring Data MongoDB cascade save on DBRef objects","description":"Spring Data MongoDB by default does not support cascade operations on referenced objects with @DBRef annotations as reference says: The mapping framework","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2013\/11\/spring-data-mongodb-cascade-save-on-dbref-objects.html","og_locale":"en_US","og_type":"article","og_title":"Spring Data MongoDB cascade save on DBRef objects","og_description":"Spring Data MongoDB by default does not support cascade operations on referenced objects with @DBRef annotations as reference says: The mapping framework","og_url":"https:\/\/www.javacodegeeks.com\/2013\/11\/spring-data-mongodb-cascade-save-on-dbref-objects.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2013-11-29T11:00:33+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/mongodb-logo.jpg","type":"image\/jpeg"}],"author":"Maciej Walkowiak","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Maciej Walkowiak","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2013\/11\/spring-data-mongodb-cascade-save-on-dbref-objects.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/11\/spring-data-mongodb-cascade-save-on-dbref-objects.html"},"author":{"name":"Maciej Walkowiak","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/918c1b6d9d8de83830e5b24c0f0f4419"},"headline":"Spring Data MongoDB cascade save on DBRef objects","datePublished":"2013-11-29T11:00:33+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/11\/spring-data-mongodb-cascade-save-on-dbref-objects.html"},"wordCount":557,"commentCount":2,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/11\/spring-data-mongodb-cascade-save-on-dbref-objects.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/mongodb-logo.jpg","keywords":["MongoDB","NoSQL","Spring","Spring Data"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2013\/11\/spring-data-mongodb-cascade-save-on-dbref-objects.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2013\/11\/spring-data-mongodb-cascade-save-on-dbref-objects.html","url":"https:\/\/www.javacodegeeks.com\/2013\/11\/spring-data-mongodb-cascade-save-on-dbref-objects.html","name":"Spring Data MongoDB cascade save on DBRef objects","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/11\/spring-data-mongodb-cascade-save-on-dbref-objects.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/11\/spring-data-mongodb-cascade-save-on-dbref-objects.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/mongodb-logo.jpg","datePublished":"2013-11-29T11:00:33+00:00","description":"Spring Data MongoDB by default does not support cascade operations on referenced objects with @DBRef annotations as reference says: The mapping framework","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/11\/spring-data-mongodb-cascade-save-on-dbref-objects.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2013\/11\/spring-data-mongodb-cascade-save-on-dbref-objects.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2013\/11\/spring-data-mongodb-cascade-save-on-dbref-objects.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/mongodb-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/mongodb-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2013\/11\/spring-data-mongodb-cascade-save-on-dbref-objects.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"Spring Data MongoDB cascade save on DBRef objects"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/918c1b6d9d8de83830e5b24c0f0f4419","name":"Maciej Walkowiak","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/897c85e1c7fe1b9b9ed640f6ff04c5f2141980d6c5c2b933034783495c8e8db5?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/897c85e1c7fe1b9b9ed640f6ff04c5f2141980d6c5c2b933034783495c8e8db5?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/897c85e1c7fe1b9b9ed640f6ff04c5f2141980d6c5c2b933034783495c8e8db5?s=96&d=mm&r=g","caption":"Maciej Walkowiak"},"sameAs":["http:\/\/maciejwalkowiak.pl"],"url":"https:\/\/www.javacodegeeks.com\/author\/Maciej-Walkowiak"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/19258","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/245"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=19258"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/19258\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/187"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=19258"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=19258"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=19258"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}