blob: 01414d66d62a6c69eeb082e26f799d81d7a10929 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Persisted Title :: Apache Isis</title>
<link rel="canonical" href="https://isis.apache.org/userguide/2.0.0-M3/btb/hints-and-tips/persisted-title.html">
<meta name="generator" content="Antora 2.2.0">
<link rel="stylesheet" href="../../../../_/css/site.css">
<link rel="stylesheet" href="../../../../_/css/site-custom.css">
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,700,700i|Raleway:300,400,500,700,800|Montserrat:300,400,700" rel="stylesheet">
<link rel="home" href="https://isis.apache.org" title="Apache Isis">
</head>
<body class="article">
<header class="header">
<nav class="navbar">
<div class="navbar-brand">
<a class="navbar-item" href="https://isis.apache.org">
<span class="icon">
<img src="../../../../_/img/isis-logo-48x48.png"></img>
</span>
<span>Apache Isis</span>
</a>
<button class="navbar-burger" data-target="topbar-nav">
<span></span>
<span></span>
<span></span>
</button>
</div>
<div id="topbar-nav" class="navbar-menu">
<a class="navbar-end">
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">Quick Start</a>
<div class="navbar-dropdown">
<span class="navbar-item navbar-heading">Starter Apps</span>
<a class="navbar-item" href="../../../../docs/latest/starters/helloworld.html">Hello World</a>
<a class="navbar-item" href="../../../../docs/latest/starters/simpleapp.html">Simple App</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Demos &amp; Tutorials</span>
<a class="navbar-item" href="../../../../docs/latest/demo/about.html">Demo App</a>
<a class="navbar-item" href="https://danhaywood.gitlab.io/isis-petclinic-tutorial-docs/petclinic/1.16.2/intro.html">Petclinic (tutorial)</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Resources</span>
<a class="navbar-item" href="../../../../docs/latest/resources/cheatsheet.html">Cheatsheet</a>
<a class="navbar-item" href="../../../../docs/latest/resources/icons.html">Icons</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">Guides</a>
<div class="navbar-dropdown">
<span class="navbar-item navbar-heading">Development</span>
<a class="navbar-item" href="../../../../setupguide/latest/about.html">Setup Guide</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Core</span>
<a class="navbar-item" href="../../../../userguide/latest/about.html">User Guide</a>
<a class="navbar-item" href="../../../../refguide/latest/about.html">Reference Guide</a>
<a class="navbar-item" href="../../../../testing/latest/about.html">Testing Guide</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">Libraries</a>
<div class="navbar-dropdown">
<span class="navbar-item navbar-heading">For Use in Apps</span>
<a class="navbar-item" href="../../../../subdomains/latest/about.html">Subdomain Libraries</a>
<a class="navbar-item" href="../../../../valuetypes/latest/about.html">Value Types</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Integrate between Apps</span>
<a class="navbar-item" href="../../../../mappings/latest/about.html">Bounded Context Mapping Libraries</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Other</span>
<a class="navbar-item" href="../../../../incubator/latest/about.html">Incubator</a>
<a class="navbar-item" href="../../../../legacy/latest/about.html">Legacy</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">Components</a>
<div class="navbar-dropdown">
<span class="navbar-item navbar-heading">Viewers</span>
<a class="navbar-item" href="../../../../vw/latest/about.html">Wicket UI</a>
<a class="navbar-item" href="../../../../vro/latest/about.html">Restful Objects (REST)</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Security</span>
<a class="navbar-item" href="../../../../security/latest/about.html">Security Guide</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Persistence</span>
<a class="navbar-item" href="../../../../pjdo/latest/about.html">DataNucleus (JDO)</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Extensions</span>
<a class="navbar-item" href="../../../../extensions/latest/about.html">Extensions Catalog</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">Support</a>
<div class="navbar-dropdown">
<span class="navbar-item navbar-heading">Contact</span>
<a class="navbar-item" href="../../../../docs/latest/support/slack-channel.html">Slack</a>
<a class="navbar-item" href="../../../../docs/latest/support/mailing-list.html">Mailing Lists</a>
<a class="navbar-item" href="https://issues.apache.org/jira/browse/ISIS">JIRA</a>
<a class="navbar-item" href="https://stackoverflow.com/questions/tagged/isis">Stack Overflow</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Releases</span>
<a class="navbar-item" href="../../../../docs/latest/downloads/how-to.html">Downloads</a>
<a class="navbar-item" href="../../../../relnotes/latest/about.html">Release Notes</a>
<a class="navbar-item" href="../../../../docs/latest/archive/1-x.html">Archive (1.x)</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Framework</span>
<a class="navbar-item" href="../../../../conguide/latest/about.html">Contributors' Guide</a>
<a class="navbar-item" href="../../../../comguide/latest/about.html">Committers' Guide</a>
<a class="navbar-item" href="../../../../core/latest/about.html">Core Design</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">ASF</a>
<div class="navbar-dropdown">
<a class="navbar-item" href="http://www.apache.org/">Apache Homepage</a>
<a class="navbar-item" href="https://www.apache.org/events/current-event">Events</a>
<a class="navbar-item" href="https://www.apache.org/licenses/">Licenses</a>
<a class="navbar-item" href="https://www.apache.org/security/">Security</a>
<a class="navbar-item" href="https://www.apache.org/foundation/sponsorship.html">Sponsorship</a>
<a class="navbar-item" href="https://www.apache.org/foundation/thanks.html">Thanks</a>
<hr class="navbar-divider"/>
<a class="navbar-item" href="https://whimsy.apache.org/board/minutes/Isis.html">PMC board minutes</a>
</div>
</div>
<a class="navbar-item" href="../../../../docs/latest/about.html">
<span class="icon">
<img src="../../../../_/img/home.png"></img>
</span>
</a>
</div>
</div>
</nav>
</header>
<div class="body ">
<div class="nav-container" data-component="userguide" data-version="2.0.0-M3">
<aside class="nav">
<div class="panels">
<div class="nav-panel-pagination">
<a class="page-previous disabled" rel="prev" href="" title=""><span></span></a>
<a class="page-next disabled" rel="next"
href="" title=""><span></span></a>
<!--
page.parent doesn't seem to be set...
<a class="page-parent disabled" rel="prev" href="" title=""><span></span></a>
-->
</div>
<div class="nav-panel-menu is-active" data-panel="menu">
<nav class="nav-menu">
<h3 class="title"><a href="../../about.html">User Guide</a></h3>
<ul class="nav-list">
<li class="nav-item" data-depth="0">
<ul class="nav-list">
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../fun/concepts-patterns.html">Concepts &amp; Patterns</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../fun/overview.html">Overview</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../fun/domain-entities-and-services.html">Domain Entities &amp; Services</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../fun/object-members.html">Object Members</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../fun/ui.html">UI Layout &amp; Hints</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../fun/business-rules.html">Business Rules</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../fun/drop-downs-and-defaults.html">Drop downs and Defaults</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../fun/meta-annotations.html">Meta-annotations</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../fun/view-models.html">View Models</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../fun/mixins.html">Mixins</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../fun/modules.html">Modules</a>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../about.html">Beyond the Basics</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../i18n.html">i18n</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../headless-access.html">Headless Access</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../hints-and-tips.html">Hints-n-Tips</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../programming-model.html">Programming Model</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<span class="nav-text">Extensions</span>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../flyway/about.html">Flyway</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</div>
<div class="nav-panel-explore" data-panel="explore">
<div class="context">
<span class="title">User Guide</span>
<span class="version">2.0.0-M3</span>
</div>
<ul class="components">
<li class="component">
<span class="title"> </span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../docs/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">BC Mappings Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../mappings/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Committers' Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../comguide/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Contributors' Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../conguide/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Design Docs</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../core/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Extensions Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../extensions/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Incubator Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../incubator/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">JDO/DataNucleus</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../pjdo/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Legacy Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../legacy/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Reference Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../refguide/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Release Notes</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../relnotes/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Restful Objects Viewer</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../vro/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Security Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../security/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Setup Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../setupguide/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Subdomains Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../subdomains/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Testing Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../testing/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component is-current">
<span class="title">User Guide</span>
<ul class="versions">
<li class="version is-current is-latest">
<a href="../../about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Value Types Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../valuetypes/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Wicket Viewer</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../vw/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
</aside>
</div>
<main role="main">
<div class="toolbar" role="navigation">
<button class="nav-toggle"></button>
<a href="../../../../docs/2.0.0-M3/about.html" class="home-link"></a>
<nav class="breadcrumbs" aria-label="breadcrumbs">
<ul>
<li><a href="../../about.html">User Guide</a></li>
<li><a href="persisted-title.html">Persisted Title</a></li>
</ul>
</nav>
<div class="edit-this-page"><a href="https://github.com/apache/isis/edit/2.0.0-M3/api/adoc/userguide/modules/btb/pages/hints-and-tips/persisted-title.adoc">Edit</a></div>
</div>
<article class="doc">
<a name="section-top"></a>
<h1 class="page">Persisted Title</h1>
<div class="paragraph">
<p>Normally the title of an object is not persisted to the database, rather it is recomputed automatically from underlying properties.
On occasion though you might want the title to also be persisted; either to make things easier for the DBA, or for an integration scenario, or to support full-text search.</p>
</div>
<div class="paragraph">
<p>We can implement this feature by either overriding the <a href="#refguide:applib-cm:methods/lifecycle.adoc" class="page unresolved">lifecycle methods</a> or (probably better) subscribing to the <a href="#refguide:applib-cm:classes/lifecycleevent.adoc" class="page unresolved">lifecycle events</a>.</p>
</div>
<div class="paragraph">
<p>In the design we discuss here we make it a responsibility of the entities to persist the title as a property, by implementing a <code>ObjectWithPersistedTitle</code> interface:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public interface ObjectWithPersistedTitle {
@Programmatic <i class="conum" data-value="1"></i><b>(1)</b>
String getPersistedTitle();
void setPersistedTitle(final String title);
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>we don&#8217;t want to expose this in the UI.</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>We can then define a subscribing domain service that leverage this.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import org.apache.isis.applib.events.lifecycle.ObjectPersistingEvent;
import org.apache.isis.applib.events.lifecycle.ObjectUpdatingEvent;
import lombok.val;
@Service
public class TitlingService {
@EventListener(ObjectPersistingEvent.class)
public void on(ObjectPersistingEvent ev) {
handle(ev.getSource());
}
@EventListener(ObjectUpdatingEvent.class)
public void on(ObjectUpdatingEvent ev) {
handle(ev.getSource());
}
private void handle(final Object persistentInstance) {
if(persistentInstance instanceof ObjectWithPersistedTitle) {
val objectWithPersistedTitle =
(ObjectWithPersistedTitle) persistentInstance;
objectWithPersistedTitle.setPersistedTitle(titleService.titleOf(objectWithPersistedTitle));
}
}
@Inject
TitleService titleService;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The above is probably the easiest and most straightforward design.
One could imagine other designs where the persisted title is stored elsewhere, such as a <a href="http://lucene.apache.org/">Apache Lucene</a> (or similar) database to allow for full-text searches.</p>
</div>
</article>
<aside class="article-aside toc" role="navigation">
<p class="toc-title">On this page</p>
<div id="article-toc"></div>
</aside>
</main>
</div>
<footer class="footer">
<div class="content">
<div class="copyright">
<p>
Copyright © 2010~2020 The Apache Software Foundation, licensed under the Apache License, v2.0.
<br/>
Apache, the Apache feather logo, Apache Isis, and the Apache Isis project logo are all trademarks of The Apache Software Foundation.
</p>
</div>
<div class="revision">
<p>Revision: SNAPSHOT</p>
</div>
</div>
</footer>
<script src="../../../../_/js/site.js"></script>
<script async src="../../../../_/js/vendor/highlight.js"></script>
<script src="../../../../_/js/vendor/jquery-3.4.1.min.js"></script>
<script src="../../../../_/js/vendor/jquery-ui-1.12.1.custom.widget-only.min.js"></script>
<script src="../../../../_/js/vendor/jquery.tocify.min.js"></script>
<script>
$(function() {
$("#article-toc").tocify( {
showEffect: "slideDown",
hashGenerator: "pretty",
hideEffect: "slideUp",
selectors: "h2, h3",
scrollTo: 120,
smoothScroll: true,
theme: "jqueryui",
highlightOnScroll: true
} );
});
</script>
</body>
</html>