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 2015/11/25 19:23:51 UTC

[4/5] isis-site git commit: ISIS-803 custom lifecycle events; live templates

http://git-wip-us.apache.org/repos/asf/isis-site/blob/2d3a7aab/content/guides/rg.html
----------------------------------------------------------------------
diff --git a/content/guides/rg.html b/content/guides/rg.html
index 7e254c4..6d2ff81 100644
--- a/content/guides/rg.html
+++ b/content/guides/rg.html
@@ -5015,6 +5015,16 @@ can be used instead, eg:</p>
 </div></div></td>
 </tr>
 <tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rg_annotations_manpage-DomainObject_createdLifecycleEvent"><code>created-</code><br>
+<code>LifecycleEvent()</code></a><br>
+(<code>1.11.0-SNAPSHOT</code>)</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">subtype of <code>ObjectCreatedEvent</code><br>
+(<code>ObjectCreatedEvent.Default</code>)</p></td>
+<td class="tableblock halign-left valign-top"><div><div class="paragraph">
+<p>the event type to be posted to the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> whenever an instance is created</p>
+</div></div></td>
+</tr>
+<tr>
 <td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rg_annotations_manpage-DomainObject_editing"><code>editing()</code></a></p></td>
 <td class="tableblock halign-left valign-top"><p class="tableblock"><code>AS_CONFIGURED</code>, <code>ENABLED</code>, <code>DISABLED</code><br>
 (<code>AS_CONFIGURED</code>)</p></td>
@@ -5037,6 +5047,26 @@ can be used instead, eg:</p>
 </div></div></td>
 </tr>
 <tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rg_annotations_manpage-DomainObject_persistedLifecycleEvent"><code>persisted-</code><br>
+<code>LifecycleEvent()</code></a><br>
+(<code>1.11.0-SNAPSHOT</code>)</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">subtype of <code>ObjectPersistedEvent</code><br>
+(<code>ObjectPersistedEvent.Default</code>)</p></td>
+<td class="tableblock halign-left valign-top"><div><div class="paragraph">
+<p>the event type to be posted (<code>1.11.0-SNAPSHOT</code>) to the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> whenever an instance has just been persisted</p>
+</div></div></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rg_annotations_manpage-DomainObject_persistingLifecycleEvent"><code>persisting-</code><br>
+<code>LifecycleEvent()</code></a><br>
+(<code>1.11.0-SNAPSHOT</code>)</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">subtype of <code>ObjectPersistingEvent</code><br>
+(<code>ObjectPersistingEvent.Default</code>)</p></td>
+<td class="tableblock halign-left valign-top"><div><div class="paragraph">
+<p>the event type to be posted (<code>1.11.0-SNAPSHOT</code>) to the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> whenever an instance is about to be persisted</p>
+</div></div></td>
+</tr>
+<tr>
 <td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rg_annotations_manpage-DomainObject_publishing"><code>publishing()</code></a></p></td>
 <td class="tableblock halign-left valign-top"><p class="tableblock"><code>AS_CONFIGURED</code>, <code>ENABLED</code>, <code>DISABLED</code><br>
 (<code>AS_CONFIGURED</code>)</p></td>
@@ -5052,6 +5082,36 @@ can be used instead, eg:</p>
 <p>specifies that a custom implementation of <code>PublishingPayloadFactoryForObject</code> be used to create the (payload of the) published event representing the change to the object</p>
 </div></div></td>
 </tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rg_annotations_manpage-DomainObject_removingLifecycleEvent"><code>removing-</code><br>
+<code>LifecycleEvent()</code></a><br>
+(<code>1.11.0-SNAPSHOT</code>)</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">subtype of <code>ObjectRemovingEvent</code><br>
+(<code>ObjectRemovingEvent.Default</code>)</p></td>
+<td class="tableblock halign-left valign-top"><div><div class="paragraph">
+<p>the event type to be posted (<code>1.11.0-SNAPSHOT</code>) to the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> whenever an instance is about to be deleted</p>
+</div></div></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rg_annotations_manpage-DomainObject_updatedLifecycleEvent"><code>updated-</code><br>
+<code>LifecycleEvent()</code></a><br>
+(<code>1.11.0-SNAPSHOT</code>)</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">subtype of <code>ObjectUpdatedEvent</code><br>
+(<code>ObjectUpdatedEvent.Default</code>)</p></td>
+<td class="tableblock halign-left valign-top"><div><div class="paragraph">
+<p>the event type to be posted (<code>1.11.0-SNAPSHOT</code>) to the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> whenever an instance has just been updated</p>
+</div></div></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rg_annotations_manpage-DomainObject_updatingLifecycleEvent"><code>updating-</code><br>
+<code>LifecycleEvent()</code></a><br>
+(<code>1.11.0-SNAPSHOT</code>)</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">subtype of <code>ObjectUpdatingEvent</code><br>
+(<code>ObjectUpdatingEvent.Default</code>)</p></td>
+<td class="tableblock halign-left valign-top"><div><div class="paragraph">
+<p>the event type to be posted (<code>1.11.0-SNAPSHOT</code>) to the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> whenever an instance is about to be updated</p>
+</div></div></td>
+</tr>
 </tbody>
 </table>
 <div class="paragraph">
