{"id":8124,"date":"2013-07-23T09:42:02","date_gmt":"2013-07-23T07:42:02","guid":{"rendered":"https:\/\/blog.trifork.com\/?p=8124"},"modified":"2013-07-23T09:42:02","modified_gmt":"2013-07-23T07:42:02","slug":"persist-beans-to-the-magnolia-repository-with-the-om-module","status":"publish","type":"post","link":"https:\/\/trifork.nl\/blog\/persist-beans-to-the-magnolia-repository-with-the-om-module\/","title":{"rendered":"Persist beans to the Magnolia repository with the OM module"},"content":{"rendered":"<p><img decoding=\"async\" style=\"background-image: none;float: left;padding: 35px 25px 25px 25px;border: 0px\" title=\"Magnolia\" alt=\"Magnolia\" src=\"https:\/\/trifork.nl\/articles\/wp-content\/uploads\/sites\/3\/2013\/07\/magnolia.jpg\" width=\"172\" align=\"left\" border=\"0\" \/><\/p>\n<p>Every once in a while when developing some integration with Magnolia CMS, you might want to save the contents of a bean to a Magnolia node.\u00a0The other way around, from content node to a bean, has never been an issue due to the <a href=\"http:\/\/nexus.magnolia-cms.com\/content\/sites\/magnolia.public.sites\/ref\/4.4.5\/apidocs\/info\/magnolia\/content2bean\/Content2BeanUtil.html\" target=\"_blank\" rel=\"noopener\">Content2Bean<\/a>\u00a0utilities that Magnolia provides. You might have already stumbled upon the\u00a0<a href=\"http:\/\/nexus.magnolia-cms.com\/content\/sites\/magnolia.public.sites\/ref\/4.4.5\/apidocs\/info\/magnolia\/content2bean\/Bean2ContentProcessor.html\" target=\"_blank\" rel=\"noopener\">Bean2ContentProcessor<\/a>\u00a0and the\u00a0<a href=\"http:\/\/nexus.magnolia-cms.com\/content\/sites\/magnolia.public.sites\/ref\/4.4.5\/apidocs\/info\/magnolia\/content2bean\/Bean2ContentTransformer.html\" target=\"_blank\" rel=\"noopener\">Bean2ContentTransformer<\/a>\u00a0interfaces in the Magnolia API, or have been looking for Bean2Content or Bean2Node, but an implementation has yet to be seen.\u00a0So when we want to save object classes to the repository, we are usually stuck creating content nodes, and adding the node data manually. Over and over again.<\/p>\n<p>While working on a new Magnolia tool, the need to persist object structures to the repository arose once again.\u00a0This time &#8217;round I finally decided that it was time for a simple, yet effective, Magnolia Object Mapping module. Interested??<\/p>\n<p style=\"text-align: center;margin-top: 20px\"><a title=\"Magnolia-OM jar\" href=\"http:\/\/info.trifork.nl\/MagnoliaOMDownload.html\" target=\"_blank\" rel=\"noopener\"><strong>Download OM Module<\/strong><\/a><\/p>\n<p><!--more--><br \/>\n<a id=\"start\"><\/a><\/p>\n<h2>The Magnolia Object Mapping module (magnolia-om)<\/h2>\n<p>The Magnolia Object Mapping module contains a service that uses reflection to access the accessible fields in an object class by their getter-methods. By default the contents of an object is persisted entirely to the Magnolia repository. Any field types that are compatible with Magnolia <a href=\"http:\/\/nexus.magnolia-cms.com\/content\/sites\/magnolia.public.sites\/ref\/4.4.6\/apidocs\/info\/magnolia\/cms\/core\/NodeData.html\" target=\"_blank\" rel=\"noopener\">NodeData<\/a>, are saved as node data properties of the content node. Any other types and their fields are saved as sub-nodes.<\/p>\n<h3>Getting started<\/h3>\n<p>Start by <a title=\"Magnolia-OM jar\" href=\"http:\/\/info.trifork.nl\/MagnoliaOMDownload.html\" target=\"_blank\" rel=\"noopener\">downloading and deploying the Magnolia-OM jar<\/a> in your local library. Add the following dependency to your project:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\n&lt;dependency&gt;\n\t&lt;groupId&gt;nl.trifork.magnolia&lt;\/groupId&gt;\n\t&lt;artifactId&gt;magnolia-om&lt;\/artifactId&gt;\n\t&lt;version&gt;1.0.0&lt;\/version&gt;\n&lt;\/dependency&gt;\n<\/pre>\n<h3>Example<\/h3>\n<p>Say we have these two very simple objects, An Author and his Books. The getters and setters are removed from the examples for clarity.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\npublic class Author {\n\n\tprivate String name;\n\tprivate String email;\n\tprivate List&lt;Book&gt; books;\n\t...\n}\n\npublic class Book {\n\n\tprivate long id;\n\tprivate String title;\n\tprivate String isbn;\n\t...\n}\n<\/pre>\n<p>When saved manually the code will be quite verbose:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\nSession session = MgnlContext.getJCRSession(&quot;config&quot;);\nNode node = session.getNode(&quot;\/parent\/path&quot;);\n\nNode authorNode = node.addNode(author.getName());\nauthorNode.setProperty(&quot;name&quot;, author.getName());\nauthorNode.setProperty(&quot;email&quot;, author.getEmail());\n\nfor (Book book : author.getBooks()){\n\tNode bookNode = authorNode.addNode(book.getTitle());\n\tbookNode.setProperty(&quot;id&quot;, book.getId());\n\tbookNode.setProperty(&quot;isbn&quot;, book.getIsbn());\n\tbookNode.setProperty(&quot;title&quot;, book.getTitle());\n}\n\nsession.save();\n<\/pre>\n<p>However, after creating some instances and saving this structure using the Magnolia OM service, your code will look like:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\nmappingService.toNode(&quot;\/parent\/path&quot;, &quot;config&quot;, myAuthorObject);\n<\/pre>\n<p>This will result in the following Magnolia node structure in the <em>config<\/em> repository, under <em>\/parent\/node<\/em>:<br \/>\n<img decoding=\"async\" class=\"alignnone size-full wp-image-8138\" style=\"border: 1px solid black\" alt=\"Magnolia OM example 1\" src=\"https:\/\/trifork.nl\/articles\/wp-content\/uploads\/sites\/3\/2013\/06\/restruct-11.jpg\" \/><\/p>\n<h3>Annotated beans<\/h3>\n<p>When you have full control over the contents of your objects, then this straight-forward approach might just be enough for you. However, if you want some more control over what properties are saved, the property names or their types and the Magnolia node types, we have introduced some annotations:<\/p>\n<ul>\n<li><strong>@MagnoliaNode (<em>name(String)<\/em>, <em>type(NodeType)<\/em>)<\/strong><br \/>\nIdentifies that this type or field should be saved to a sub node.<br \/>\nIf the <strong><em>name<\/em><\/strong> element is provided, this will be used as the node name. By default the the name of the type or field is used.<br \/>\nWith the <strong><em>type<\/em><\/strong> element, you can specify the Magnolia node type (Folder, Content, ContentNode). The default type is Content. Please keep in mind that Magnolia content nodes cannot contain folders by design.<\/li>\n<li><strong>@MagnoliaNodeData(<em>name(String)<\/em>, <em>type(int)<\/em>, <em>persist(boolean)<\/em>)<\/strong><br \/>\nIdentifies that the value of this field should be added as node data.<br \/>\nIf the <strong><em>name<\/em><\/strong> element is provided, this will be used as the node data name. By default the name of the field is used.<br \/>\nThe <strong><em>type<\/em><\/strong> element defines the javax.jcr.PropertyType to use for this NodeData. For example PropertyType.LONG, PropertyType.DOUBLE, etc. You can use different JCR property types than the field types in your bean. The value is converted for you automatically.<br \/>\nThe <strong><em>persist<\/em><\/strong> element defines whether this field should be saved to the Magnolia repository or not. The default value is true.<\/li>\n<li><strong>@MagnoliaNodeName<\/strong><br \/>\nIdentifies that the value of this field, or the returned value of a declared method should be used as the current node&#8217;s name.<\/li>\n<\/ul>\n<p>Now let&#8217;s adjust the classes a bit, using a couple of these annotations:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\n@MagnoliaNode(type=NodeType.CONTENTNODE)\npublic class Author {\n\n\t@MagnoliaNodeName\n\tprivate String name;\n\n\tprivate String email;\n\n\t@MagnoliaNode(type=NodeType.CONTENT)\n\tprivate List&lt;Book&gt; books;\n\t...\n\n@MagnoliaNode(type=NodeType.CONTENTNODE)\npublic class Book {\n\n\t@MagnoliaNodeName\n\t@MagnoliaNodeData(persist=false)\n\tprivate long id;\n\n\tprivate String title;\n\n\t@MagnoliaNodeData(name=&quot;isbnNumber&quot;,type=PropertyType.STRING)\n\tprivate String isbn;\n\t...\n<\/pre>\n<h4>Behavior<\/h4>\n<ul>\n<li>The Author object will be saved as a Magnolia ContentNode.<\/li>\n<li>For the Author object, the value of the field <em>name<\/em> will be used to name the Magnolia ContentNode.<\/li>\n<li>The value of the field <em>books<\/em> in Author will be persisted in Magnolia Content.<\/li>\n<li>The individual Book nodes will be saved as Magnolia ContentNodes.<\/li>\n<li>The value of the field <em>id<\/em> in Book will be used to name the individual book nodes.<\/li>\n<li>The field <em>id<\/em> in Book itself will not be persisted as node data, it&#8217;s just used to name the node.<\/li>\n<li>And finally in Book the value of the field <em>isbn<\/em> will be saved to a Magnolia string NodeData property called <em>isbnNumber<\/em> instead of isbn<\/li>\n<\/ul>\n<p>So if we would persist the object model again, we would end up with:<br \/>\n<img decoding=\"async\" class=\"alignnone size-full wp-image-8138\" style=\"border: 1px solid black\" alt=\"Magnolia OM example 2\" src=\"https:\/\/trifork.nl\/articles\/wp-content\/uploads\/sites\/3\/2013\/06\/restruct-2.jpg\" \/><\/p>\n<h2>Configuation<\/h2>\n<p>As most of our Magnolia modules, this module relies on our Spring context configuration module to initialize the service and expose it to the modules&#8217; class. However, this service can also just be instantiated and called directly.<\/p>\n<h3>Spring context<\/h3>\n<p>The best way to explain the module structure is by showing you the Spring context. The packages are starting with <em>nl.trifork.magnolia.om<\/em>, but are abbreviated to <em>om<\/em> for cosmetic reasons.<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;\n&lt;beans&gt;\n &lt;bean id=&quot;mappingService&quot;\n       class=&quot;om.service.AnnotationObjectMappingServiceImpl&quot;&gt;\n  &lt;property name=&quot;contextProvider&quot;&gt;\n   &lt;bean class=&quot;om.provider.LegacyMagnoliaContextProvider&quot; \/&gt;\n   OR\n   &lt;bean class=&quot;om.provider.DefaultMagnoliaContextProvider&quot; \/&gt;\n  &lt;\/property&gt;\n &lt;\/bean&gt;\n\n &lt;bean class=&quot;om.module.MagnoliaOMModule&quot; factory-method=&quot;getInstance&quot;&gt;\n  &lt;property name=&quot;mappingService&quot; ref=&quot;mappingService&quot; \/&gt;\n &lt;\/bean&gt;\n&lt;\/beans&gt;\n<\/pre>\n<p>The <code>AnnotationObjectMappingServiceImpl<\/code> implementation takes a contextProvider as a required property. All of the actual Magnolia API access is abstracted into a Magnolia context provider. The reason for this is that the way to access the Magnolia API differs slightly for either versions before 4.5, and after. If you are using a version before 4.5x, just inject the <code>LegacyMagnoliaContextProvider<\/code>, and if you are using one of the spanking new Magnolia versions, use the <code>DefaultMagnoliaContextProvider<\/code>. This way the module is easy to use for any Magnolia version you are using.<\/p>\n<h3>No Spring?<\/h3>\n<p>If you are not ready to use Trifork&#8217;s <a href=\"https:\/\/blog.trifork.com\/2012\/05\/31\/spring-context-configuration-in-magnolia\/\" target=\"_blank\" rel=\"noopener\">Spring context configuration module<\/a> just yet, feel free to instantiate the service as follows:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\nMagnoliaContextProvider contextProvider = new DefaultMagnoliaContextProvider(); \/\/ or use the legacy provider for &lt; 4.5x\n\t\tAnnotationObjectMappingServiceImpl mappingService = new AnnotationObjectMappingServiceImpl();\n\t\tmappingService.setContextProvider(contextProvider);\n<\/pre>\n<p>You can also set two default behaviors:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\nmappingService.setDefaultNodeType(NodeType.CONTENT);\nmappingService.setPersistEmptyValues(true);\n<\/pre>\n<p><strong>setDefaultNodeType (default NodeType.CONTENT)<\/strong><br \/>\nThis sets the default Magnolia node type you want to use. Might be very useful instead of annotating each and every bean to use a different node type than the default one.<\/p>\n<p><strong>setPersistEmptyValues (default true)<\/strong><br \/>\nThis property defines whether to save empty collections, empty maps or null values to the repository. When set to false, these empty node datas and nodes are skipped.<\/p>\n<h2>That&#8217;s it!<\/h2>\n<p>So if you ever need to persist your beans to the repository in the future again, try out this small and easy to use module <a title=\"Magnolia OM\" href=\"http:\/\/info.trifork.nl\/MagnoliaOMDownload.html\" target=\"_blank\" rel=\"noopener\">(Download the JAR!!)<\/a>. I guarantee you that you will not be creating any ContentNodes or NodeDatas manually ever again!!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Every once in a while when developing some integration with Magnolia CMS, you might want to save the contents of a bean to a Magnolia node.\u00a0The other way around, from content node to a bean, has never been an issue due to the Content2Bean\u00a0utilities that Magnolia provides. You might have already stumbled upon the\u00a0Bean2ContentProcessor\u00a0and the\u00a0Bean2ContentTransformer\u00a0interfaces [&hellip;]<\/p>\n","protected":false},"author":40,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"content-type":"","footnotes":""},"categories":[106,68],"tags":[],"class_list":["post-8124","post","type-post","status-publish","format-standard","hentry","category-cms-2","category-magnolia"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Persist beans to the Magnolia repository with the OM module - Trifork Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/trifork.nl\/blog\/persist-beans-to-the-magnolia-repository-with-the-om-module\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Persist beans to the Magnolia repository with the OM module - Trifork Blog\" \/>\n<meta property=\"og:description\" content=\"Every once in a while when developing some integration with Magnolia CMS, you might want to save the contents of a bean to a Magnolia node.\u00a0The other way around, from content node to a bean, has never been an issue due to the Content2Bean\u00a0utilities that Magnolia provides. You might have already stumbled upon the\u00a0Bean2ContentProcessor\u00a0and the\u00a0Bean2ContentTransformer\u00a0interfaces [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/trifork.nl\/blog\/persist-beans-to-the-magnolia-repository-with-the-om-module\/\" \/>\n<meta property=\"og:site_name\" content=\"Trifork Blog\" \/>\n<meta property=\"article:published_time\" content=\"2013-07-23T07:42:02+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/trifork.nl\/articles\/wp-content\/uploads\/sites\/3\/2013\/07\/magnolia.jpg\" \/>\n<meta name=\"author\" content=\"Erik Alphenaar\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Erik Alphenaar\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/trifork.nl\/blog\/persist-beans-to-the-magnolia-repository-with-the-om-module\/\",\"url\":\"https:\/\/trifork.nl\/blog\/persist-beans-to-the-magnolia-repository-with-the-om-module\/\",\"name\":\"Persist beans to the Magnolia repository with the OM module - Trifork Blog\",\"isPartOf\":{\"@id\":\"https:\/\/trifork.nl\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/trifork.nl\/blog\/persist-beans-to-the-magnolia-repository-with-the-om-module\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/trifork.nl\/blog\/persist-beans-to-the-magnolia-repository-with-the-om-module\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/trifork.nl\/articles\/wp-content\/uploads\/sites\/3\/2013\/07\/magnolia.jpg\",\"datePublished\":\"2013-07-23T07:42:02+00:00\",\"author\":{\"@id\":\"https:\/\/trifork.nl\/blog\/#\/schema\/person\/63f17c99a57ab0e632f09f27214f9466\"},\"breadcrumb\":{\"@id\":\"https:\/\/trifork.nl\/blog\/persist-beans-to-the-magnolia-repository-with-the-om-module\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/trifork.nl\/blog\/persist-beans-to-the-magnolia-repository-with-the-om-module\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/trifork.nl\/blog\/persist-beans-to-the-magnolia-repository-with-the-om-module\/#primaryimage\",\"url\":\"https:\/\/trifork.nl\/articles\/wp-content\/uploads\/sites\/3\/2013\/07\/magnolia.jpg\",\"contentUrl\":\"https:\/\/trifork.nl\/articles\/wp-content\/uploads\/sites\/3\/2013\/07\/magnolia.jpg\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/trifork.nl\/blog\/persist-beans-to-the-magnolia-repository-with-the-om-module\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/trifork.nl\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Persist beans to the Magnolia repository with the OM module\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/trifork.nl\/blog\/#website\",\"url\":\"https:\/\/trifork.nl\/blog\/\",\"name\":\"Trifork Blog\",\"description\":\"Keep updated on the technical solutions Trifork is working on!\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/trifork.nl\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/trifork.nl\/blog\/#\/schema\/person\/63f17c99a57ab0e632f09f27214f9466\",\"name\":\"Erik Alphenaar\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/trifork.nl\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/f9734b3c518fbdb970d63dcea60b331d?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/f9734b3c518fbdb970d63dcea60b331d?s=96&d=mm&r=g\",\"caption\":\"Erik Alphenaar\"},\"url\":\"https:\/\/trifork.nl\/blog\/author\/erika\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Persist beans to the Magnolia repository with the OM module - Trifork Blog","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:\/\/trifork.nl\/blog\/persist-beans-to-the-magnolia-repository-with-the-om-module\/","og_locale":"en_US","og_type":"article","og_title":"Persist beans to the Magnolia repository with the OM module - Trifork Blog","og_description":"Every once in a while when developing some integration with Magnolia CMS, you might want to save the contents of a bean to a Magnolia node.\u00a0The other way around, from content node to a bean, has never been an issue due to the Content2Bean\u00a0utilities that Magnolia provides. You might have already stumbled upon the\u00a0Bean2ContentProcessor\u00a0and the\u00a0Bean2ContentTransformer\u00a0interfaces [&hellip;]","og_url":"https:\/\/trifork.nl\/blog\/persist-beans-to-the-magnolia-repository-with-the-om-module\/","og_site_name":"Trifork Blog","article_published_time":"2013-07-23T07:42:02+00:00","og_image":[{"url":"https:\/\/trifork.nl\/articles\/wp-content\/uploads\/sites\/3\/2013\/07\/magnolia.jpg","type":"","width":"","height":""}],"author":"Erik Alphenaar","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Erik Alphenaar","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/trifork.nl\/blog\/persist-beans-to-the-magnolia-repository-with-the-om-module\/","url":"https:\/\/trifork.nl\/blog\/persist-beans-to-the-magnolia-repository-with-the-om-module\/","name":"Persist beans to the Magnolia repository with the OM module - Trifork Blog","isPartOf":{"@id":"https:\/\/trifork.nl\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/trifork.nl\/blog\/persist-beans-to-the-magnolia-repository-with-the-om-module\/#primaryimage"},"image":{"@id":"https:\/\/trifork.nl\/blog\/persist-beans-to-the-magnolia-repository-with-the-om-module\/#primaryimage"},"thumbnailUrl":"https:\/\/trifork.nl\/articles\/wp-content\/uploads\/sites\/3\/2013\/07\/magnolia.jpg","datePublished":"2013-07-23T07:42:02+00:00","author":{"@id":"https:\/\/trifork.nl\/blog\/#\/schema\/person\/63f17c99a57ab0e632f09f27214f9466"},"breadcrumb":{"@id":"https:\/\/trifork.nl\/blog\/persist-beans-to-the-magnolia-repository-with-the-om-module\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/trifork.nl\/blog\/persist-beans-to-the-magnolia-repository-with-the-om-module\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/trifork.nl\/blog\/persist-beans-to-the-magnolia-repository-with-the-om-module\/#primaryimage","url":"https:\/\/trifork.nl\/articles\/wp-content\/uploads\/sites\/3\/2013\/07\/magnolia.jpg","contentUrl":"https:\/\/trifork.nl\/articles\/wp-content\/uploads\/sites\/3\/2013\/07\/magnolia.jpg"},{"@type":"BreadcrumbList","@id":"https:\/\/trifork.nl\/blog\/persist-beans-to-the-magnolia-repository-with-the-om-module\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/trifork.nl\/blog\/"},{"@type":"ListItem","position":2,"name":"Persist beans to the Magnolia repository with the OM module"}]},{"@type":"WebSite","@id":"https:\/\/trifork.nl\/blog\/#website","url":"https:\/\/trifork.nl\/blog\/","name":"Trifork Blog","description":"Keep updated on the technical solutions Trifork is working on!","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/trifork.nl\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/trifork.nl\/blog\/#\/schema\/person\/63f17c99a57ab0e632f09f27214f9466","name":"Erik Alphenaar","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/trifork.nl\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/f9734b3c518fbdb970d63dcea60b331d?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f9734b3c518fbdb970d63dcea60b331d?s=96&d=mm&r=g","caption":"Erik Alphenaar"},"url":"https:\/\/trifork.nl\/blog\/author\/erika\/"}]}},"_links":{"self":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/posts\/8124","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/users\/40"}],"replies":[{"embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/comments?post=8124"}],"version-history":[{"count":0,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/posts\/8124\/revisions"}],"wp:attachment":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/media?parent=8124"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/categories?post=8124"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/tags?post=8124"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}