{"id":840,"date":"2009-12-02T21:00:46","date_gmt":"2009-12-02T20:00:46","guid":{"rendered":"http:\/\/www.gamlor.info\/wordpress\/?p=840"},"modified":"2021-03-11T09:44:57","modified_gmt":"2021-03-11T08:44:57","slug":"db4o-transparent-persistence","status":"publish","type":"post","link":"https:\/\/www.gamlor.info\/wordpress\/2009\/12\/db4o-transparent-persistence\/","title":{"rendered":"db4o: Transparent-Persistence"},"content":{"rendered":"<p>It has been a while since I\u2019ve wrote my last post about db4o. You may remember the post about the <a href=\"?p=637\">activation-mechanism<\/a>. Don\u2019t you think that this is quite painful? Activating objects with the right activation depth and so forth? Wouldn\u2019t it be nice if db4o actually activates the objects as soon as you need then? Well db4o can do that, it\u2019s called <a href=\"http:\/\/developer.db4o.com\/Documentation\/Reference\/db4o-7.12\/net2\/reference\/html\/reference\/object_lifecycle\/activation\/transparent_activation_framework.html\">Transparent-Activation<\/a>.<\/p>\n<p>(All posts of this series: <a href=\"?p=620\">the basics<\/a>, <a href=\"?p=637\">activation<\/a>, <a href=\"?p=654\">object-identity<\/a>, <a href=\"?p=671\">transactions<\/a>, <a href=\"?p=695\">persistent classes<\/a>, <a href=\"?p=733\">single container concurrency<\/a>, <a href=\"?p=744\">Queries in Java, C# 2.0<\/a>, <a href=\"?p=779\">client-server concurrency<\/a>, <a href=\"?p=840\">transparent persistence<\/a>, <a href=\"?p=949\">adhoc query tools<\/a>)<\/p>\n<div id=\"attachment_844\" style=\"width: 310px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/db4o-activation-pain.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-844\" class=\"size-medium wp-image-844\" title=\"db4o-activation-pain\" src=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/db4o-activation-pain-300x100.png\" alt=\"activation pain\" width=\"300\" height=\"100\" srcset=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/db4o-activation-pain-300x100.png 300w, https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/db4o-activation-pain.png 920w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-844\" class=\"wp-caption-text\">activation pain<\/p><\/div>\n<h3>Prepare The Persistent Classes<\/h3>\n<p>We don\u2019t want to activate the object manually all over our codebase. Therefore a object has to activate it self. To achieve this, the class needs to implement the IActivatable-Interface. For example:<\/p>\n<pre class=\"csharpcode\"><span class=\"kwrd\">internal<\/span> <span class=\"kwrd\">class<\/span> Person : IActivatable\r\n{\r\n    <span class=\"kwrd\">private<\/span> <span class=\"kwrd\">string<\/span> _firstname;\r\n    <span class=\"kwrd\">private<\/span> Person _parent;\r\n\r\n    [Transient] <span class=\"kwrd\">private<\/span> IActivator _activator;\r\n\r\n    <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">string<\/span> Firstname\r\n    {\r\n        get\r\n        {\r\n            Activate(ActivationPurpose.Read);\r\n            <span class=\"kwrd\">return<\/span> _firstname;\r\n        }\r\n        set { _firstname = <span class=\"kwrd\">value<\/span>; }\r\n    }\r\n\r\n   <span class=\"rem\">\/** Other properties like above.<\/span>\r\n<span class=\"rem\">     Every time you read a field you need to call <\/span>\r\n<span class=\"rem\">     Activate(ActivationPurpose.Read); first *\/<\/span>\r\n\r\n    <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">void<\/span> Bind(IActivator activator)\r\n    {\r\n        <span class=\"kwrd\">if<\/span> (_activator == activator)\r\n            <span class=\"kwrd\">return<\/span>;\r\n        <span class=\"kwrd\">if<\/span> (activator != <span class=\"kwrd\">null<\/span> &amp;&amp; _activator != <span class=\"kwrd\">null<\/span>)\r\n            <span class=\"kwrd\">throw<\/span> <span class=\"kwrd\">new<\/span> InvalidOperationException(<span class=\"str\">\"cannot rebind with another activator\"<\/span>);\r\n        _activator = activator;\r\n    }\r\n\r\n    <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">void<\/span> Activate(ActivationPurpose purpose)\r\n    {\r\n        <span class=\"kwrd\">if<\/span> (<span class=\"kwrd\">null<\/span> != _activator)\r\n            _activator.Activate(purpose);\r\n    }\r\n}<\/pre>\n<p>Now db4o calls the Bind()-method for each object. As soon as a property is read the Activate-method is called. The activator now is responsible for reading the data from the database and set the fields.<\/p>\n<p>It\u2019s extremely important that the implementation ensures that the activator is called before any field is accessed. Notice also that the \u2018_activator\u2019-field is marked as transient. It quite useless to store the activator.<\/p>\n<h3>First Test Run<\/h3>\n<p>The first test-run is easy. We create a deep object-graph. Then we access it and check if we get the expected data. For example:<\/p>\n<pre class=\"csharpcode\"><span class=\"kwrd\">using<\/span> (var db = OpenDB(FilePath))\r\n{\r\n    var me = (from Person p <span class=\"kwrd\">in<\/span> db\r\n              <span class=\"kwrd\">where<\/span> p.Firstname.Equals(<span class=\"str\">\"Roman\"<\/span>)\r\n              select p).Single();\r\n    var adam = me.Father.Father.Father.Father.Father.Father.Father;\r\n    AssertEqual(<span class=\"str\">\"Adam\"<\/span>, adam.Firstname);\r\n}<\/pre>\n<p>When you just run the code it will throw a NullReferenceException. Because first\u00a0you\u00a0need to activate the support for Transparent Activation. To do this, add the Transparent Activation support in the configuration:<\/p>\n<pre class=\"csharpcode\">var cfg = Db4oEmbedded.NewConfiguration();\r\ncfg.Common.Add(<span class=\"kwrd\">new<\/span> TransparentActivationSupport());\r\nvar db = Db4oEmbedded.OpenFile(cfg, path);\u00a0<\/pre>\n<p>After adding the configuration-piece it works wonderful. No more activation-depth tweaking, no more NullReferenceException due to not activated objects.\u00a0<\/p>\n<div id=\"attachment_845\" style=\"width: 310px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/db4o-transparent-activation.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-845\" class=\"size-medium wp-image-845\" title=\"db4o-transparent-activation\" src=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/db4o-transparent-activation-300x157.png\" alt=\"transparent activation at work\" width=\"300\" height=\"157\" srcset=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/db4o-transparent-activation-300x157.png 300w, https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/db4o-transparent-activation.png 1024w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-845\" class=\"wp-caption-text\">transparent activation at work<\/p><\/div>\n<h3>No Way! I\u2019m Not Writing All This Boiler Plate Code<\/h3>\n<p>As you see above, writing Transparent Activation aware classes by hand is quite painful. All this boiler plate code\u00a0distracts from the important stuff and introduces potential bugs. That\u2019s why there\u2019s a byte-code enhancer tool which adds this behavior for you.<\/p>\n<p>There are two ways to achieve this: First there\u2019s command-line tool which you can use manually or call from your build-script. Additionally there\u2019s an MSBuild task. I use the MSBuild task here, since most people use Visual Studio anyway.<\/p>\n<p>So it\u2019s quite easy, you add an additional-task to your project-file. First you refer to the db4oTool.MSBuild-assembly. It\u2019s up to you where to put it. In my projects its in the lib-directory of the project. The you specify what to want to enhance, done. Note the additional \u2018debug\u2019-flag. This also updates the debug-information to allow you to step through your code.<\/p>\n<pre class=\"csharpcode\">  <span class=\"kwrd\">&lt;<\/span><span class=\"html\">UsingTask<\/span> <span class=\"attr\">AssemblyFile<\/span><span class=\"kwrd\">=\".\\lib\\db4o\\Db4oTool.MSBuild.dll\"<\/span> <span class=\"attr\">TaskName<\/span><span class=\"kwrd\">=\"Db4oTool.MSBuild.Db4oEnhancerMSBuildTask\"<\/span> <span class=\"kwrd\">\/&gt;<\/span>\r\n  <span class=\"kwrd\">&lt;<\/span><span class=\"html\">ItemGroup<\/span><span class=\"kwrd\">&gt;<\/span>\r\n    <span class=\"kwrd\">&lt;<\/span><span class=\"html\">Db4oEnhance<\/span> <span class=\"attr\">Include<\/span><span class=\"kwrd\">=\"$(TargetPath)\"<\/span> <span class=\"kwrd\">\/&gt;<\/span>\r\n  <span class=\"kwrd\">&lt;\/<\/span><span class=\"html\">ItemGroup<\/span><span class=\"kwrd\">&gt;<\/span>\r\n  <span class=\"kwrd\">&lt;<\/span><span class=\"html\">Target<\/span> <span class=\"attr\">Name<\/span><span class=\"kwrd\">=\"AfterBuild\"<\/span><span class=\"kwrd\">&gt;<\/span>\r\n    <span class=\"kwrd\">&lt;<\/span><span class=\"html\">Db4oEnhancerMSBuildTask<\/span> <span class=\"attr\">Assemblies<\/span><span class=\"kwrd\">=\"@(Db4oEnhance)\"<\/span> <span class=\"attr\">CommandLine<\/span><span class=\"kwrd\">=\"-debug\"<\/span><span class=\"kwrd\">\/&gt;<\/span>\r\n  <span class=\"kwrd\">&lt;\/<\/span><span class=\"html\">Target<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<p>Normally you create a separate assembly which contains only the persisted classes. Therefore you add this build-step only to the persisted-classes-project.<\/p>\n<p>You can also mark the classes by an attribute and tell the enhancer-task to updated only the marked classes. For example:<\/p>\n<pre class=\"csharpcode\">[AttributeUsage(AttributeTargets.Class,AllowMultiple = <span class=\"kwrd\">false<\/span>,Inherited = <span class=\"kwrd\">true<\/span>)]\r\n<span class=\"kwrd\">internal<\/span> <span class=\"kwrd\">class<\/span> PersistedAttribute : Attribute\r\n{\r\n}<\/pre>\n<p>And then:<\/p>\n<pre class=\"csharpcode\">&lt;Db4oEnhancerMSBuildTask Assemblies=<span class=\"str\">\"@(Db4oEnhance)\"<\/span> CommandLine=<span class=\"str\">\"-by-attribute:Db4OSeries.PersistedAttribute\"<\/span>\/&gt;<\/pre>\n<pre class=\"csharpcode\">\u00a0\r\n\r\n<div id=\"attachment_846\" style=\"width: 310px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/db4o-bytecode-enhancer.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-846\" class=\"size-medium wp-image-846\" title=\"db4o-bytecode-enhancer\" src=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/db4o-bytecode-enhancer-300x111.png\" alt=\"bytecode enhancer\" width=\"300\" height=\"111\" srcset=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/db4o-bytecode-enhancer-300x111.png 300w, https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/db4o-bytecode-enhancer.png 800w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-846\" class=\"wp-caption-text\">bytecode enhancer<\/p><\/div><\/pre>\n<h3>Collections<\/h3>\n<p>You probably use collections in your persisted class like a list or a map. Since you cannot change the code of the official .NET-collections, you need to use the db4o Transparent Activation aware implementations of collections. For example:<\/p>\n<pre class=\"csharpcode\">[Persisted]\r\n<span class=\"kwrd\">internal<\/span> <span class=\"kwrd\">class<\/span> Person\r\n{\r\n    <span class=\"kwrd\">private<\/span> <span class=\"kwrd\">readonly<\/span> IList&lt;Person&gt; knowsPeople = <span class=\"kwrd\">new<\/span> ArrayList4&lt;Person&gt;();\r\n\r\n    <span class=\"kwrd\">public<\/span> IEnumerable&lt;Person&gt; KnowsPeople\r\n    {\r\n        get { <span class=\"kwrd\">return<\/span> knowsPeople; }\r\n    }\r\n\r\n    <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">void<\/span> GetToKnow(Person person)\r\n    {\r\n        knowsPeople.Add(person);\r\n    }\r\n}<\/pre>\n<pre class=\"csharpcode\"><a href=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/db4o-collections.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-847\" title=\"db4o-collections\" src=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/db4o-collections.png\" alt=\"db4o-collections\" width=\"600\" height=\"357\" srcset=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/db4o-collections.png 600w, https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/db4o-collections-300x178.png 300w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/a>\u00a0<\/pre>\n<h3>Mix IActivatable With Non-Activatable<\/h3>\n<p>What happens when you mix and match IActivatable-classes with normal classes? Let\u2019s do a little experiment:<\/p>\n<pre class=\"csharpcode\"><span class=\"kwrd\">internal<\/span> <span class=\"kwrd\">class<\/span> Pet\r\n{\r\n    <span class=\"kwrd\">public<\/span> Pet(Pet otherPet)\r\n    {\r\n        OtherPet = otherPet;\r\n        Name = otherPet.Name + <span class=\"str\">\"\u2019s-child\"<\/span>;\r\n    } \r\n\r\n    <span class=\"kwrd\">public<\/span> Pet(<span class=\"kwrd\">string<\/span> name)\r\n    {\r\n        Name = name;\r\n    } \r\n\r\n    <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">string<\/span> Name { get; set; }\r\n    <span class=\"kwrd\">public<\/span> Pet OtherPet { get; set; }\r\n}<\/pre>\n<p>Extend the Person class above with:<\/p>\n<pre class=\"csharpcode\">        <span class=\"kwrd\">public<\/span> Pet Pet\r\n        {\r\n            get\r\n            {\r\n                Activate(ActivationPurpose.Read);\r\n                <span class=\"kwrd\">return<\/span> _pet;\r\n            }\r\n            set { _pet = <span class=\"kwrd\">value<\/span>; }\r\n        }<\/pre>\n<pre class=\"csharpcode\">\u00a0<\/pre>\n<pre class=\"csharpcode\">And access the a deep pet-object-graph:<\/pre>\n<pre class=\"csharpcode\">\u00a0<\/pre>\n<pre class=\"csharpcode\">         var me = (from Person p <span class=\"kwrd\">in<\/span> db\r\n               <span class=\"kwrd\">where<\/span> p.Firstname.Equals(<span class=\"str\">\"Roman\"<\/span>)\r\n               select p).Single();\r\n         var adam = me.Father.Father.Father.Father.Father.Father.Father;\r\n         var pet = me.Pet.OtherPet.OtherPet.OtherPet.OtherPet.OtherPet.OtherPet.OtherPet.OtherPet;\r\n         AssertEqual(<span class=\"str\">\"Adam\"<\/span>, adam.Firstname);\r\n         AssertEqual(<span class=\"str\">\"Fun\"<\/span>, pet.Name);<\/pre>\n<pre class=\"csharpcode\">\u00a0<\/pre>\n<p>This work\u2019s absolutely fine. The objects which are not activatable are just eagerly activated. For example: Some pure, simple Value-Object don\u2019t need to be lazy loaded from the database. It\u2019s just a small object and represents the end of the object-graph anyway.<\/p>\n<div id=\"attachment_848\" style=\"width: 310px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/db4o-activation-mixing.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-848\" class=\"size-medium wp-image-848\" title=\"db4o-activation-mixing\" src=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/db4o-activation-mixing-300x140.png\" alt=\"mix transparent activation with normal objects\" width=\"300\" height=\"140\" srcset=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/db4o-activation-mixing-300x140.png 300w, https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/db4o-activation-mixing.png 800w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-848\" class=\"wp-caption-text\">mix transparent activation with normal objects<\/p><\/div>\n<h3>Hybrid Approach<\/h3>\n<p>Now we\u2019ve seen what Transparent Activation is. It\u2019s really useful. But what if you want to stay in control and therefore avoid the bytecode-enhancer? Making every persisted class IActivateable by hand is just extremely painful.<\/p>\n<p>Based on the the observation above you could use a hybrid approach: Most of the classes do not implement IActivatable. But you use the Transparent Activation aware collections of db4o. Then you have already a quite useful construct: Everything is eager activated excluding the collections. Additionally you could\u00a0introduce a \u2018TransparentActivated\u2019-class. This class just represents a reference which is lazy loaded. So only\u00a0&#8216;special&#8217; references\u00a0and the collections are transparently activated. The rest of the object graph is just loaded normally.<\/p>\n<p>Take a looks at this small example (&lt;&lt;TA&gt;&gt; = Transparent Persistance used in this association):<\/p>\n<p>\u00a0<a href=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/TA-Hybrid.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-842\" title=\"TA-Hybrid\" src=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/TA-Hybrid.png\" alt=\"TA-Hybrid\" width=\"521\" height=\"360\" srcset=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/TA-Hybrid.png 521w, https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/TA-Hybrid-300x207.png 300w\" sizes=\"(max-width: 521px) 100vw, 521px\" \/><\/a><\/p>\n<p>So we could implement is like this:<\/p>\n<pre class=\"csharpcode\"><span class=\"kwrd\">internal<\/span> <span class=\"kwrd\">class<\/span> Person\r\n{\r\n    <span class=\"kwrd\">private<\/span> Gender _gender;\r\n    <span class=\"kwrd\">private<\/span> IList&lt;Address&gt; _addresses = <span class=\"kwrd\">new<\/span> ArrayList4&lt;Address&gt;();\r\n    <span class=\"kwrd\">private<\/span> <span class=\"kwrd\">readonly<\/span> TransparentActivated&lt;House&gt; _house = <span class=\"kwrd\">new<\/span> TransparentActivated&lt;House&gt;();\r\n\r\n    <span class=\"kwrd\">public<\/span> IEnumerable&lt;Address&gt; Addresses\r\n    {\r\n        get { <span class=\"kwrd\">return<\/span> _addresses; }\r\n    }\r\n\r\n    <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">void<\/span> Add(Address item)\r\n    {\r\n        _addresses.Add(item);\r\n    }\r\n\r\n    <span class=\"kwrd\">public<\/span> House House\r\n    {\r\n        get { <span class=\"kwrd\">return<\/span> _house.Value; }\r\n        set { _house.Value = <span class=\"kwrd\">value<\/span>; }\r\n    }\r\n\r\n    <span class=\"kwrd\">public<\/span> Gender Gender\r\n    {\r\n        get { <span class=\"kwrd\">return<\/span> _gender; }\r\n        set { _gender = <span class=\"kwrd\">value<\/span>; }\r\n    }\r\n}<\/pre>\n<pre class=\"csharpcode\"><span class=\"rem\">\/\/\/ &lt;summary&gt;<\/span>\r\n<span class=\"rem\">\/\/\/ Use this class to interrupt the eager loading of the database data into memory:<\/span>\r\n<span class=\"rem\">\/\/\/ this class represents a reference to &lt;see cref=\"T\"\/&gt;, whereas &lt;see cref=\"T\"\/&gt; is<\/span>\r\n<span class=\"rem\">\/\/\/ lazy activated as soon as &lt;see cref=\"Value\"\/&gt; is used<\/span>\r\n<span class=\"rem\">\/\/\/ &lt;\/summary&gt;<\/span>\r\n<span class=\"rem\">\/\/\/ &lt;typeparam name=\"T\"&gt;&lt;\/typeparam&gt;<\/span>\r\n<span class=\"kwrd\">internal<\/span> <span class=\"kwrd\">class<\/span> TransparentActivated&lt;T&gt;\r\n{\r\n    <span class=\"kwrd\">private<\/span> T _instance;\r\n    [Transient]\r\n    <span class=\"kwrd\">private<\/span> IActivator _activator;\r\n\r\n    <span class=\"kwrd\">public<\/span> T Value\r\n    {\r\n        get\r\n        {\r\n            Activate(ActivationPurpose.Read);\r\n            <span class=\"kwrd\">return<\/span> _instance;\r\n        }\r\n        set { _instance = <span class=\"kwrd\">value<\/span>; }\r\n    }\r\n    <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">void<\/span> Bind(IActivator activator)\r\n    {\r\n        <span class=\"kwrd\">if<\/span> (_activator == activator)\r\n            <span class=\"kwrd\">return<\/span>;\r\n        <span class=\"kwrd\">if<\/span> (activator != <span class=\"kwrd\">null<\/span> &amp;&amp; _activator != <span class=\"kwrd\">null<\/span>)\r\n            <span class=\"kwrd\">throw<\/span> <span class=\"kwrd\">new<\/span> InvalidOperationException(<span class=\"str\">\"cannot rebind with another activator\"<\/span>);\r\n        _activator = activator;\r\n    }\r\n\r\n    <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">void<\/span> Activate(ActivationPurpose purpose)\r\n    {\r\n        <span class=\"kwrd\">if<\/span> (<span class=\"kwrd\">null<\/span> != _activator)\r\n            _activator.Activate(purpose);\r\n    }\r\n}<\/pre>\n<pre class=\"csharpcode\">\u00a0<\/pre>\n<p>However, this\u00a0 has a huge drawback: Now the \u2018_house\u2019-field has additional indirection. Therefore the object-graph is even deeper which isn\u2019t free. Especially queries are more complex since more objects are involved.<\/p>\n<p>Anyway this hybrid approach isn\u2019t the indented use case for Transparent Activation. But it\u2019s a little demonstration that you can use Transparent Activation also very selective.<\/p>\n<h3>Transparent Persistence<\/h3>\n<p>There we are, we have a\u00a0nice solution to lazy load the object from the database as we need then. For this we make the persisted classes database aware. But wait! Why don\u2019t the persisted objects also manage changes? A object could notice when a property changes and store the changes to the database. That\u2019s exactly what Transparent Persistence does.<\/p>\n<p>First we need to extend also the setter, like this:<\/p>\n<pre class=\"csharpcode\"><span class=\"kwrd\">public<\/span> <span class=\"kwrd\">string<\/span> Firstname\r\n{\r\n    get\r\n    {\r\n        Activate(ActivationPurpose.Read);\r\n        <span class=\"kwrd\">return<\/span> _firstname;\r\n    }\r\n    set\r\n    {\r\n        Activate(ActivationPurpose.Write);\r\n        _firstname = <span class=\"kwrd\">value<\/span>;\r\n    }\r\n}<\/pre>\n<p>\u00a0<\/p>\n<p>As said, it\u2019s way smarter to the do this with the bytecode-enhancer. Guess what, the byte-code-enhancer already does this. So you don\u2019t have to change a thing. Just use the MSBuild-Task like above =).<\/p>\n<p>Furthermore you have to change the configuration. Instead of the TransparentActivationSupport you add the TransparentPersistenceSupport:<\/p>\n<pre class=\"csharpcode\">cfg.Common.Add(<span class=\"kwrd\">new<\/span> TransparentPersistenceSupport());<\/pre>\n<p>Now your ready for the easiest way to persist your objects. You have to store a object only once. From now on db4o knows that the object is persisted. The object stores all changes by itself. You get the objects from the database, manipulate the objects as you wish. As soon as you call commit, the changes are persisted. Isn\u2019t this wonderful =) An small example:<\/p>\n<pre class=\"csharpcode\"><span class=\"kwrd\">using<\/span> (var db = OpenDB(FilePath))\r\n{\r\n    var pers = <span class=\"kwrd\">new<\/span> Person();\r\n    pers.Add(<span class=\"kwrd\">new<\/span> Address(<span class=\"str\">\"Main.Street\"<\/span>, <span class=\"str\">\"A City\"<\/span>));\r\n    pers.House = <span class=\"kwrd\">new<\/span> House { Name = <span class=\"str\">\"My House\"<\/span> };\r\n    pers.Gender = Gender.Female;\r\n\r\n    <span class=\"rem\">\/\/ initial store<\/span>\r\n    db.Store(pers);\r\n}\r\n<span class=\"kwrd\">using<\/span> (var db = OpenDBWithTA(FilePath))\r\n{\r\n    var me = LoadPerson(db);\r\n    <span class=\"rem\">\/\/ some changes, note, NO STORE<\/span>\r\n    me.Add(<span class=\"kwrd\">new<\/span> Address(<span class=\"str\">\"Holiday-House\"<\/span>, <span class=\"str\">\"Other City\"<\/span>));\r\n    me.Gender=Gender.Male;\r\n    me.House.Name = <span class=\"str\">\"BiggerHouse\"<\/span>;\r\n}\r\n<span class=\"kwrd\">using<\/span> (var db = OpenDBWithTA(FilePath))\r\n{\r\n    var me = LoadPerson(db);\r\n    <span class=\"rem\">\/\/ everything is stored =)<\/span>\r\n    AssertTrue(me.Addresses.Count() == 2);\r\n    AssertTrue(me.Gender == Gender.Male);\r\n    AssertTrue(me.House.Name == <span class=\"str\">\"BiggerHouse\"<\/span>);\r\n}\u00a0<\/pre>\n<div id=\"attachment_849\" style=\"width: 310px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/db4o-transparent-persistance.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-849\" class=\"size-medium wp-image-849\" title=\"db4o-transparent-persistance\" src=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/db4o-transparent-persistance-300x129.png\" alt=\"transparent persistance\" width=\"300\" height=\"129\" srcset=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/db4o-transparent-persistance-300x129.png 300w, https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/db4o-transparent-persistance.png 1024w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-849\" class=\"wp-caption-text\">transparent persistance<\/p><\/div>\n<h3>Conclusion<\/h3>\n<p>Transparent Activation and Persistence are a powerful mechanisms which save you a lot of work. Use it wisely. =)<\/p>\n<p>The example-project with transparent persistance: <a href=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/12\/TransparentPersistance.zip\">TransparentPersistance.zip<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>It has been a while since I\u2019ve wrote my last post about db4o. You may remember the post about the activation-mechanism. Don\u2019t you think that this is quite painful? Activating&hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[150],"tags":[21,100],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts\/840"}],"collection":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/comments?post=840"}],"version-history":[{"count":19,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts\/840\/revisions"}],"predecessor-version":[{"id":3823,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts\/840\/revisions\/3823"}],"wp:attachment":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/media?parent=840"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/categories?post=840"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/tags?post=840"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}