@@ -5062,8 +5122,9 @@ can be used instead, eg:</p>
 <pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObject</span>(
     auditing=Auditing.ENABLED,
     autoCompleteRepository=CustomerRepository.class
-    editing=Editing.ENABLED,               <i class="conum" data-value="1"></i><b>(1)</b>
-    publishing=Publishing.ENABLED
+    editing=Editing.ENABLED,                            <i class="conum" data-value="1"></i><b>(1)</b>
+    updatedLifecycleEvent=Customer.UpdatedEvent.class
+
 )
 <span class="directive">public</span> <span class="type">class</span> <span class="class">Customer</span> {
     ...
@@ -5282,7 +5343,123 @@ can be used instead, eg:</p>
 </div>
 </div>
 <div class="sect3">
-<h4 id="_rg_annotations_manpage-DomainObject_editing">2.9.4. <code>editing()</code></h4>
+<h4 id="_rg_annotations_manpage-DomainObject_createdLifecycleEvent">2.9.4. createdLifecycleEvent() (<code>1.11.0-SNAPSHOT</code>)</h4>
+<div class="paragraph">
+<p>Whenever a domain object is instantiated or otherwise becomes known to the framework, a "created" lifecycle event is fired.  This is typically when the <a href="#_rg_services-api_manpage-DomainObjectContainer"><code>DomainObjectContainer</code></a>'s <a href="#_rg_services-api_manpage-DomainObjectContainer_object-creation-api"><code>newTransientInstance()</code></a> is called;
+it will also happen if the object is simply instantiated with <code>new(&#8230;&#8203;)</code>, and then the container&#8217;s
+<a href="#_rg_services-api_manpage-DomainObjectContainer_services-api"><code>injectServicesInto(&#8230;&#8203;)</code></a> method is called.</p>
+</div>
+<div class="paragraph">
+<p>Subscribers subscribe through the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> and can
+use the event to obtain a reference to the object just created.  The subscriber could then, for example, update the
+object, eg looking up state from some external datastore.</p>
+</div>
+<div class="paragraph">
+<p>By default the event raised is <code>ObjectCreatedEvent.Default</code>. For example:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObject</span>
+<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItemDto</span> {
+    ...
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>The purpose of the <code>createdLifecycleEvent()</code> attribute is to allows a custom subclass to be emitted instead.  A similar
+attribute is available for other lifecycle events.</p>
+</div>
+<div class="paragraph">
+<p>For example:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObjectLayout</span>(
+    createdLifecycleEvent=ToDoItem.CreatedEvent.class
+)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItem</span> {
+    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">CreatedEvent</span>
+        <span class="directive">extends</span> org.apache.isis.applib.services.eventbus.ObjectCreatedEvent&lt;ToDoItem&gt; { }
+    ...
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>The benefit is that subscribers can be more targeted as to the events that they subscribe to.</p>
+</div>
+<div class="sect4">
+<h5 id="_subscribers_3">Subscribers</h5>
+<div class="paragraph">
+<p>Subscribers (which must be domain services) subscribe using either the <a href="https://github.com/google/guava">Guava</a> API
+or (if the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> has been appropriately configured)
+using the <a href="http://www.axonframework.org/">Axon Framework</a> API.  The examples below use the Guava API.</p>
+</div>
+<div class="paragraph">
+<p>Subscribers can be either coarse-grained (if they subscribe to the top-level event type):</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
+    <span class="annotation">@com</span>.google.common.eventbus.Subscribe
+    <span class="directive">public</span> <span class="type">void</span> on(ObjectCreatedEvent ev) {
+        <span class="keyword">if</span>(ev.getSource() <span class="keyword">instanceof</span> ToDoItem) { ... }
+    }
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>or can be fine-grained (by subscribing to specific event subtypes):</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
+    <span class="annotation">@com</span>.google.common.eventbus.Subscribe
+    <span class="directive">public</span> <span class="type">void</span> on(ToDoItem.ObjectCreatedEvent ev) {
+        ...
+    }
+}</code></pre>
+</div>
+</div>
+<div class="admonitionblock tip">
+<table>
+<tr>
+<td class="icon">
+<i class="fa icon-tip" title="Tip"></i>
+</td>
+<td class="content">
+<div class="paragraph">
+<p>If the AxonFramework is being used, replace <code>@com.google.common.eventbus.Subscribe</code> with <code>@org.axonframework.eventhandling.annotation.EventHandler</code>.</p>
+</div>
+</td>
+</tr>
+</table>
+</div>
+</div>
+<div class="sect4">
+<h5 id="_default_doop_and_noop_events">Default, Doop and Noop events</h5>
+<div class="paragraph">
+<p>If the <code>createdLifecycleEvent</code> attribute is not explicitly specified (is left as its default value, <code>ObjectCreatedEvent.Default</code>),
+then the framework will, by default, post an event.</p>
+</div>
+<div class="paragraph">
+<p>If this is not required, then the <code>isis.reflector.facet.domainObjectAnnotation.createdLifecycleEvent.postForDefault</code>
+configuration property can be set to "false"; this will disable posting.</p>
+</div>
+<div class="paragraph">
+<p>On the other hand, if the <code>createdLifecycleEvent</code> has been explicitly specified to some subclass, then an event will be posted.
+The framework provides <code>ObjectCreatedEvent.Doop</code> as such a subclass, so setting the <code>createdLifecycleEvent</code> attribute to this class
+will ensure that the event to be posted, irrespective of the configuration property setting.</p>
+</div>
+<div class="paragraph">
+<p>And, conversely, the framework also provides <code>ObjectCreatedEvent.Noop</code>; if <code>createdLifecycleEvent</code> attribute is set to this class,
+then no event will be posted.</p>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_rg_annotations_manpage-DomainObject_editing">2.9.5. <code>editing()</code></h4>
 <div class="paragraph">
 <p>The <code>editing()</code> attribute determines whether a domain object&#8217;s properties and collections are not editable (are read-only).</p>
 </div>
@@ -5366,7 +5543,121 @@ can be used instead, eg:</p>
 </div>
 </div>
 <div class="sect3">
-<h4 id="_rg_annotations_manpage-DomainObject_nature">2.9.5. <code>nature()</code></h4>
+<h4 id="_rg_annotations_manpage-DomainObject_loadedLifecycleEvent">2.9.6. loadedLifecycleEvent() (<code>1.11.0-SNAPSHOT</code>)</h4>
+<div class="paragraph">
+<p>Whenever a persistent domain object is loaded from the database, a "loaded" lifecycle event is fired.</p>
+</div>
+<div class="paragraph">
+<p>Subscribers subscribe through the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> and can
+use the event to obtain a reference to the domain object just loaded.  The subscriber could then, for example, update
+or default values on the object (eg to support on-the-fly migration scenarios).</p>
+</div>
+<div class="paragraph">
+<p>By default the event raised is <code>ObjectLoadedEvent.Default</code>. For example:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObject</span>
+<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItemDto</span> {
+    ...
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>The purpose of the <code>loadedLifecycleEvent()</code> attribute is to allows a custom subclass to be emitted instead.  A similar
+attribute is available for other lifecycle events.</p>
+</div>
+<div class="paragraph">
+<p>For example:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObjectLayout</span>(
+    loadedLifecycleEvent=ToDoItem.LoadedEvent.class
+)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItem</span> {
+    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">LoadedEvent</span>
+        <span class="directive">extends</span> org.apache.isis.applib.services.eventbus.ObjectLoadedEvent&lt;ToDoItem&gt; { }
+    ...
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>The benefit is that subscribers can be more targeted as to the events that they subscribe to.</p>
+</div>
+<div class="sect4">
+<h5 id="_subscribers_4">Subscribers</h5>
+<div class="paragraph">
+<p>Subscribers (which must be domain services) subscribe using either the <a href="https://github.com/google/guava">Guava</a> API
+or (if the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> has been appropriately configured)
+using the <a href="http://www.axonframework.org/">Axon Framework</a> API.  The examples below use the Guava API.</p>
+</div>
+<div class="paragraph">
+<p>Subscribers can be either coarse-grained (if they subscribe to the top-level event type):</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
+    <span class="annotation">@com</span>.google.common.eventbus.Subscribe
+    <span class="directive">public</span> <span class="type">void</span> on(ObjectLoadedEvent ev) {
+        <span class="keyword">if</span>(ev.getSource() <span class="keyword">instanceof</span> ToDoItem) { ... }
+    }
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>or can be fine-grained (by subscribing to specific event subtypes):</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
+    <span class="annotation">@com</span>.google.common.eventbus.Subscribe
+    <span class="directive">public</span> <span class="type">void</span> on(ToDoItem.ObjectLoadedEvent ev) {
+        ...
+    }
+}</code></pre>
+</div>
+</div>
+<div class="admonitionblock tip">
+<table>
+<tr>
+<td class="icon">
+<i class="fa icon-tip" title="Tip"></i>
+</td>
+<td class="content">
+<div class="paragraph">
+<p>If the AxonFramework is being used, replace <code>@com.google.common.eventbus.Subscribe</code> with <code>@org.axonframework.eventhandling.annotation.EventHandler</code>.</p>
+</div>
+</td>
+</tr>
+</table>
+</div>
+</div>
+<div class="sect4">
+<h5 id="_default_doop_and_noop_events_2">Default, Doop and Noop events</h5>
+<div class="paragraph">
+<p>If the <code>loadedLifecycleEvent</code> attribute is not explicitly specified (is left as its default value, <code>ObjectLoadedEvent.Default</code>),
+then the framework will, by default, post an event.</p>
+</div>
+<div class="paragraph">
+<p>If this is not required, then the <code>isis.reflector.facet.domainObjectAnnotation.loadedLifecycleEvent.postForDefault</code>
+configuration property can be set to "false"; this will disable posting.</p>
+</div>
+<div class="paragraph">
+<p>On the other hand, if the <code>loadedLifecycleEvent</code> has been explicitly specified to some subclass, then an event will be posted.
+The framework provides <code>ObjectLoadedEvent.Doop</code> as such a subclass, so setting the <code>loadedLifecycleEvent</code> attribute to this class
+will ensure that the event to be posted, irrespective of the configuration property setting.</p>
+</div>
+<div class="paragraph">
+<p>And, conversely, the framework also provides <code>ObjectLoadedEvent.Noop</code>; if <code>loadedLifecycleEvent</code> attribute is set to this class,
+then no event will be posted.</p>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_rg_annotations_manpage-DomainObject_nature">2.9.7. <code>nature()</code></h4>
 <div class="paragraph">
 <p>The <code>nature()</code> attribute is used to characterize the domain object as either an entity (part of the domain layer) or as a view model (part of the application layer).  If the domain object should be thought of as an entity, it also captures how the persistence of that entity is managed.</p>
 </div>
@@ -5465,49 +5756,310 @@ can be used instead, eg:</p>
 </div>
 </div>
 <div class="sect3">
-<h4 id="_rg_annotations_manpage-DomainObject_objectType">2.9.6. <code>objectType()</code></h4>
+<h4 id="_rg_annotations_manpage-DomainObject_persistedLifecycleEvent">2.9.8. persistedLifecycleEvent() (<code>1.11.0-SNAPSHOT</code>)</h4>
 <div class="paragraph">
-<p>The <code>objectType()</code> attribute is used to provide a unique alias for the object&#8217;s class name.</p>
+<p>Whenever a (just created, still transient) domain object has been saved (INSERTed in)to the database, a "persisted" lifecycle
+event is fired.</p>
 </div>
 <div class="paragraph">
-<p>This value is used internally to generate a string representation of an objects identity (the <code>Oid</code>).  This can appear in several contexts, including:</p>
+<p>Subscribers subscribe through the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> and can
+use the event to obtain a reference to the domain object.  The subscriber could then, for example, maintain an
+external datastore.</p>
 </div>
-<div class="ulist">
-<ul>
-<li>
-<p>as the value of <code>o.a.i.applib.services.bookmark.Bookmark#getObjectType()</code></p>
-</li>
-<li>
-<p>in the <code>toString()</code> value of <code>Bookmark</code></p>
-</li>
-<li>
-<p>in the URLs of the <a href="ug.html#_ug_restfulobjects-viewer">RestfulObjects viewer</a></p>
-</li>
-<li>
-<p>in the URLs of the <a href="ug.html#_ug_wicket-viewer">Wicket viewer</a> (in general and in particular if <a href="ug.html#_ug_wicket-viewer_features_hints-and-copy-url">copying URLs</a>)</p>
-</li>
-<li>
-<p>in XML snapshots generated by the <a href="#_rg_services-api_manpage-XmlSnapshotService"><code>XmlSnapshotService</code></a></p>
-</li>
-</ul>
+<div class="admonitionblock warning">
+<table>
+<tr>
+<td class="icon">
+<i class="fa icon-warning" title="Warning"></i>
+</td>
+<td class="content">
+<div class="paragraph">
+<p>The object should <em>not</em> be modified during the persisted callback.</p>
+</div>
+</td>
+</tr>
+</table>
 </div>
 <div class="paragraph">
-<p>For example:</p>
+<p>By default the event raised is <code>ObjectPersistedEvent.Default</code>. For example:</p>
 </div>
 <div class="listingblock">
 <div class="content">
-<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObject</span>(
-    objectType=<span class="string"><span class="delimiter">&quot;</span><span class="content">ORD</span><span class="delimiter">&quot;</span></span>
-)
-<span class="directive">public</span> <span class="type">class</span> <span class="class">Order</span> {
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObject</span>
+<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItemDto</span> {
     ...
 }</code></pre>
 </div>
 </div>
 <div class="paragraph">
-<p>If the object type has not been specified, then Apache Isis will use the fully qualified class name of the entity.</p>
+<p>The purpose of the <code>persistedLifecycleEvent()</code> attribute is to allows a custom subclass to be emitted instead.  A similar
+attribute is available for other lifecycle events.</p>
 </div>
-<div class="admonitionblock tip">
+<div class="paragraph">
+<p>For example:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObjectLayout</span>(
+    persistedLifecycleEvent=ToDoItem.PersistedEvent.class
+)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItem</span> {
+    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">PersistedEvent</span>
+        <span class="directive">extends</span> org.apache.isis.applib.services.eventbus.ObjectPersistedEvent&lt;ToDoItem&gt; { }
+    ...
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>The benefit is that subscribers can be more targeted as to the events that they subscribe to.</p>
+</div>
+<div class="sect4">
+<h5 id="_subscribers_5">Subscribers</h5>
+<div class="paragraph">
+<p>Subscribers (which must be domain services) subscribe using either the <a href="https://github.com/google/guava">Guava</a> API
+or (if the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> has been appropriately configured)
+using the <a href="http://www.axonframework.org/">Axon Framework</a> API.  The examples below use the Guava API.</p>
+</div>
+<div class="paragraph">
+<p>Subscribers can be either coarse-grained (if they subscribe to the top-level event type):</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
+    <span class="annotation">@com</span>.google.common.eventbus.Subscribe
+    <span class="directive">public</span> <span class="type">void</span> on(ObjectPersistedEvent ev) {
+        <span class="keyword">if</span>(ev.getSource() <span class="keyword">instanceof</span> ToDoItem) { ... }
+    }
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>or can be fine-grained (by subscribing to specific event subtypes):</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
+    <span class="annotation">@com</span>.google.common.eventbus.Subscribe
+    <span class="directive">public</span> <span class="type">void</span> on(ToDoItem.ObjectPersistedEvent ev) {
+        ...
+    }
+}</code></pre>
+</div>
+</div>
+<div class="admonitionblock tip">
+<table>
+<tr>
+<td class="icon">
+<i class="fa icon-tip" title="Tip"></i>
+</td>
+<td class="content">
+<div class="paragraph">
+<p>If the AxonFramework is being used, replace <code>@com.google.common.eventbus.Subscribe</code> with <code>@org.axonframework.eventhandling.annotation.EventHandler</code>.</p>
+</div>
+</td>
+</tr>
+</table>
+</div>
+</div>
+<div class="sect4">
+<h5 id="_default_doop_and_noop_events_3">Default, Doop and Noop events</h5>
+<div class="paragraph">
+<p>If the <code>persistedLifecycleEvent</code> attribute is not explicitly specified (is left as its default value, <code>ObjectPersistedEvent.Default</code>),
+then the framework will, by default, post an event.</p>
+</div>
+<div class="paragraph">
+<p>If this is not required, then the <code>isis.reflector.facet.domainObjectAnnotation.persistedLifecycleEvent.postForDefault</code>
+configuration property can be set to "false"; this will disable posting.</p>
+</div>
+<div class="paragraph">
+<p>On the other hand, if the <code>persistedLifecycleEvent</code> has been explicitly specified to some subclass, then an event will be posted.
+The framework provides <code>ObjectPersistedEvent.Doop</code> as such a subclass, so setting the <code>persistedLifecycleEvent</code> attribute to this class
+will ensure that the event to be posted, irrespective of the configuration property setting.</p>
+</div>
+<div class="paragraph">
+<p>And, conversely, the framework also provides <code>ObjectPersistedEvent.Noop</code>; if <code>persistedLifecycleEvent</code> attribute is set to this class,
+then no event will be posted.</p>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_rg_annotations_manpage-DomainObject_persistingLifecycleEvent">2.9.9. persistingLifecycleEvent() (<code>1.11.0-SNAPSHOT</code>)</h4>
+<div class="paragraph">
+<p>Whenever a (just created, still transient) domain object is about to be saved (INSERTed in)to the database, a "persisting" lifecycle
+event is fired.</p>
+</div>
+<div class="paragraph">
+<p>Subscribers subscribe through the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> and can
+use the event to obtain a reference to the domain object.  The subscriber could then, for example, update the object,
+or it could use it maintain an external datastore.  One possible application is to maintain a full-text search database using
+<a href="https://lucene.apache.org/">Apache Lucene</a> or similar.</p>
+</div>
+<div class="admonitionblock note">
+<table>
+<tr>
+<td class="icon">
+<i class="fa icon-note" title="Note"></i>
+</td>
+<td class="content">
+<div class="paragraph">
+<p>Another use case is to maintain "last updated by"/"last updated at" properties.  While you can roll your own, note that
+the framework provides built-in support for this use case through the
+<a href="#_rg_classes_roles_manpage-Timestampable"><code>Timestampable</code></a> role interface.</p>
+</div>
+</td>
+</tr>
+</table>
+</div>
+<div class="paragraph">
+<p>By default the event raised is <code>ObjectPersistingEvent.Default</code>. For example:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObject</span>
+<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItemDto</span> {
+    ...
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>The purpose of the <code>persistingLifecycleEvent()</code> attribute is to allows a custom subclass to be emitted instead.  A similar
+attribute is available for other lifecycle events.</p>
+</div>
+<div class="paragraph">
+<p>For example:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObjectLayout</span>(
+    persistingLifecycleEvent=ToDoItem.PersistingEvent.class
+)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItem</span> {
+    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">PersistingEvent</span>
+        <span class="directive">extends</span> org.apache.isis.applib.services.eventbus.ObjectPersistingEvent&lt;ToDoItem&gt; { }
+    ...
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>The benefit is that subscribers can be more targeted as to the events that they subscribe to.</p>
+</div>
+<div class="sect4">
+<h5 id="_subscribers_6">Subscribers</h5>
+<div class="paragraph">
+<p>Subscribers (which must be domain services) subscribe using either the <a href="https://github.com/google/guava">Guava</a> API
+or (if the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> has been appropriately configured)
+using the <a href="http://www.axonframework.org/">Axon Framework</a> API.  The examples below use the Guava API.</p>
+</div>
+<div class="paragraph">
+<p>Subscribers can be either coarse-grained (if they subscribe to the top-level event type):</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
+    <span class="annotation">@com</span>.google.common.eventbus.Subscribe
+    <span class="directive">public</span> <span class="type">void</span> on(ObjectPersistingEvent ev) {
+        <span class="keyword">if</span>(ev.getSource() <span class="keyword">instanceof</span> ToDoItem) { ... }
+    }
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>or can be fine-grained (by subscribing to specific event subtypes):</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
+    <span class="annotation">@com</span>.google.common.eventbus.Subscribe
+    <span class="directive">public</span> <span class="type">void</span> on(ToDoItem.ObjectPersistingEvent ev) {
+        ...
+    }
+}</code></pre>
+</div>
+</div>
+<div class="admonitionblock tip">
+<table>
+<tr>
+<td class="icon">
+<i class="fa icon-tip" title="Tip"></i>
+</td>
+<td class="content">
+<div class="paragraph">
+<p>If the AxonFramework is being used, replace <code>@com.google.common.eventbus.Subscribe</code> with <code>@org.axonframework.eventhandling.annotation.EventHandler</code>.</p>
+</div>
+</td>
+</tr>
+</table>
+</div>
+</div>
+<div class="sect4">
+<h5 id="_default_doop_and_noop_events_4">Default, Doop and Noop events</h5>
+<div class="paragraph">
+<p>If the <code>persistingLifecycleEvent</code> attribute is not explicitly specified (is left as its default value, <code>ObjectPersistingEvent.Default</code>),
+then the framework will, by default, post an event.</p>
+</div>
+<div class="paragraph">
+<p>If this is not required, then the <code>isis.reflector.facet.domainObjectAnnotation.persistingLifecycleEvent.postForDefault</code>
+configuration property can be set to "false"; this will disable posting.</p>
+</div>
+<div class="paragraph">
+<p>On the other hand, if the <code>persistingLifecycleEvent</code> has been explicitly specified to some subclass, then an event will be posted.
+The framework provides <code>ObjectPersistingEvent.Doop</code> as such a subclass, so setting the <code>persistingLifecycleEvent</code> attribute to this class
+will ensure that the event to be posted, irrespective of the configuration property setting.</p>
+</div>
+<div class="paragraph">
+<p>And, conversely, the framework also provides <code>ObjectPersistingEvent.Noop</code>; if <code>persistingLifecycleEvent</code> attribute is set to this class,
+then no event will be posted.</p>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_rg_annotations_manpage-DomainObject_objectType">2.9.10. <code>objectType()</code></h4>
+<div class="paragraph">
+<p>The <code>objectType()</code> attribute is used to provide a unique alias for the object&#8217;s class name.</p>
+</div>
+<div class="paragraph">
+<p>This value is used internally to generate a string representation of an objects identity (the <code>Oid</code>).  This can appear in several contexts, including:</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>as the value of <code>o.a.i.applib.services.bookmark.Bookmark#getObjectType()</code></p>
+</li>
+<li>
+<p>in the <code>toString()</code> value of <code>Bookmark</code></p>
+</li>
+<li>
+<p>in the URLs of the <a href="ug.html#_ug_restfulobjects-viewer">RestfulObjects viewer</a></p>
+</li>
+<li>
+<p>in the URLs of the <a href="ug.html#_ug_wicket-viewer">Wicket viewer</a> (in general and in particular if <a href="ug.html#_ug_wicket-viewer_features_hints-and-copy-url">copying URLs</a>)</p>
+</li>
+<li>
+<p>in XML snapshots generated by the <a href="#_rg_services-api_manpage-XmlSnapshotService"><code>XmlSnapshotService</code></a></p>
+</li>
+</ul>
+</div>
+<div class="paragraph">
+<p>For example:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObject</span>(
+    objectType=<span class="string"><span class="delimiter">&quot;</span><span class="content">ORD</span><span class="delimiter">&quot;</span></span>
+)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">Order</span> {
+    ...
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>If the object type has not been specified, then Apache Isis will use the fully qualified class name of the entity.</p>
+</div>
+<div class="admonitionblock tip">
 <table>
 <tr>
 <td class="icon">
@@ -5521,88 +6073,480 @@ can be used instead, eg:</p>
 <p>As noted above, if the object type has not been specified, then Apache Isis will use the fully qualified class name of the entity.  However, this is liable to change over time, for example if the code is refactored or (more fundamentally) if your company/organization reorganizes/renames itself/is acquired.</p>
 </div>
 <div class="paragraph">
-<p>We therefore strongly recommend that you specify an object type for all entities, either using <code>objectType()</code> or using the JDO <a href="#_rg_annotations_manpage-PersistenceCapable"><code>@PersistenceCapable</code></a> (with a <code>schema()</code> attribute) or <a href="#_rg_annotations_manpage-Discriminator"><code>@Discriminator</code></a> annotations.  Specifying <code>@Discriminator</code> will override <code>@PersistenceCapable</code>, which in turn overrides <code>objectType()</code>.  Using <code>@PersistenceCapable#schema()</code> is probably the best choice in most cases.</p>
+<p>We therefore strongly recommend that you specify an object type for all entities, either using <code>objectType()</code> or using the JDO <a href="#_rg_annotations_manpage-PersistenceCapable"><code>@PersistenceCapable</code></a> (with a <code>schema()</code> attribute) or <a href="#_rg_annotations_manpage-Discriminator"><code>@Discriminator</code></a> annotations.  Specifying <code>@Discriminator</code> will override <code>@PersistenceCapable</code>, which in turn overrides <code>objectType()</code>.  Using <code>@PersistenceCapable#schema()</code> is probably the best choice in most cases.</p>
+</div>
+</td>
+</tr>
+</table>
+</div>
+<div class="admonitionblock note">
+<table>
+<tr>
+<td class="icon">
+<i class="fa icon-note" title="Note"></i>
+</td>
+<td class="content">
+<div class="paragraph">
+<p>If the object type is not unique across all domain classes then the framework will fail-fast and fail to boot.  An error message will be printed in the log to help you determine which classes have duplicate object tyoes.</p>
+</div>
+</td>
+</tr>
+</table>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_rg_annotations_manpage-DomainObject_publishing">2.9.11. <code>publishing()</code></h4>
+<div class="paragraph">
+<p>The <code>publishing()</code> attribute determines whether and how a modified object instance is published via the registered implementation of a <a href="#_rg_services-spi_manpage-PublishingService"><code>PublishingService</code></a>).  This attribute is also supported for <a href="#_rg_annotations_manpage-Action_publishing">actions</a>, where it controls whether action invocations are published as events.</p>
+</div>
+<div class="paragraph">
+<p>A common use case is to notify external "downstream" systems of changes in the state of the Isis application.</p>
+</div>
+<div class="paragraph">
+<p>The default value for the attribute is <code>AS_CONFIGURED</code>, meaning that the <a href="#_rg_runtime_configuring-core">configuration property</a> <code>isis.services.publish.objects</code> is used to determine the whether the action is published:</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p><code>all</code><br></p>
+<div class="paragraph">
+<p>all changed objects are published</p>
+</div>
+</li>
+<li>
+<p><code>none</code><br></p>
+<div class="paragraph">
+<p>no changed objects are published</p>
+</div>
+</li>
+</ul>
+</div>
+<div class="paragraph">
+<p>If there is no configuration property in <code>isis.properties</code> then publishing is automatically enabled for domain objects.</p>
+</div>
+<div class="paragraph">
+<p>This default can be overridden on an object-by-object basis; if <code>publishing()</code> is set to <code>ENABLED</code> then changed instances of the domain class are published irrespective of the configured value; if set to <code>DISABLED</code> then the changed instances are <em>not</em> published, again irrespective of the configured value.</p>
+</div>
+<div class="paragraph">
+<p>For example:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObject</span>(
+    publishing=Publishing.ENABLED  <i class="conum" data-value="1"></i><b>(1)</b>
+)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">InterestRate</span> {
+    ...
+}</code></pre>
+</div>
+</div>
+<div class="colist arabic">
+<table>
+<tr>
+<td><i class="conum" data-value="1"></i><b>1</b></td>
+<td>because set to enabled, will be published irrespective of the configured value.</td>
+</tr>
+</table>
+</div>
+<div class="sect4">
+<h5 id="__code_publishingpayloadfactory_code_2"><code>publishingPayloadFactory()</code></h5>
+<div class="paragraph">
+<p>The (optional) related <code>publishingPayloadFactory()</code> specifies the class to use to create the (payload of the) event to be published by the publishing factory.</p>
+</div>
+<div class="paragraph">
+<p>Rather than simply broadcast that the object was changed, the payload factory allows a "fatter" payload to be instantiated that can eagerly push commonly-required information to all subscribers. For at least some subscribers this should avoid the necessity to query back for additional information.</p>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_rg_annotations_manpage-DomainObject_removingLifecycleEvent">2.9.12. removingLifecycleEvent() (<code>1.11.0-SNAPSHOT</code>)</h4>
+<div class="paragraph">
+<p>Whenever a (persistent) domain object is about to be removed (DELETEd) from the database, a "removing"
+lifecycle event is fired.</p>
+</div>
+<div class="paragraph">
+<p>Subscribers subscribe through the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> and can
+use the event to obtain a reference to the domain object.  The subscriber could then, for example, could use it
+maintain an external datastore.  One possible application is to maintain a full-text search database
+using <a href="https://lucene.apache.org/">Apache Lucene</a> or similar.</p>
+</div>
+<div class="admonitionblock note">
+<table>
+<tr>
+<td class="icon">
+<i class="fa icon-note" title="Note"></i>
+</td>
+<td class="content">
+<div class="paragraph">
+<p>Another use case is to maintain "last updated by"/"last updated at" properties.  While you can roll your own, note that
+the framework provides built-in support for this use case through the
+<a href="#_rg_classes_roles_manpage-Timestampable"><code>Timestampable</code></a> role interface.</p>
+</div>
+</td>
+</tr>
+</table>
+</div>
+<div class="paragraph">
+<p>By default the event raised is <code>ObjectRemovingEvent.Default</code>. For example:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObject</span>
+<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItemDto</span> {
+    ...
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>The purpose of the <code>removingLifecycleEvent()</code> attribute is to allows a custom subclass to be emitted instead.  A similar
+attribute is available for other lifecycle events.</p>
+</div>
+<div class="paragraph">
+<p>For example:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObjectLayout</span>(
+    removingLifecycleEvent=ToDoItem.RemovingEvent.class
+)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItem</span> {
+    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">RemovingEvent</span>
+        <span class="directive">extends</span> org.apache.isis.applib.services.eventbus.ObjectRemovingEvent&lt;ToDoItem&gt; { }
+    ...
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>The benefit is that subscribers can be more targeted as to the events that they subscribe to.</p>
+</div>
+<div class="sect4">
+<h5 id="_subscribers_7">Subscribers</h5>
+<div class="paragraph">
+<p>Subscribers (which must be domain services) subscribe using either the <a href="https://github.com/google/guava">Guava</a> API
+or (if the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> has been appropriately configured)
+using the <a href="http://www.axonframework.org/">Axon Framework</a> API.  The examples below use the Guava API.</p>
+</div>
+<div class="paragraph">
+<p>Subscribers can be either coarse-grained (if they subscribe to the top-level event type):</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
+    <span class="annotation">@com</span>.google.common.eventbus.Subscribe
+    <span class="directive">public</span> <span class="type">void</span> on(ObjectRemovingEvent ev) {
+        <span class="keyword">if</span>(ev.getSource() <span class="keyword">instanceof</span> ToDoItem) { ... }
+    }
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>or can be fine-grained (by subscribing to specific event subtypes):</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
+    <span class="annotation">@com</span>.google.common.eventbus.Subscribe
+    <span class="directive">public</span> <span class="type">void</span> on(ToDoItem.ObjectRemovingEvent ev) {
+        ...
+    }
+}</code></pre>
+</div>
+</div>
+<div class="admonitionblock tip">
+<table>
+<tr>
+<td class="icon">
+<i class="fa icon-tip" title="Tip"></i>
+</td>
+<td class="content">
+<div class="paragraph">
+<p>If the AxonFramework is being used, replace <code>@com.google.common.eventbus.Subscribe</code> with <code>@org.axonframework.eventhandling.annotation.EventHandler</code>.</p>
+</div>
+</td>
+</tr>
+</table>
+</div>
+</div>
+<div class="sect4">
+<h5 id="_default_doop_and_noop_events_5">Default, Doop and Noop events</h5>
+<div class="paragraph">
+<p>If the <code>removingLifecycleEvent</code> attribute is not explicitly specified (is left as its default value, <code>ObjectRemovingEvent.Default</code>),
+then the framework will, by default, post an event.</p>
+</div>
+<div class="paragraph">
+<p>If this is not required, then the <code>isis.reflector.facet.domainObjectAnnotation.removingLifecycleEvent.postForDefault</code>
+configuration property can be set to "false"; this will disable posting.</p>
+</div>
+<div class="paragraph">
+<p>On the other hand, if the <code>removingLifecycleEvent</code> has been explicitly specified to some subclass, then an event will be posted.
+The framework provides <code>ObjectRemovingEvent.Doop</code> as such a subclass, so setting the <code>removingLifecycleEvent</code> attribute to this class
+will ensure that the event to be posted, irrespective of the configuration property setting.</p>
+</div>
+<div class="paragraph">
+<p>And, conversely, the framework also provides <code>ObjectRemovingEvent.Noop</code>; if <code>removingLifecycleEvent</code> attribute is set to this class,
+then no event will be posted.</p>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_rg_annotations_manpage-DomainObject_updatingLifecycleEvent">2.9.13. updatingLifecycleEvent() (<code>1.11.0-SNAPSHOT</code>)</h4>
+<div class="paragraph">
+<p>Whenever a (persistent) domain object has been modified and is about to be updated to the database, an "updating"
+lifecycle event is fired.</p>
+</div>
+<div class="paragraph">
+<p>Subscribers subscribe through the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> and can
+use the event to obtain a reference to the domain object.  The subscriber could then, for example, update the object,
+or it could use it maintain an external datastore.  One possible application is to maintain a full-text search database
+using <a href="https://lucene.apache.org/">Apache Lucene</a> or similar.</p>
+</div>
+<div class="admonitionblock note">
+<table>
+<tr>
+<td class="icon">
+<i class="fa icon-note" title="Note"></i>
+</td>
+<td class="content">
+<div class="paragraph">
+<p>Another use case is to maintain "last updated by"/"last updated at" properties.  While you can roll your own, note that
+the framework provides built-in support for this use case through the
+<a href="#_rg_classes_roles_manpage-Timestampable"><code>Timestampable</code></a> role interface.</p>
+</div>
+</td>
+</tr>
+</table>
+</div>
+<div class="paragraph">
+<p>By default the event raised is <code>ObjectUpdatingEvent.Default</code>. For example:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObject</span>
+<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItemDto</span> {
+    ...
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>The purpose of the <code>updatingLifecycleEvent()</code> attribute is to allows a custom subclass to be emitted instead.  A similar
+attribute is available for other lifecycle events.</p>
+</div>
+<div class="paragraph">
+<p>For example:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObjectLayout</span>(
+    updatingLifecycleEvent=ToDoItem.UpdatingEvent.class
+)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItem</span> {
+    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">UpdatingEvent</span>
+        <span class="directive">extends</span> org.apache.isis.applib.services.eventbus.ObjectUpdatingEvent&lt;ToDoItem&gt; { }
+    ...
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>The benefit is that subscribers can be more targeted as to the events that they subscribe to.</p>
+</div>
+<div class="sect4">
+<h5 id="_subscribers_8">Subscribers</h5>
+<div class="paragraph">
+<p>Subscribers (which must be domain services) subscribe using either the <a href="https://github.com/google/guava">Guava</a> API
+or (if the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> has been appropriately configured)
+using the <a href="http://www.axonframework.org/">Axon Framework</a> API.  The examples below use the Guava API.</p>
+</div>
+<div class="paragraph">
+<p>Subscribers can be either coarse-grained (if they subscribe to the top-level event type):</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
+    <span class="annotation">@com</span>.google.common.eventbus.Subscribe
+    <span class="directive">public</span> <span class="type">void</span> on(ObjectUpdatingEvent ev) {
+        <span class="keyword">if</span>(ev.getSource() <span class="keyword">instanceof</span> ToDoItem) { ... }
+    }
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>or can be fine-grained (by subscribing to specific event subtypes):</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
+    <span class="annotation">@com</span>.google.common.eventbus.Subscribe
+    <span class="directive">public</span> <span class="type">void</span> on(ToDoItem.ObjectUpdatingEvent ev) {
+        ...
+    }
+}</code></pre>
+</div>
+</div>
+<div class="admonitionblock tip">
+<table>
+<tr>
+<td class="icon">
+<i class="fa icon-tip" title="Tip"></i>
+</td>
+<td class="content">
+<div class="paragraph">
+<p>If the AxonFramework is being used, replace <code>@com.google.common.eventbus.Subscribe</code> with <code>@org.axonframework.eventhandling.annotation.EventHandler</code>.</p>
+</div>
+</td>
+</tr>
+</table>
+</div>
+</div>
+<div class="sect4">
+<h5 id="_default_doop_and_noop_events_6">Default, Doop and Noop events</h5>
+<div class="paragraph">
+<p>If the <code>updatingLifecycleEvent</code> attribute is not explicitly specified (is left as its default value, <code>ObjectUpdatingEvent.Default</code>),
+then the framework will, by default, post an event.</p>
+</div>
+<div class="paragraph">
+<p>If this is not required, then the <code>isis.reflector.facet.domainObjectAnnotation.updatingLifecycleEvent.postForDefault</code>
+configuration property can be set to "false"; this will disable posting.</p>
+</div>
+<div class="paragraph">
+<p>On the other hand, if the <code>updatingLifecycleEvent</code> has been explicitly specified to some subclass, then an event will be posted.
+The framework provides <code>ObjectUpdatingEvent.Doop</code> as such a subclass, so setting the <code>updatingLifecycleEvent</code> attribute to this class
+will ensure that the event to be posted, irrespective of the configuration property setting.</p>
+</div>
+<div class="paragraph">
+<p>And, conversely, the framework also provides <code>ObjectUpdatingEvent.Noop</code>; if <code>updatingLifecycleEvent</code> attribute is set to this class,
+then no event will be posted.</p>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_rg_annotations_manpage-DomainObject_updatedLifecycleEvent">2.9.14. updatedLifecycleEvent() (<code>1.11.0-SNAPSHOT</code>)</h4>
+<div class="paragraph">
+<p>Whenever a (persistent) domain object has been modified and has been updated in the database, an "updated" lifecycle
+event is fired.</p>
 </div>
-</td>
-</tr>
-</table>
+<div class="paragraph">
+<p>Subscribers subscribe through the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> and can
+use the event to obtain a reference to the domain object.</p>
 </div>
-<div class="admonitionblock note">
+<div class="admonitionblock warning">
 <table>
 <tr>
 <td class="icon">
-<i class="fa icon-note" title="Note"></i>
+<i class="fa icon-warning" title="Warning"></i>
 </td>
 <td class="content">
 <div class="paragraph">
-<p>If the object type is not unique across all domain classes then the framework will fail-fast and fail to boot.  An error message will be printed in the log to help you determine which classes have duplicate object tyoes.</p>
+<p>The object should <em>not</em> be modified during the updated callback.</p>
 </div>
 </td>
 </tr>
 </table>
 </div>
-</div>
-<div class="sect3">
-<h4 id="_rg_annotations_manpage-DomainObject_publishing">2.9.7. <code>publishing()</code></h4>
 <div class="paragraph">
-<p>The <code>publishing()</code> attribute determines whether and how a modified object instance is published via the registered implementation of a <a href="#_rg_services-spi_manpage-PublishingService"><code>PublishingService</code></a>).  This attribute is also supported for <a href="#_rg_annotations_manpage-Action_publishing">actions</a>, where it controls whether action invocations are published as events.</p>
+<p>By default the event raised is <code>ObjectUpdatedEvent.Default</code>. For example:</p>
 </div>
-<div class="paragraph">
-<p>A common use case is to notify external "downstream" systems of changes in the state of the Isis application.</p>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObject</span>
+<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItemDto</span> {
+    ...
+}</code></pre>
 </div>
-<div class="paragraph">
-<p>The default value for the attribute is <code>AS_CONFIGURED</code>, meaning that the <a href="#_rg_runtime_configuring-core">configuration property</a> <code>isis.services.publish.objects</code> is used to determine the whether the action is published:</p>
 </div>
-<div class="ulist">
-<ul>
-<li>
-<p><code>all</code><br></p>
 <div class="paragraph">
-<p>all changed objects are published</p>
+<p>The purpose of the <code>updatedLifecycleEvent()</code> attribute is to allows a custom subclass to be emitted instead.  A similar
+attribute is available for other lifecycle events.</p>
 </div>
-</li>
-<li>
-<p><code>none</code><br></p>
 <div class="paragraph">
-<p>no changed objects are published</p>
+<p>For example:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObjectLayout</span>(
+    updatedLifecycleEvent=ToDoItem.UpdatedEvent.class
+)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItem</span> {
+    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">UpdatedEvent</span>
+        <span class="directive">extends</span> org.apache.isis.applib.services.eventbus.ObjectUpdatedEvent&lt;ToDoItem&gt; { }
+    ...
+}</code></pre>
 </div>
-</li>
-</ul>
 </div>
 <div class="paragraph">
-<p>If there is no configuration property in <code>isis.properties</code> then publishing is automatically enabled for domain objects.</p>
+<p>The benefit is that subscribers can be more targeted as to the events that they subscribe to.</p>
 </div>
+<div class="sect4">
+<h5 id="_subscribers_9">Subscribers</h5>
 <div class="paragraph">
-<p>This default can be overridden on an object-by-object basis; if <code>publishing()</code> is set to <code>ENABLED</code> then changed instances of the domain class are published irrespective of the configured value; if set to <code>DISABLED</code> then the changed instances are <em>not</em> published, again irrespective of the configured value.</p>
+<p>Subscribers (which must be domain services) subscribe using either the <a href="https://github.com/google/guava">Guava</a> API
+or (if the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> has been appropriately configured)
+using the <a href="http://www.axonframework.org/">Axon Framework</a> API.  The examples below use the Guava API.</p>
 </div>
 <div class="paragraph">
-<p>For example:</p>
+<p>Subscribers can be either coarse-grained (if they subscribe to the top-level event type):</p>
 </div>
 <div class="listingblock">
 <div class="content">
-<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObject</span>(
-    publishing=Publishing.ENABLED  <i class="conum" data-value="1"></i><b>(1)</b>
-)
-<span class="directive">public</span> <span class="type">class</span> <span class="class">InterestRate</span> {
-    ...
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
+    <span class="annotation">@com</span>.google.common.eventbus.Subscribe
+    <span class="directive">public</span> <span class="type">void</span> on(ObjectUpdatedEvent ev) {
+        <span class="keyword">if</span>(ev.getSource() <span class="keyword">instanceof</span> ToDoItem) { ... }
+    }
 }</code></pre>
 </div>
 </div>
-<div class="colist arabic">
+<div class="paragraph">
+<p>or can be fine-grained (by subscribing to specific event subtypes):</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
+    <span class="annotation">@com</span>.google.common.eventbus.Subscribe
+    <span class="directive">public</span> <span class="type">void</span> on(ToDoItem.ObjectUpdatedEvent ev) {
+        ...
+    }
+}</code></pre>
+</div>
+</div>
+<div class="admonitionblock tip">
 <table>
 <tr>
-<td><i class="conum" data-value="1"></i><b>1</b></td>
-<td>because set to enabled, will be published irrespective of the configured value.</td>
+<td class="icon">
+<i class="fa icon-tip" title="Tip"></i>
+</td>
+<td class="content">
+<div class="paragraph">
+<p>If the AxonFramework is being used, replace <code>@com.google.common.eventbus.Subscribe</code> with <code>@org.axonframework.eventhandling.annotation.EventHandler</code>.</p>
+</div>
+</td>
 </tr>
 </table>
 </div>
+</div>
 <div class="sect4">
-<h5 id="__code_publishingpayloadfactory_code_2"><code>publishingPayloadFactory()</code></h5>
+<h5 id="_default_doop_and_noop_events_7">Default, Doop and Noop events</h5>
 <div class="paragraph">
-<p>The (optional) related <code>publishingPayloadFactory()</code> specifies the class to use to create the (payload of the) event to be published by the publishing factory.</p>
+<p>If the <code>updatedLifecycleEvent</code> attribute is not explicitly specified (is left as its default value, <code>ObjectUpdatedEvent.Default</code>),
+then the framework will, by default, post an event.</p>
 </div>
 <div class="paragraph">
-<p>Rather than simply broadcast that the object was changed, the payload factory allows a "fatter" payload to be instantiated that can eagerly push commonly-required information to all subscribers. For at least some subscribers this should avoid the necessity to query back for additional information.</p>
+<p>If this is not required, then the <code>isis.reflector.facet.domainObjectAnnotation.updatedLifecycleEvent.postForDefault</code>
+configuration property can be set to "false"; this will disable posting.</p>
+</div>
+<div class="paragraph">
+<p>On the other hand, if the <code>updatedLifecycleEvent</code> has been explicitly specified to some subclass, then an event will be posted.
+The framework provides <code>ObjectUpdatedEvent.Doop</code> as such a subclass, so setting the <code>updatedLifecycleEvent</code> attribute to this class
+will ensure that the event to be posted, irrespective of the configuration property setting.</p>
+</div>
+<div class="paragraph">
+<p>And, conversely, the framework also provides <code>ObjectUpdatedEvent.Noop</code>; if <code>updatedLifecycleEvent</code> attribute is set to this class,
+then no event will be posted.</p>
 </div>
 </div>
 </div>
@@ -5940,8 +6884,9 @@ in any wrapping <code>&lt;div&gt;</code>s and <code>&lt;span&gt;</code>s that re
 it will take precedence).</p>
 </div>
 <div class="paragraph">
-<p>Subscribers subscribe through the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> using either <a href="https://github.com/google/guava">Guava</a> or <a href="http://www.axonframework.org/">Axon Framework</a> annotations and can
-optionally specify a title.</p>
+<p>Subscribers subscribe through the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> and can
+use obtain a reference to the domain object from the event.  From this they can, if they wish, specify a CSS class for
+the domain object using the event&#8217;s API.</p>
 </div>
 <div class="admonitionblock note">
 <table>
@@ -5993,7 +6938,7 @@ attribute is available for titles and icons.</p>
 <p>The benefit is that subscribers can be more targeted as to the events that they subscribe to.</p>
 </div>
 <div class="sect4">
-<h5 id="_subscribers_3">Subscribers</h5>
+<h5 id="_subscribers_10">Subscribers</h5>
 <div class="paragraph">
 <p>Subscribers (which must be domain services) subscribe using either the <a href="https://github.com/google/guava">Guava</a> API
 or (if the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> has been appropriately configured)
@@ -6046,7 +6991,7 @@ using the <a href="http://www.axonframework.org/">Axon Framework</a> API.  The e
 </div>
 </div>
 <div class="sect4">
-<h5 id="_default_doop_and_noop_events">Default, Doop and Noop events</h5>
+<h5 id="_default_doop_and_noop_events_8">Default, Doop and Noop events</h5>
 <div class="paragraph">
 <p>If the <code>cssClassUiEvent</code> attribute is not explicitly specified (is left as its default value, <code>CssClassUiEvent.Default</code>),
 then the framework will, by default, post an event.</p>
@@ -6062,7 +7007,7 @@ will ensure that the event to be posted, irrespective of the configuration prope
 </div>
 <div class="paragraph">
 <p>And, conversely, the framework also provides <code>CssClassUiEvent.Noop</code>; if <code>cssClassUiEvent</code> attribute is set to this class,
-thn no event will be posted.</p>
+then no event will be posted.</p>
 </div>
 </div>
 <div class="sect4">
@@ -6102,8 +7047,9 @@ object (if possible). This is as an alternative to implementing
 it will take precedence).</p>
 </div>
 <div class="paragraph">
-<p>Subscribers subscribe through the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> using either <a href="https://github.com/google/guava">Guava</a> or <a href="http://www.axonframework.org/">Axon Framework</a> annotations and can
-optionally specify a title.</p>
+<p>Subscribers subscribe through the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> and can
+use obtain a reference to the domain object from the event.  From this they can, if they wish, specify an icon name for
+the domain object using the event&#8217;s API.</p>
 </div>
 <div class="admonitionblock note">
 <table>
@@ -6155,7 +7101,7 @@ attribute is available for titles and CSS classes.</p>
 <p>The benefit is that subscribers can be more targeted as to the events that they subscribe to.</p>
 </div>
 <div class="sect4">
-<h5 id="_subscribers_4">Subscribers</h5>
+<h5 id="_subscribers_11">Subscribers</h5>
 <div class="paragraph">
 <p>Subscribers (which must be domain services) subscribe using either the <a href="https://github.com/google/guava">Guava</a> API
 or (if the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> has been appropriately configured)
@@ -6208,7 +7154,7 @@ using the <a href="http://www.axonframework.org/">Axon Framework</a> API.  The e
 </div>
 </div>
 <div class="sect4">
-<h5 id="_default_doop_and_noop_events_2">Default, Doop and Noop events</h5>
+<h5 id="_default_doop_and_noop_events_9">Default, Doop and Noop events</h5>
 <div class="paragraph">
 <p>If the <code>iconUiEvent</code> attribute is not explicitly specified (is left as its default value, <code>IconUiEvent.Default</code>),
 then the framework will, by default, post an event.</p>
@@ -6356,8 +7302,9 @@ using the <a href="#_rg_annotations_manpage-Title"><code>@Title</code></a> annot
 <code>title()</code> or <code>@Title</code> are present, then they will take precedence).</p>
 </div>
 <div class="paragraph">
-<p>Subscribers subscribe through the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> using either <a href="https://github.com/google/guava">Guava</a> or <a href="http://www.axonframework.org/">Axon Framework</a> annotations and can
-optionally specify a title.</p>
+<p>Subscribers subscribe through the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> and can
+use obtain a reference to the domain object from the event.  From this they can, if they wish, specify a title for
+the domain object using the event&#8217;s API.</p>
 </div>
 <div class="admonitionblock note">
 <table>
@@ -6409,7 +7356,7 @@ attribute is available for icon names and CSS classes.</p>
 <p>The benefit is that subscribers can be more targeted as to the events that they subscribe to.</p>
 </div>
 <div class="sect4">
-<h5 id="_subscribers_5">Subscribers</h5>
+<h5 id="_subscribers_12">Subscribers</h5>
 <div class="paragraph">
 <p>Subscribers (which must be domain services) subscribe using either the <a href="https://github.com/google/guava">Guava</a> API
 or (if the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> has been appropriately configured)
@@ -6463,7 +7410,7 @@ actually specify the title to be used.</p>
 </div>
 </div>
 <div class="sect4">
-<h5 id="_default_doop_and_noop_events_3">Default, Doop and Noop events</h5>
+<h5 id="_default_doop_and_noop_events_10">Default, Doop and Noop events</h5>
 <div class="paragraph">
 <p>If the <code>titleUiEvent</code> attribute is not explicitly specified (is left as its default value, <code>TitleUiEvent.Default</code>),
 then the framework will, by default, post an event.</p>
@@ -8729,7 +9676,7 @@ rather than through the constructor.  This substantially reduces the boilerplate
 </table>
 </div>
 <div class="sect4">
-<h5 id="_subscribers_6">Subscribers</h5>
+<h5 id="_subscribers_13">Subscribers</h5>
 <div class="paragraph">
 <p>Subscribers (which must be domain services) subscribe using either the <a href="https://github.com/google/guava">Guava</a> API or (if the <a href="#_rg_services-api_manpage-EventBusService"><code>EventBusService</code></a> has been appropriately configured) using the <a href="http://www.axonframework.org/">Axon Framework</a> API.  The examples below use the Guava API.</p>
 </div>
@@ -10011,17 +10958,25 @@ can be used instead, eg:</p>
 <div class="content">
 <pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">void</span> Customer {
     <span class="annotation">@Title</span>(sequence=<span class="string"><span class="delimiter">&quot;</span><span class="content">1.0</span><span class="delimiter">&quot;</span></span>)
-    <span class="directive">public</span> <span class="predefined-type">String</span> lastName() { ... }
+    <span class="directive">public</span> <span class="predefined-type">String</span> getLastName() { ... }     <i class="conum" data-value="1"></i><b>(1)</b>
     ...
     <span class="annotation">@Title</span>(sequence=<span class="string"><span class="delimiter">&quot;</span><span class="content">1.5</span><span class="delimiter">&quot;</span></span>, prepend=<span class="string"><span class="delimiter">&quot;</span><span class="content">, </span><span class="delimiter">&quot;</span></span>)
-    <span class="directive">public</span> <span class="predefined-type">String</span> firstName() { ... }
+    <span class="directive">public</span> <span class="predefined-type">String</span> getFirstName() { ... }
     ...
     <span class="annotation">@Title</span>(sequence=<span class="string"><span class="delimiter">&quot;</span><span class="content">1.7</span><span class="delimiter">&quot;</span></span>, append=<span class="string"><span class="delimiter">&quot;</span><span class="content">.</span><span class="delimiter">&quot;</span></span>)
-    <span class="directive">public</span> <span class="predefined-type">String</span> midInitial() { ... }
+    <span class="directive">public</span> <span class="predefined-type">String</span> getMidInitial() { ... }
     ...
 }</code></pre>
 </div>
 </div>
+<div class="colist arabic">
+<table>
+<tr>
+<td><i class="conum" data-value="1"></i><b>1</b></td>
+<td>backing field and setters omitted</td>
+</tr>
+</table>
+</div>
 <div class="paragraph">
 <p>could be used to create names of the style "Bloggs, Joe K."</p>
 </div>
@@ -10038,6 +10993,32 @@ viewer), this convention excludes any properties whose value is already
 present in the title column. This convention can be overridden using
 <code>@Hidden(where=Where.NOWHERE)</code>.</p>
 </div>
