You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by bu...@apache.org on 2013/07/31 09:40:29 UTC
svn commit: r872059 - in /websites/staging/isis/trunk: cgi-bin/ content/
content/applib-guide/how-tos/ content/applib-guide/reference/
content/components/objectstores/jdo/ content/core/
Author: buildbot
Date: Wed Jul 31 07:40:29 2013
New Revision: 872059
Log:
Staging update by buildbot for isis
Added:
websites/staging/isis/trunk/content/components/objectstores/jdo/managed-1-to-m-relationships.html
Modified:
websites/staging/isis/trunk/cgi-bin/ (props changed)
websites/staging/isis/trunk/content/ (props changed)
websites/staging/isis/trunk/content/applib-guide/how-tos/how-to-04-060-How-to-set-up-and-maintain-bidirectional-relationships.html
websites/staging/isis/trunk/content/applib-guide/reference/Utility.html
websites/staging/isis/trunk/content/components/objectstores/jdo/about.html
websites/staging/isis/trunk/content/core/unittestsupport.html
websites/staging/isis/trunk/content/documentation.html
Propchange: websites/staging/isis/trunk/cgi-bin/
------------------------------------------------------------------------------
--- cms:source-revision (original)
+++ cms:source-revision Wed Jul 31 07:40:29 2013
@@ -1 +1 @@
-1507050
+1508746
Propchange: websites/staging/isis/trunk/content/
------------------------------------------------------------------------------
--- cms:source-revision (original)
+++ cms:source-revision Wed Jul 31 07:40:29 2013
@@ -1 +1 @@
-1507050
+1508746
Modified: websites/staging/isis/trunk/content/applib-guide/how-tos/how-to-04-060-How-to-set-up-and-maintain-bidirectional-relationships.html
==============================================================================
--- websites/staging/isis/trunk/content/applib-guide/how-tos/how-to-04-060-How-to-set-up-and-maintain-bidirectional-relationships.html (original)
+++ websites/staging/isis/trunk/content/applib-guide/how-tos/how-to-04-060-How-to-set-up-and-maintain-bidirectional-relationships.html Wed Jul 31 07:40:29 2013
@@ -254,6 +254,12 @@
<h2>How to set up and maintain bidirectional relationships</h2>
+<blockquote>
+ <p><strong>Note</strong>: </p>
+
+ <p>If using the <a href="../../components/objectstores/jdo/about.html">JDO Objectstore</a> then there is generally no need to explicitly maintain bidirectional relationships. Indeed, doing so may cause subtle errors. See <a href="../../components/objectstores/jdo/managed-1-to-m-relationships.html">here</a> for more details.</p>
+</blockquote>
+
<p>The modifyXxx() and clearXxx() methods (see ?) can be used to setup
bidirectional relationships. This is typically done with 1:m
relationships, eg between Order and OrderLine, or Department and
@@ -261,20 +267,19 @@ Employee.</p>
<p>The recommended way of maintaining a bidirectional relationship is to
use the 'mutual registration pattern', a write-up of which can be found
-at
-<a href="http://www.two-sdg.demon.co.uk/curbralan/papers/MutualRegistration.pdf">http://www.two-sdg.demon.co.uk/curbralan/papers/MutualRegistration.pdf</a>.
+<a href="http://www.two-sdg.demon.co.uk/curbralan/papers/MutualRegistration.pdf">here</a>.
The general idea is that one side of the relationship is responsible for
maintaining the associations, while the other side simply delegates.</p>
-<p>To implement this in <em>Isis</em> for a 1:m relationship, use the addToXxx() /
-removeFromXxx() and modifyXxx() / clearXxx() methods.</p>
+<p>To implement this in <em>Isis</em> for a 1:m relationship, use the <code>addToXxx()</code> /
+<code>removeFromXxx()</code> and the <code>modifyXxx()</code> / <code>clearXxx()</code> methods.</p>
<p>For example:</p>
<pre><code>public class Department {
- private List<Employee> employees = new ArrayList<Employee>();
- public List<Employee> getEmployees() { ... }
- private void setEmployees(List<Employee> employees) { ... }
+ private SortedSet<Employee> employees = new TreeSet<Employee>();
+ public SortedSet<Employee> getEmployees() { ... }
+ private void setEmployees(SortedSet<Employee> employees) { ... }
public void addToEmployees(Employee e) {
if(e == null || employees.contains(e)) return;
e.setDepartment(this);
@@ -310,13 +315,6 @@ removeFromXxx() and modifyXxx() / clearX
}
</code></pre>
-<blockquote>
- <p><strong>Note</strong></p>
-
- <p>For some object stores this explicit coding may not be necessary; the
- object store automatically maintains the relationship.</p>
-</blockquote>
-
</div>
Modified: websites/staging/isis/trunk/content/applib-guide/reference/Utility.html
==============================================================================
--- websites/staging/isis/trunk/content/applib-guide/reference/Utility.html (original)
+++ websites/staging/isis/trunk/content/applib-guide/reference/Utility.html Wed Jul 31 07:40:29 2013
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
- <title></title>
+ <title>Utility Classes
</title>
<meta name="description" content="">
<meta name="author" content="">
@@ -111,7 +111,7 @@
};
function twshare () {
window.open(
- "https://twitter.com/intent/tweet?url="+document.URL+"&text=",
+ "https://twitter.com/intent/tweet?url="+document.URL+"&text=Utility Classes
",
'Share on Twitter',
'width=800,height=526');
};
@@ -247,13 +247,11 @@
<div class="page-header">
<p><a href="./../../documentation.html">Docs</a> » <a href="./../../applib-guide/about.html">Applib Guide</a> » <a href="./../../applib-guide/reference/about.html">Reference</a></p>
-<h1>
+<h1>Utility Classes
</h1>
</div>
-<h1>Utility Classes</h1>
-
<blockquote>
<p>Simple utility classes for domain objects.</p>
</blockquote>
@@ -292,6 +290,36 @@ by <code>disableXxX()</code> and <code>v
<p>Which you use (if any) is up to you.</p>
+<h2>ObjectContracts</h2>
+
+<p>The <code>ObjectContracts</code> test provides a series of methods to make it easy for your domain objects to:</p>
+
+<ul>
+<li>implement <code>Comparable</code> (eg so can be stored in <code>java.util.SortedSet</code>s)</li>
+<li>implement <code>toString()</code></li>
+<li>implement <code>equals()</code></li>
+<li>implement <code>hashCode()</code></li>
+</ul>
+
+<p>For example:</p>
+
+<pre><code>public class ToDoItem implements Comparable<ToDoItem> {
+
+ public boolean isComplete() { ... }
+ public LocalDate getDueBy() { ... }
+ public String getDescription() { ... }
+ public String getOwnedBy() { ... }
+
+ public int compareTo(final ToDoItem other) {
+ return ObjectContracts.compare(this, other, "complete,dueBy,description");
+ }
+
+ public String toString() {
+ return ObjectContracts.toString(this, "description,complete,dueBy,ownedBy");
+ }
+}
+</code></pre>
+
</div>
Modified: websites/staging/isis/trunk/content/components/objectstores/jdo/about.html
==============================================================================
--- websites/staging/isis/trunk/content/components/objectstores/jdo/about.html (original)
+++ websites/staging/isis/trunk/content/components/objectstores/jdo/about.html Wed Jul 31 07:40:29 2013
@@ -261,6 +261,7 @@
<li><a href="datanucleus-and-maven.html">DataNucleus and Maven</a></li>
<li><a href="persistence_xml.html"><code>persistence.xml</code> file</a></li>
<li><a href="dates-blobs-lazy-loading.html">Dates, Blobs and Lazy Loading</a></li>
+<li><a href="managed-1-to-m-relationships.html">Managed 1:m bidirectional relationships</a></li>
<li><a href="using-jndi-datasource.html">Using a JNDI Datasource</a></li>
<li><a href="workarounds.html">Workarounds (the <code>IsisJdoSupport</code> service)</a></li>
<li><a href="enabling-logging.html">Enabling Logging</a></li>
Added: websites/staging/isis/trunk/content/components/objectstores/jdo/managed-1-to-m-relationships.html
==============================================================================
--- websites/staging/isis/trunk/content/components/objectstores/jdo/managed-1-to-m-relationships.html (added)
+++ websites/staging/isis/trunk/content/components/objectstores/jdo/managed-1-to-m-relationships.html Wed Jul 31 07:40:29 2013
@@ -0,0 +1,337 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+
+ <meta charset="utf-8">
+ <title>Managed 1:m bidirectional relationships</title>
+ <meta name="description" content="">
+ <meta name="author" content="">
+
+ <!-- Le HTML5 shim, for IE6-8 support of HTML elements -->
+ <!--[if lt IE 9]>
+ <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
+ <![endif]-->
+
+ <!-- Le styles -->
+ <link href="./../../../bootstrap.css" rel="stylesheet">
+ <link href="./../../../prettify.css" rel="stylesheet">
+
+ <style type="text/css">
+ body {
+ padding-top: 60px;
+ }
+ .sprite {
+ display: inline-block;
+ height: 20px;
+ margin: 0 auto 4px;
+ outline: medium none;
+ text-indent: -999em;
+ width: 24px;
+ background-image: url('./../../../images/sprites.png');
+ background-repeat: no-repeat;
+ overflow: hidden;
+ cursor: pointer;
+ }
+ .edit-page {
+ display: inline-block;
+ height: 20px;
+ margin: 0 auto 4px;
+ outline: medium none;
+ text-indent: -999em;
+ width: 24px;
+ background-image: url('./../../../images/edit.png');
+ background-repeat: no-repeat;
+ overflow: hidden;
+ cursor: pointer;
+ }
+ .fb-share {
+ background-position: 0px -40px;
+ }
+ .gp-share {
+ background-position: 0px 0px;
+ }
+ .tw-share {
+ background-position: 0px -80px;
+ }
+ .markdown-content {
+ min-height: 500px;
+ }
+ .book-image img {
+ border: 1px;
+ border-style: solid;
+ }
+ .release-matrix .heading {
+ background-color: #eeeeee;
+ }
+ .release-matrix .new {
+ color: #dd0000;
+ font-weight: bolder;
+ }
+ .stub,.note {
+ position: relative;
+ padding: 7px 15px;
+ margin-bottom: 18px;
+ color: #404040;
+ background-color: #eedc94;
+ background-repeat: repeat-x;
+ background-image: -khtml-gradient(linear, left top, left bottom, from(#fceec1), to(#eedc94));
+ background-image: -moz-linear-gradient(top, #fceec1, #eedc94);
+ background-image: -ms-linear-gradient(top, #fceec1, #eedc94);
+ background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fceec1), color-stop(100%, #eedc94));
+ background-image: -webkit-linear-gradient(top, #fceec1, #eedc94);
+ background-image: -o-linear-gradient(top, #fceec1, #eedc94);
+ background-image: linear-gradient(top, #fceec1, #eedc94);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fceec1', endColorstr='#eedc94', GradientType=0);
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ border-color: #eedc94 #eedc94 #e4c652;
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
+ border-width: 1px;
+ border-style: solid;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
+ -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
+ }
+ </style>
+ <script type="text/javascript">
+ function fbshare () {
+ window.open(
+ "http://www.facebook.com/sharer/sharer.php?u="+document.URL,
+ 'Share on Facebook',
+ 'width=640,height=426');
+ };
+ function gpshare () {
+ window.open(
+ "https://plus.google.com/share?url="+document.URL,
+ 'Share on Google+',
+ 'width=584,height=385');
+ };
+ function twshare () {
+ window.open(
+ "https://twitter.com/intent/tweet?url="+document.URL+"&text=Managed 1:m bidirectional relationships",
+ 'Share on Twitter',
+ 'width=800,height=526');
+ };
+ </script>
+
+ <!-- Le fav and touch icons -->
+ <link rel="shortcut icon" href="./../../../images/favicon.ico">
+ <!--
+ <link rel="apple-touch-icon" href="./../../../images/apple-touch-icon.png">
+ <link rel="apple-touch-icon" sizes="72x72" href="./../../../images/apple-touch-icon-72x72.png">
+ <link rel="apple-touch-icon" sizes="114x114" href="./../../../images/apple-touch-icon-114x114.png">
+ -->
+
+ <script src="./../../../javascript/prettify.js" type="text/javascript"></script>
+ <script src="./../../../javascript/jquery-latest.js"></script>
+
+
+ <script src="http://platform.twitter.com/widgets.js" type="text/javascript"></script>
+ <script src="./../../../javascript/common.js"></script>
+ <script src="./../../../javascript/prettyprint.js"></script>
+
+ <script src="./../../../javascript/bootstrap-alert.js"></script>
+ <script src="./../../../javascript/bootstrap-dropdown.js"></script>
+ <script src="./../../../javascript/bootstrap-tooltip.js"></script>
+ <!--
+ <script src="./../../../javascript/bootstrap-alerts.js"></script>
+ -->
+ <script src="./../../../javascript/bootstrap-modal.js"></script>
+ <script src="./../../../javascript/bootstrap-transition.js"></script>
+ <script src="./../../../javascript/bootstrap-button.js"></script>
+ <script src="./../../../javascript/bootstrap-popover.js"></script>
+ <script src="./../../../javascript/bootstrap-scrollspy.js"></script>
+ <script src="./../../../javascript/bootstrap-typeahead.js"></script>
+ <script src="./../../../javascript/bootstrap-carousel.js"></script>
+ <script src="./../../../javascript/bootstrap-tab.js"></script>
+ <script src="./../../../javascript/bootstrap-collapse.js"></script>
+
+
+
+
+
+ <script>
+ $(function () { prettyPrint() })
+ $().dropdown()
+ </script>
+
+ <!-- GAQ stuff removed here -->
+
+
+ </head>
+
+ <body>
+
+ <div class="topbar">
+ <div class="fill">
+ <div class="container">
+ <a class="brand" href="./../../../index.html">Apache Isis™</a>
+ <ul class="nav">
+ <li class="dropdown">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">Apache <b class="caret"></b></a>
+ <ul class="dropdown-menu">
+ <li>
+ <a href="http://www.apache.org/">Apache Homepage <i class="icon-share-alt"></i></a>
+ </li>
+ <li>
+ <a href="http://www.apache.org/licenses/">Licenses <i class="icon-share-alt"></i></a>
+ </li>
+ <li>
+ <a href="http://www.apache.org/security/">Security <i class="icon-share-alt"></i></a>
+ </li>
+ <li>
+ <a href="http://www.apache.org/foundation/sponsorship.html">Sponsorship <i class="icon-share-alt"></i></a>
+ </li>
+ <li>
+ <a href="http://www.apache.org/foundation/thanks.html">Thanks <i class="icon-share-alt"></i></a>
+ </li>
+ <li>
+ <a href="./../../../more-thanks.html">More thanks <i class="icon-share-alt"></i></a>
+ </li>
+ </ul>
+ </li>
+ <li><a href="./../../../index.html">Home</a></li>
+ <li><a href="./../../../download.html">Download</a></li>
+ <li class="dropdown">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">Screenshots<b class="caret"></b></a>
+ <ul class="dropdown-menu">
+ <li><a href="./../../../getting-started/screenshots.html">Screenshots</a></li>
+ <li><a href="./../../../getting-started/screencasts.html">Screencasts</a></li>
+ <li><a href="./../../../getting-started/powered-by.html">Powered by</a></li>
+ <!--
+ <li><a href="#">Online Demo</a></li>
+ -->
+ </ul>
+ </li>
+ <li><a href="./../../../documentation.html">Documentation</a></li>
+ <li><a href="./../../../support.html">Support</a></li>
+
+ </ul>
+
+ <!-- Google CSE Search Box Begins -->
+ <div style="float: right; position: relative; ">
+
+ <!--
+ <form action="http://www.google.com/cse" id="cse-search-box" _lpchecked="1">
+ <div>
+ <input type="hidden" name="cx" value="012614087480249044419:dn-q5gtwxya">
+ <input type="hidden" name="ie" value="UTF-8">
+ <input type="text" name="q" placeholder="Search" size="31" style="border: 1px solid rgb(126, 157, 185); padding: 2px; background-color: rgb(255, 255, 255); background-position: 0% 50%; background-repeat: no-repeat no-repeat;">
+ <input type="submit" name="sa" value="Search">
+ </div>
+ <input name="siteurl" type="hidden" value="isis.apache.org">
+ <input name="ref" type="hidden" value="">
+ <input name="ss" type="hidden" value="677j458329j2">
+ </form>
+ -->
+
+ <FORM class="pull-right" id="searchbox_012614087480249044419:dn-q5gtwxya" action="http://www.google.com/cse">
+ <input type="hidden" name="cx" value="012614087480249044419:dn-q5gtwxya">
+ <INPUT type="hidden" name="cof" value="FORID:0">
+ <INPUT name="q" type="text" placeholder="Search">
+ </FORM>
+
+ </div>
+ <!-- Google CSE Search Box Ends -->
+
+ </div>
+ </div>
+ </div>
+
+ <div class="container">
+ <div class="markdown-content">
+
+
+<div class="page-header">
+<p><a href="./../../../documentation.html">Docs</a> » <a href="./../../../components/about.html">Components</a> » <a href="./../../../components/objectstores/about.html">Objectstores</a> » <a href="./../../../components/objectstores/jdo/about.html">Jdo</a></p>
+<h1>Managed 1:m bidirectional relationships
+
+</h1>
+</div>
+
+<p>When an object is added to a 1:m bidirectional relationship, the child object must refer to the parent and the child must be added to the parent's children collection.</p>
+
+<p>In general, <em>Isis</em> recommends that the mutual registration pattern is ensure that both the parent and child are updated correctly; the framework supports the <code>modifyXxx()</code> and <code>clearXxx()</code> methods to accomplish this, and this <a href="../../../applib-guide/how-tos/how-to-04-060-How-to-set-up-and-maintain-bidirectional-relationships.html">how-to</a> describes the boilerplate necessary. </p>
+
+<p>However, in a relational database, these two operations in the domain object model correspond simply to updating the foreign key of the child table to reference the parent's primary key.</p>
+
+<p>So long as the parent's children collection is a <code>java.util.Set</code> (rather than a <code>Collection</code> or a <code>List</code>), the JDO Objectstore will automatically maintain both sides of the relationship. All that is necessary is to set the child to refer to the parent.</p>
+
+<p>For example</p>
+
+<pre><code>public class Department {
+
+ @javax.jdo.annotations.Persistent(mappedBy="department")
+ private SortedSet<Employee> employees = new TreeSet<Employee>();
+
+ public SortedSet<Employee> getEmployees() { ... }
+ public void setEmployees(SortedSet<Employee> employees) { ... }
+ ...
+}
+</code></pre>
+
+<p>and</p>
+
+<pre><code>public class Employee {
+ private Department department;
+ public Department getDepartment() { ... }
+ public void setDepartment(Department department) { ... }
+ ...
+}
+</code></pre>
+
+<p>Contrast the above with the programmatic maintenance described in the <a href="../../../applib-guide/how-tos/how-to-04-060-How-to-set-up-and-maintain-bidirectional-relationships.html">how-to</a>.</p>
+
+<blockquote>
+ <p><strong>Note</strong></p>
+
+ <p>In fact, not only do you not need to manually maintain the relationship, we have noted on at least <a href="http://markmail.org/message/agnwmzocvdfht32f">one occasion</a> a subtle error if the code is programmatically added.</p>
+
+ <p>The error in that case was that the same object was contained in the parents collection. This of course should not happen for a <code>TreeSet</code>. However, JDO/DataNucleus replaces the <code>TreeSet</code> with its own implementation, and (either by design or otherwise) this does not enforce <code>Set</code> semantics.</p>
+
+ <p>The upshot is that you should NEVER programmatically add the child object to the parent's collection if using JDO Objectstore.</p>
+</blockquote>
+
+
+
+ </div>
+
+ <div id="edit" class="modal hide fade in" style="display: none; ">
+ <div class="modal-header">
+ <a class="close" data-dismiss="modal">x</a>
+
+ <h3>Thank you for contributing to the documention!</h3>
+ </div>
+ <div class="modal-body">
+ <h4>Any help with the documentation is greatly appreciated.</h4>
+ <p>All edits are reviewed before going live, so feel free to do much more than fix typos or links. If you see a page that could benefit from an entire rewrite, we'd be thrilled to review it. Don't be surprised if we like it so much we ask you for help with other pages :)</p>
+ <small>NOTICE: unless indicated otherwise on the pages in question, all editable content available from apache.org is presumed to be licensed under the Apache License (AL) version 2.0 and hence all submissions to apache.org treated as formal Contributions under the license terms.</small>
+ <!--[if gt IE 6]>
+ <h4>Internet Explorer Users</h4>
+ <p>If you are not an Apache committer, click the Yes link and enter a <i>anonymous</i> for the username and leave the password empty</p>
+ <![endif]-->
+
+ </div>
+ <div class="modal-footer">
+ Do you have an Apache ID?
+ <a href="javascript:void(location.href='https://cms.apache.org/redirect?uri='+escape(location.href))" class="btn">Yes</a>
+ <a href="javascript:void(location.href='https://anonymous:@cms.apache.org/redirect?uri='+escape(location.href))" class="btn">No</a>
+ </div>
+ </div>
+ <script src="./../../../javascript/bootstrap-modal.js"></script>
+
+ <footer>
+ <p>
+ Copyright © 2012~2013 The Apache Software Foundation, Licensed under the Apache License, Version 2.0.
+ <br/>
+ Apache Isis, Isis, Apache, the Apache feather logo, and the Apache Isis project logo are trademarks of The Apache Software Foundation.
+ </p>
+ </footer>
+
+ </div> <!-- /container -->
+
+ </body>
+</html>
Modified: websites/staging/isis/trunk/content/core/unittestsupport.html
==============================================================================
--- websites/staging/isis/trunk/content/core/unittestsupport.html (original)
+++ websites/staging/isis/trunk/content/core/unittestsupport.html Wed Jul 31 07:40:29 2013
@@ -263,13 +263,94 @@
</dependency>
</pre>
-<h2>Bidirectional Contract Tests [1.3.0-SNAPSHOT]</h2>
+<h2>SortedSets Contract Test [1.3.0-SNAPSHOT]</h2>
-<p>Automatically tests that bidirectional 1:m or 1:1 associations are being maintained correctly (assuming that they follow the <a href="../applib-guide/how-tos/how-to-04-060-How-to-set-up-and-maintain-bidirectional-relationships.html">mutual registration pattern</a></p>
+<p>This contract test automatically checks that all fields of type <code>java.util.Collection</code> are declared as <code>java.util.SortedSet</code>. In other words, it precludes either <code>java.util.List</code> or <code>java.util.Set</code> from being used as a collection.</p>
-<p><div class="note">
-Isis provides <a href="../getting-started/editor-templates.html">Eclipse templates</a> to help generate the necessary boilerplate.
-</div></p>
+<p>For example, the following passes the contract test:</p>
+
+<pre><code>public class Department {
+
+ private SortedSet<Employee> employees = new TreeSet<Employee>();
+
+ ...
+}
+</code></pre>
+
+<p>whereas this would not:</p>
+
+<pre><code>public class SomeDomainObject {
+
+ private List<Employee> employees = new ArrayList<Employee>();
+
+ ...
+}
+</code></pre>
+
+<p>If using the JDO Objectstore then we strongly recommend that you implement this test, for several reasons:</p>
+
+<ul>
+<li>First, <code>Set</code>s align more closely to the relational model than do <code>List</code>s. A <code>List</code> must have an additional index to specify order.</li>
+<li>Second, <code>SortedSet</code> is preferable to <code>Set</code> because then the order is well-defined and predictable (to an end user, to the programmer).</p>
+
+<p>The <a href="../applib-guide/reference/Utility.html">ObjectContracts</a> utility class substantially simplifies the task of implementing <code>Comparable</code> in your domain classes. </li>
+<li>Third, if the relationship is bidirectional then JDO/Objectstore will automatically maintain the relationship. See <a href="../components/objectstores/jdo/managed-1-to-m-relationships.html">here</a> for further discussion. </li>
+</ul>
+
+<p>To use the contract test, subclass <code>SortedSetsContractTestAbstract</code>, specifying the root package to search for domain classes.</p>
+
+<p>For example:</p>
+
+<pre><code>public class SortedSetsContractTestAll extends SortedSetsContractTestAbstract {
+
+ public SortedSetsContractTestAll() {
+ super("org.estatio.dom");
+ withLoggingTo(System.out);
+ }
+}
+</code></pre>
+
+<h2>Injected Services Method Contract Test [1.3.0-SNAPSHOT]</h2>
+
+<p>It is quite common for some basic services to be injected in a project-specific domain object superclass; for example a <code>ClockService</code> might generally be injected everywhere:</p>
+
+<pre><code>public abstract class EstatioDomainObject {
+ protected ClockService clockService;
+ public void injectClockService(ClockService clockService) {
+ this.clockService = clockService;
+ }
+}
+</code></pre>
+
+<p>If a subclass inadvertantly overrides this method and provides its own <code>ClockService</code> field, then the field in the superclass will never initialized. As you might imagine, <code>NullPointerException</code>s could then arise.</p>
+
+<p>This contract test automatically checks that the <code>injectXxx(...)</code> method, to allow for injected services, is not overridable, ie <code>final</code>.</p>
+
+<p>To use the contract test, , subclass <code>SortedSetsContractTestAbstract</code>, specifying the root package to search for domain classes.</p>
+
+<p>For example:</p>
+
+<pre><code>public class InjectServiceMethodMustBeFinalContractTestAll extends InjectServiceMethodMustBeFinalContractTestAbstract {
+
+ public InjectServiceMethodMustBeFinalContractTestAll() {
+ super("org.estatio.dom");
+ withLoggingTo(System.out);
+ }
+}
+</code></pre>
+
+<h2>Bidirectional Contract Test [1.3.0-SNAPSHOT]</h2>
+
+<p>This contract test automatically checks that bidirectional 1:m or 1:1 associations are being maintained correctly (assuming that they follow the <a href="../applib-guide/how-tos/how-to-04-060-How-to-set-up-and-maintain-bidirectional-relationships.html">mutual registration pattern</a></p>
+
+<p>>
+<strong>Note:</strong>
+>
+If using the <a href="../components/objectstores/jdo/about.html">JDO Object Store</a>, then there is generally no need to programmatically maintain 1:m relationships (indeed it may introduce subtle errors). For more details, see <a href="../components/objectstores/jdo/managed-1-to-m-relationships.html">here</a>.</p>
+
+<blockquote>
+ <p>If <em>not</em> using the JDO Object Store, note that <em>Isis</em> provides <a href="../getting-started/editor-templates.html">Eclipse templates</a> to help generate the necessary boilerplate.</p>
+</blockquote>
<p>For example, suppose that <code>ParentDomainObject</code> and <code>ChildDomainObject</code> have a 1:m relationship (<code>ParentDomainObject#children</code> / <code>ChildDomainObject#parent</code>), and also <code>PeerDomainObject</code> has a 1:1 relationship with itself (<code>PeerDomainObject#next</code> / <code>PeerDomainObject#previous</code>). </p>
Modified: websites/staging/isis/trunk/content/documentation.html
==============================================================================
--- websites/staging/isis/trunk/content/documentation.html (original)
+++ websites/staging/isis/trunk/content/documentation.html Wed Jul 31 07:40:29 2013
@@ -262,6 +262,7 @@
<li><a href="getting-started/screencasts.html">Screencasts</a></li>
<li><a href="getting-started/quickstart-archetype.html">Wicket/Restful/JDO Archetype</a> (<a href="getting-started/release-notes/about.html">1.0.3</a>)</li>
<li><a href="applib-guide/about.html">Programming Model and How-tos</a></li>
+<li><a href="applib-guide/reference/Utility.html">Applib utility classes</a></li>
<li><a href="core/dynamic-layouts.html">Static and dynamic layouts</a></li>
<li><a href="getting-started/cheat-sheet.html">Programming Model Cheat Sheet</a></li>
</ul>
@@ -449,6 +450,7 @@
<li><a href="components/objectstores/jdo/datanucleus-and-maven.html">DataNucleus and Maven</a></li>
<li><a href="components/objectstores/jdo/persistence_xml.html"><code>persistence.xml</code> file</a></li>
<li><a href="components/objectstores/jdo/dates-blobs-lazy-loading.html">Dates, Blobs and Lazy Loading</a></li>
+<li><a href="components/objectstores/jdo/managed-1-to-m-relationships.html">Managed 1:m bidirectional relationships</a></li>
<li><a href="components/objectstores/jdo/using-jndi-datasource.html">Using a JNDI Datasource</a></li>
<li><a href="components/objectstores/jdo/workarounds.html">Workarounds</a></li>
<li><a href="components/objectstores/jdo/enabling-logging.html">Enabling Logging</a></li>