You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2014/10/09 19:50:39 UTC

svn commit: r1630539 - /isis/site/trunk/content/more-advanced-topics/how-to-04-010-How-to-make-a-derived-property.md

Author: danhaywood
Date: Thu Oct  9 17:50:39 2014
New Revision: 1630539

URL: http://svn.apache.org/r1630539
Log:
ISIS-852

Modified:
    isis/site/trunk/content/more-advanced-topics/how-to-04-010-How-to-make-a-derived-property.md

Modified: isis/site/trunk/content/more-advanced-topics/how-to-04-010-How-to-make-a-derived-property.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/more-advanced-topics/how-to-04-010-How-to-make-a-derived-property.md?rev=1630539&r1=1630538&r2=1630539&view=diff
==============================================================================
--- isis/site/trunk/content/more-advanced-topics/how-to-04-010-How-to-make-a-derived-property.md (original)
+++ isis/site/trunk/content/more-advanced-topics/how-to-04-010-How-to-make-a-derived-property.md Thu Oct  9 17:50:39 2014
@@ -23,51 +23,82 @@ For example:
         ...
     }
 
-### Read-write
+### Read-write using a setter
 
 A derived property can be made updateable (in that it takes the provided
-value and does something sensible with it) by providing a `modifyXxx()`
-supporting method:
+value and does something sensible with it) simply providing a setter that
+has been annotated using both Isis' `@NotPersisted` attribute and JDO's
+`@javax.jdo.annotations.NotPersistent` attribute:
 
     public class Employee {
         public Department getDepartment() { ... }
         ...
 
-        // this is the derived property
+        @javax.jdo.annotations.NotPersistent
+        @NotPersisted
         public Employee getManager() { ... }
-
-        // this makes the derived property modifiable
-        public void modifyManager(Employee manager) {
+        public void setManager(Employee manager) {
             if (getDepartment() == null) { return; }
             getDepartment().modifyManager(manager);
         }
-
         ...
     }
 
-Note how the implementation of such a `modifyXxx()` method typically
-modifies the original source of the information (the Department object).
+### Read-write using a modify method (1.7.0-SNAPSHOT onwards)
 
-Alternatively, if you prefer to have a setter, then you can use Isis'
-@NotPersisted attribute.
+Alternatively, a derived property can be made updateable by providing a 
+`modifyXxx()` supporting method:
 
     public class Employee {
         public Department getDepartment() { ... }
         ...
 
-        @NotPersisted
+        // this is the derived property
         public Employee getManager() { ... }
-        public void setManager(Employee manager) {
+
+        // this makes the derived property modifiable
+        public void modifyManager(Employee manager) {
             if (getDepartment() == null) { return; }
             getDepartment().modifyManager(manager);
         }
+
         ...
     }
 
-> **Note**
->
-> If you use this approach, then for some object stores you may also
-> need to annotate the property to exclude it. For example the
-> JDO/DataNucleus object store requires the property being annotated
-> with @javax.jdo.annotations.NotPersistent.
+Note how the implementation of such a `modifyXxx()` method typically
+modifies the original source of the information (the Department object).
 
+### Caveats
+
+Beware of having two visible properties that update the same underlying data;
+which value "wins" is not well-defined.
+
+For example, consider this silly example:
+
+    public class ToDoItem {
+    
+        private String description;
+        public String getDescription() { return description; }
+        public void setDescription(String description) { this.description = description; }
+
+        public String getDerivedDescription() { return getDescription(); }
+        public void modifyDerivedDescription(String derivedDescription) { setDescription(derivedDescription); }
+        
+    }
+    
+The value that is persisted back will be either from the 'description' field
+or the 'derivedDescription' field, which is almost certainly not what was intended.
+
+The fix is easy enough; make one of the fields invisible, eg:
+
+    public class ToDoItem {
+    
+        private String description;
+        @Hidden // problem resolved!
+        public String getDescription() { return description; }
+        public void setDescription(String description) { this.description = description; }
+        
+        public String getDerivedDescription() { return getDescription(); }
+        public void modifyDerivedDescription(String derivedDescription) { setDescription(derivedDescription); }
+        
+    }