+<div class="sect3">
+<h4 id="_lombok_support">2.30.1. Lombok support</h4>
+<div class="paragraph">
+<p>If <a href="cg.html#_cg_ide_project-lombok">Project Lombok</a> is being used, then <code>@Title</code> can be specified on the backing field.</p>
+</div>
+<div class="paragraph">
+<p>For example:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">void</span> Customer {
+    <span class="annotation">@Title</span>(sequence=<span class="string"><span class="delimiter">&quot;</span><span class="content">1.0</span><span class="delimiter">&quot;</span></span>)
+    <span class="annotation">@Getter</span> <span class="annotation">@Setter</span>
+    <span class="directive">private</span> <span class="predefined-type">String</span> name;
+
+    <span class="annotation">@Title</span>(sequence=<span class="string"><span class="delimiter">&quot;</span><span class="content">1.5</span><span class="delimiter">&quot;</span></span>, prepend=<span class="string"><span class="delimiter">&quot;</span><span class="content">, </span><span class="delimiter">&quot;</span></span>)
+    <span class="annotation">@Getter</span> <span class="annotation">@Setter</span>
+    <span class="directive">private</span> <span class="predefined-type">String</span> firstName;
+
+    <span class="annotation">@Title</span>(sequence=<span class="string"><span class="delimiter">&quot;</span><span class="content">1.7</span><span class="delimiter">&quot;</span></span>, append=<span class="string"><span class="delimiter">&quot;</span><span class="content">.</span><span class="delimiter">&quot;</span></span>)
+    <span class="annotation">@Getter</span> <span class="annotation">@Setter</span>
+    <span class="directive">private</span> <span class="predefined-type">String</span> midInitial;
+}</code></pre>
+</div>
+</div>
+</div>
 </div>
 <div class="sect2">
 <h3 id="_rg_annotations_manpage-ViewModel">2.31. <code>@ViewModel</code></h3>
@@ -23392,7 +24373,8 @@ using security or using a <a href="ug.html#_ug_more-advanced_decoupling_vetoing-
 <p><code>isis.object.</code><br>
 <code>editing</code></p>
 </div></div></td>
-<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>,<code>false</code> (<code>true</code>)</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>,<code>false</code><br>
+(<code>true</code>)</p></td>
 <td class="tableblock halign-left valign-top"><div><div class="paragraph">
 <p>Whether objects' properties and collections can be edited directly (for objects annotated with <a href="#_rg_annotations_manpage-DomainObject_editing"><code>@DomainObject#editing()</code></a>); see <a href="#_rg_runtime_configuring-core_isis-objects-editing">below</a> for further discussion.</p>
 </div></div></td>
@@ -23402,7 +24384,8 @@ using security or using a <a href="ug.html#_ug_more-advanced_decoupling_vetoing-
 <p><code>isis.persistor.</code><br>
 <code>disableConcurrencyChecking</code></p>
 </div></div></td>
-<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>,<code>false</code> (<code>false</code>)</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>,<code>false</code><br>
+(<code>false</code>)</p></td>
 <td class="tableblock halign-left valign-top"><div><div class="paragraph">
 <p>Disables concurrency checking globally. <br></p>
 </div>
@@ -23416,7 +24399,8 @@ using security or using a <a href="ug.html#_ug_more-advanced_decoupling_vetoing-
 <code>actionAnnotation.</code><br>
 <code>domainEvent.postForDefault</code></p>
 </div></div></td>
-<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>,<code>false</code> (<code>true</code>)</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>,<code>false</code><br>
+(<code>true</code>)</p></td>
 <td class="tableblock halign-left valign-top"><div><div class="paragraph">
 <p>Whether an event should be posted if <a href="#_rg_annotations_manpage-Action_domainEvent"><code>@Action#domainEvent()</code></a> is not specified (is set to <code>ActionDomainEvent.Default</code>).</p>
 </div></div></td>
@@ -23427,7 +24411,8 @@ using security or using a <a href="ug.html#_ug_more-advanced_decoupling_vetoing-
 <code>collectionAnnotation.</code><br>
 <code>domainEvent.postForDefault</code></p>
 </div></div></td>
-<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>,<code>false</code> (<code>true</code>)</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>,<code>false</code><br>
+(<code>true</code>)</p></td>
 <td class="tableblock halign-left valign-top"><div><div class="paragraph">
 <p>Whether an event should be posted if <a href="#_rg_annotations_manpage-Collection_domainEvent"><code>@Collection#domainEvent()</code></a> is not specified (is set to <code>CollectionDomainEvent.Default</code>).</p>
 </div></div></td>
@@ -23437,7 +24422,7 @@ using security or using a <a href="ug.html#_ug_more-advanced_decoupling_vetoing-
 <p><code>isis.reflector.facet.</code><br>
 <code>cssClass.patterns</code></p>
 </div></div></td>
-<td class="tableblock halign-left valign-top"><p class="tableblock">regex:css1,regex2:css2,&#8230;&#8203;</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">regex:css1, regex2:css2,&#8230;&#8203;</p></td>
 <td class="tableblock halign-left valign-top"><div><div class="paragraph">
 <p>Comma separated list of key:value pairs, where the key is a regex matching action names (eg <code>delete.*</code>) and the value is a <a href="http://getbootstrap.com/css/">Bootstrap</a> CSS button class (eg <code>btn-warning) to be applied (as per `@CssClass()</code>) to all action members matching the regex.<br></p>
 </div>
@@ -23461,10 +24446,110 @@ using security or using a <a href="ug.html#_ug_more-advanced_decoupling_vetoing-
 <tr>
 <td class="tableblock halign-left valign-top"><div><div class="paragraph">
 <p><code>isis.reflector.facet.</code><br>
+<code>domainObjectAnnotation.</code><br>
+<code>createdLifecycleEvent.</code><br>
+<code>postForDefault</code><br>
+(<code>1.11.0-SNAPSHOT</code>)</p>
+</div></div></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>,<code>false</code><br>
+(<code>true</code>)</p></td>
+<td class="tableblock halign-left valign-top"><div><div class="paragraph">
+<p>Whether an event should be posted if <a href="#_rg_annotations_manpage-DomainObject_createdLifecycleEvent"><code>@DomainObject#createdLifecycleEvent()</code></a> is not specified (is set to <code>ObjectCreatedEvent.Default</code>).</p>
+</div></div></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><div><div class="paragraph">
+<p><code>isis.reflector.facet.</code><br>
+<code>domainObjectAnnotation.</code><br>
+<code>loadedLifecycleEvent.</code><br>
+<code>postForDefault</code><br>
+(<code>1.11.0-SNAPSHOT</code>)</p>
+</div></div></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>,<code>false</code><br>
+(<code>true</code>)</p></td>
+<td class="tableblock halign-left valign-top"><div><div class="paragraph">
+<p>Whether an event should be posted if <a href="#_rg_annotations_manpage-DomainObject_loadedLifecycleEvent"><code>@DomainObject#loadedLifecycleEvent()</code></a> is not specified (is set to <code>ObjectLoadedEvent.Default</code>).</p>
+</div></div></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><div><div class="paragraph">
+<p><code>isis.reflector.facet.</code><br>
+<code>domainObjectAnnotation.</code><br>
+<code>persistingLifecycleEvent.</code><br>
+<code>postForDefault</code><br>
+(<code>1.11.0-SNAPSHOT</code>)</p>
+</div></div></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>,<code>false</code><br>
+(<code>true</code>)</p></td>
+<td class="tableblock halign-left valign-top"><div><div class="paragraph">
+<p>Whether an event should be posted if <a href="#_rg_annotations_manpage-DomainObject_persistingLifecycleEvent"><code>@DomainObject#persistingLifecycleEvent()</code></a> is not specified (is set to <code>ObjectPersistingEvent.Default</code>).</p>
+</div></div></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><div><div class="paragraph">
+<p><code>isis.reflector.facet.</code><br>
+<code>domainObjectAnnotation.</code><br>
+<code>persistedLifecycleEvent.</code><br>
+<code>postForDefault</code><br>
+(<code>1.11.0-SNAPSHOT</code>)</p>
+</div></div></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>,<code>false</code><br>
+(<code>true</code>)</p></td>
+<td class="tableblock halign-left valign-top"><div><div class="paragraph">
+<p>Whether an event should be posted if <a href="#_rg_annotations_manpage-DomainObject_persistedLifecycleEvent"><code>@DomainObject#persistedLifecycleEvent()</code></a> is not specified (is set to <code>ObjectPersistedEvent.Default</code>).</p>
+</div></div></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><div><div class="paragraph">
+<p><code>isis.reflector.facet.</code><br>
+<code>domainObjectAnnotation.</code><br>
+<code>removingLifecycleEvent.</code><br>
+<code>postForDefault</code><br>
+(<code>1.11.0-SNAPSHOT</code>)</p>
+</div></div></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>,<code>false</code><br>
+(<code>true</code>)</p></td>
+<td class="tableblock halign-left valign-top"><div><div class="paragraph">
+<p>Whether an event should be posted if <a href="#_rg_annotations_manpage-DomainObject_removingLifecycleEvent"><code>@DomainObject#removingLifecycleEvent()</code></a> is not specified (is set to <code>ObjectRemovingEvent.Default</code>).</p>
+</div></div></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><div><div class="paragraph">
+<p><code>isis.reflector.facet.</code><br>
+<code>domainObjectAnnotation.</code><br>
+<code>updatingLifecycleEvent.</code><br>
+<code>postForDefault</code><br>
+(<code>1.11.0-SNAPSHOT</code>)</p>
+</div></div></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>,<code>false</code><br>
+(<code>true</code>)</p></td>
+<td class="tableblock halign-left valign-top"><div><div class="paragraph">
+<p>Whether an event should be posted if <a href="#_rg_annotations_manpage-DomainObject_updatingLifecycleEvent"><code>@DomainObject#updatingLifecycleEvent()</code></a> is not specified (is set to <code>ObjectUpdatingEvent.Default</code>).</p>
+</div></div></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><div><div class="paragraph">
+<p><code>isis.reflector.facet.</code><br>
+<code>domainObjectAnnotation.</code><br>
+<code>updatedLifecycleEvent.</code><br>
+<code>postForDefault</code><br>
+(<code>1.11.0-SNAPSHOT</code>)</p>
+</div></div></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>,<code>false</code><br>
+(<code>true</code>)</p></td>
+<td class="tableblock halign-left valign-top"><div><div class="paragraph">
+<p>Whether an event should be posted if <a href="#_rg_annotations_manpage-DomainObject_updatedLifecycleEvent"><code>@DomainObject#updatedLifecycleEvent()</code></a> is not specified (is set to <code>ObjectUpdatedEvent.Default</code>).</p>
+</div></div></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><div><div class="paragraph">
+<p><code>isis.reflector.facet.</code><br>
 <code>domainObjectLayoutAnnotation.</code><br>
-<code>cssClassUiEvent.postForDefault</code></p>
+<code>cssClassUiEvent.postForDefault</code><br>
+(<code>1.11.0-SNAPSHOT</code>)</p>
 </div></div></td>
-<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>,<code>false</code> (<code>true</code>)</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>,<code>false</code><br>
+(<code>true</code>)</p></td>
 <td class="tableblock halign-left valign-top"><div><div class="paragraph">
 <p>Whether an event should be posted if <a href="#_rg_annotations_manpage-DomainObjectLayout_cssClassUiEvent"><code>@DomainObjectLayout#cssClassUiEvent()</code></a> is not specified (is set to <code>CssClassUiEvent.Default</code>).</p>
 </div></div></td>
@@ -23473,9 +24558,11 @@ using security or using a <a href="ug.html#_ug_more-advanced_decoupling_vetoing-
 <td class="tableblock halign-left valign-top"><div><div class="paragraph">
 <p><code>isis.reflector.facet.</code><br>
 <code>domainObjectLayoutAnnotation.</code><br>
-<code>iconUiEvent.postForDefault</code></p>
+<code>iconUiEvent.postForDefault</code><br>
+(<code>1.11.0-SNAPSHOT</code>)</p>
 </div></div></td>
-<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>,<code>false</code> (<code>true</code>)</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>,<code>false</code><br>
+(<code>true</code>)</p></td>
 <td class="tableblock halign-left valign-top"><div><div class="paragraph">
 <p>Whether an event should be posted if <a href="#_rg_annotations_manpage-DomainObjectLayout_iconUiEvent"><code>@DomainObjectLayout#iconUiEvent()</code></a> is not specified (is set to <code>IconUiEvent.Default</code>).</p>
 </div></div></td>
@@ -23484,9 +24571,11 @@ using security or using a <a href="ug.html#_ug_more-advanced_decoupling_vetoing-
 <td class="tableblock halign-left valign-top"><div><div class="paragraph">
 <p><code>isis.reflector.facet.</code><br>
 <code>domainObjectLayoutAnnotation.</code><br>
-<code>titleUiEvent.postForDefault</code></p>
+<code>titleUiEvent.postForDefault</code><br>
+(<code>1.11.0-SNAPSHOT</code>)</p>
 </div></div></td>
-<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>,<code>false</code> (<code>true</code>)</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>,<code>false</code><br>
+(<code>true</code>)</p></td>
 <td class="tableblock halign-left valign-top"><div><div class="paragraph">
 <p>Whether an event should be posted if <a href="#_rg_annotations_manpage-DomainObjectLayout_titleUiEvent"><code>@DomainObjectLayout#titleUiEvent()</code></a> is not specified (is set to <code>TitleUiEvent.Default</code>).</p>
 </div></div></td>
@@ -23496,7 +24585,8 @@ using security or using a <a href="ug.html#_ug_more-advanced_decoupling_vetoing-
 <p><code>isis.reflector.facet.</code><br>
 <code>filterVisibility</code></p>
 </div></div></td>
-<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>,<code>false</code> (<code>true</code>)</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>,<code>false</code><br>
+(<code>true</code>)</p></td>
 <td class="tableblock halign-left valign-top"><div><div class="paragraph">
 <p>Whether objects should be filtered for visibility.<br></p>
 </div>
@@ -23510,7 +24600,8 @@ using security or using a <a href="ug.html#_ug_more-advanced_decoupling_vetoing-
 <code>propertyAnnotation.</code><br>
 <code>domainEvent.postForDefault</code></p>
 </div></div></td>
-<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>,<code>false</code> (<code>true</code>)</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>,<code>false</code><br>
+(<code>true</code>)</p></td>
 <td class="tableblock halign-left valign-top"><div><div class="paragraph">
 <p>Whether an event should be posted if <a href="#_rg_annotations_manpage-Property_domainEvent"><code>@Property#domainEvent()</code></a> is not specified (is set to <code>PropertyDomainEvent.Default</code>).</p>
 </div></div></td>
@@ -23581,7 +24672,8 @@ See <a href="ug.html#_ug_extending_programming-model_finetuning">finetuning the
 <p><code>isis.reflector.validator.</code><br>
 <code>allowDeprecated</code></p>
 </div></div></td>
-<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>,<code>false</code> (<code>true</code>)</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>,<code>false</code><br>
+(<code>true</code>)</p></td>
 <td class="tableblock halign-left valign-top"><div><div class="paragraph">
 <p>Whether deprecated annotations or naming conventions are tolerated or not.  If not, then a metamodel validation error will be triggered, meaning the app won&#8217;t boot (fail-fast).</p>
 </div></div></td>
@@ -23606,7 +24698,8 @@ See <a href="ug.html#_ug_extending_programming-model_finetuning">finetuning the
 <p><code>isis.services.</code><br>
 <code>audit.objects</code></p>
 </div></div></td>
-<td class="tableblock halign-left valign-top"><p class="tableblock"><code>all</code>, <code>none</code> (<code>all</code>)</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock"><code>all</code>, <code>none</code><br>
+(<code>all</code>)</p></td>
 <td class="tableblock halign-left valign-top"><div><div cl

<TRUNCATED>