| <html><head> |
| <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> |
| <title xmlns:d="http://docbook.org/ns/docbook">Chapter 5. Starting Cayenne</title><link rel="stylesheet" type="text/css" href="css/cayenne-doc.css"><meta xmlns:d="http://docbook.org/ns/docbook" name="keywords" content="Cayenne 3.1 documentation"><meta xmlns:d="http://docbook.org/ns/docbook" name="description" content="User documentation for Apache Cayenne version 3.1"><link rel="home" href="index.html" title="Cayenne Guide"><link rel="up" href="cayenne-guide-part2.html" title="Part II. Cayenne Framework"><link rel="prev" href="including-cayenne-in-project.html" title="Chapter 4. Including Cayenne in a Project"><link rel="next" href="persistent-objects-objectcontext.html" title="Chapter 6. Persistent Objects and ObjectContext"><script xmlns:d="http://docbook.org/ns/docbook" type="text/javascript"> |
| var _gaq = _gaq || []; |
| _gaq.push(['_setAccount', 'UA-7036673-1']); |
| _gaq.push(['_trackPageview']); |
| (function() { |
| var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; |
| ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; |
| var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); |
| })(); |
| </script></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div xmlns:d="http://docbook.org/ns/docbook" class="navheader"><table width="100%" summary="Navigation header"><tr><th class="versioninfo">v.3.1 (3.1)</th><th align="center">Chapter 5. Starting Cayenne</th><th></th></tr><tr><td width="20%" align="left"><a accesskey="p" href="including-cayenne-in-project.html">Prev</a> </td><th width="60%" align="center"><a accesskey="u" href="cayenne-guide-part2.html">Part II. Cayenne Framework</a></th><td width="20%" align="right"> <a accesskey="n" href="persistent-objects-objectcontext.html">Next</a></td></tr></table><hr></div><div class="chapter" title="Chapter 5. Starting Cayenne"><div class="titlepage"><div><div><h2 class="title"><a name="starting-cayenne"></a>Chapter 5. Starting Cayenne</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="starting-cayenne.html#starting-serverruntime">Starting and Stopping ServerRuntime</a></span></dt><dt><span class="section"><a href="starting-cayenne.html#d0e963">Merging Multiple Projects</a></span></dt><dt><span class="section"><a href="starting-cayenne.html#webapps">Web Applications</a></span></dt></dl></div><div class="section" title="Starting and Stopping ServerRuntime"><div class="titlepage"><div><div><h2 class="title"><a name="starting-serverruntime"></a>Starting and Stopping ServerRuntime</h2></div></div></div><p>In runtime Cayenne is accessed via |
| <code class="code">org.apache.cayenne.configuration.server.ServerRuntime</code>. ServerRuntime is |
| created simply by calling a |
| constructor:</p><pre class="programlisting">ServerRuntime runtime = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">new</span> ServerRuntime(<span xmlns="http://www.w3.org/1999/xhtml" class="hl-string">"com/example/cayenne-project.xml"</span>);</pre><p>The parameter you pass to the constructor is a location of the main project file. Location |
| is a '/'-separated path (same path separator is used on UNIX and Windows) that is |
| resolved relative to the application classpath. The project file can be placed in the |
| root package or in a subpackage (e.g. in the code above it is in "com/example" |
| subpackage).</p><p>ServerRuntime encapsulates a single Cayenne stack. Most applications will just have |
| one ServerRuntime using it to create as many ObjectContexts as needed, access the |
| Dependency Injection (DI) container and work with other Cayenne features. Internally |
| ServerRuntime is just a thin wrapper around the DI container. Detailed features of the |
| container are discussed in "Customizing Cayenne Runtime" chapter. Here we'll just show |
| an example of how an application might replace a default implementation of a built-in |
| Cayenne service (in this case - QueryCache) with a different |
| class:</p><pre class="programlisting"><span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">public</span> <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">class</span> MyExtensionsModule <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">implements</span> Module { |
| <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">public</span> <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">void</span> configure(Binder binder) { |
| binder.bind(QueryCache.<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">class</span>).to(EhCacheQueryCache.<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">class</span>); |
| } |
| }</pre><pre class="programlisting">Module extensions = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">new</span> MyExtensionsModule(); |
| ServerRuntime runtime = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">new</span> ServerRuntime(<span xmlns="http://www.w3.org/1999/xhtml" class="hl-string">"com/example/cayenne-project.xml"</span>, extensions);</pre><p>It is a good idea to shut down the runtime when it is no longer needed, usually before the |
| application itself is shutdown: </p><pre class="programlisting">runtime.shutdown();</pre><p>When |
| a runtime object has the same scope as the application, this may not be always |
| necessary, however in some cases it is essential, and is generally considered a good |
| practice. E.g. in a web container hot redeploy of a webapp will cause resource leaks and |
| eventual OutOfMemoryError if the application fails to shutdown CayenneRuntime.</p></div><div class="section" title="Merging Multiple Projects"><div class="titlepage"><div><div><h2 class="title"><a name="d0e963"></a>Merging Multiple Projects</h2></div></div></div><p>ServerRuntime requires at least one mapping project to run. But it can also take multiple |
| projects and merge them together in a single configuration. This way different parts of |
| a database can be mapped independenlty from each other (even by different software |
| providers), and combined in runtime when assembling an application. Doing it is as easy |
| as passing multiple project locations to ServerRuntime constructor:</p><pre class="programlisting">ServerRuntime runtime = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">new</span> ServerRuntime(<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">new</span> String[] { |
| <span xmlns="http://www.w3.org/1999/xhtml" class="hl-string">"com/example/cayenne-project.xml"</span>, |
| <span xmlns="http://www.w3.org/1999/xhtml" class="hl-string">"org/foo/cayenne-library1.xml"</span>, |
| <span xmlns="http://www.w3.org/1999/xhtml" class="hl-string">"org/foo/cayenne-library2.xml"</span> |
| } |
| );</pre><p>When the projects are merged, the following rules are applied:</p><div class="itemizedlist"><ul class="itemizedlist"><li class="listitem"><p>The order of projects matters during merge. If there are two conflicting |
| metadata objects belonging to two projects, an object from the <span class="italic">last</span> project takes precedence over the object |
| from the first one. This makes possible to override pieces of metadata. This |
| is also similar to how DI modules are merged in Cayenne.</p></li><li class="listitem"><p>Runtime DataDomain name is set to the name of the last project in the |
| list.</p></li><li class="listitem"><p>Runtime DataDomain properties are the same as the properties of the last |
| project in the list. I.e. <span class="italic">properties are not |
| merged</span> to avoid invalid combinations and unexpected runtime |
| behavior.</p></li><li class="listitem"><p>If there are two or more DataMaps with the same name, only one DataMap is |
| used in the merged project, the rest are discarded. Same precedence rules |
| apply - DataMap from the project with the highest index in the project list |
| overrides all other DataMaps with the same name.</p></li><li class="listitem"><p>If there are two or more DataNodes with the same name, only one DataNodes |
| is used in the merged project, the rest are discarded. DataNode coming from |
| project with the highest index in the project list is chosen per precedence |
| rule above.</p></li><li class="listitem"><p>There is a notion of "default" DataNode. After the merge if any DataMaps |
| are not explicitly linked to DataNodes, their queries will be executed via a |
| default DataNode. This makes it possible to build mapping "libraries" that |
| are only associated with a specific database in runtime. If there's only one |
| DataNode in the merged project, it will be automatically chosen as default. |
| A possible way to explicitly designate a specific node as default is to |
| override <code class="code">DataDomainProvider.createAndInitDataDomain()</code>.</p></li></ul></div></div><div class="section" title="Web Applications"><div class="titlepage"><div><div><h2 class="title"><a name="webapps"></a>Web Applications</h2></div></div></div><p>Web applications can use a variety of mechanisms to configure and start the "services" |
| they need, Cayenne being one of such services. Configuration can be done within standard |
| Servlet specification objects like Servlets, Filters, or ServletContextListeners, or can |
| use Spring, JEE CDI, etc. This is a user's architectural choice and Cayenne is agnostic |
| to it and will happily work in any environment. As described above, all that is needed |
| is to create an instance of ServerRuntime somewhere and provide the application code |
| with means to access it. And shut it down when the application ends to avoid container |
| leaks.</p><p>Still Cayenne includes a piece of web app configuration code that can assist in |
| quickly setting up simple Cayenne-enabled web applications. We are talking about |
| CayenneFilter. It is declared in |
| web.xml:</p><pre class="programlisting"><web-app> |
| ... |
| <filter> |
| <filter-name>cayenne-project</filter-name> |
| <filter-class>org.apache.cayenne.configuration.web.CayenneFilter</filter-class> |
| </filter> |
| <filter-mapping> |
| <filter-name>cayenne-project</filter-name> |
| <url-pattern>/*</url-pattern> |
| </filter-mapping> |
| ... |
| </web-app> </pre><p>When started by the web container, it creates a instance of ServerRuntime and stores |
| it in the ServletContext. Note that the name of Cayenne XML project file is derived from |
| the "filter-name". In the example above CayenneFilter will look for an XML file |
| "cayenne-project.xml". This can be overridden with "configuration-location" init |
| parameter.</p><p>When the application runs, all HTTP requests matching the filter url-pattern will have |
| access to a session-scoped ObjectContext like |
| this:</p><pre class="programlisting">ObjectContext context = BaseContext.getThreadObjectContext();</pre><p>Of |
| course the ObjectContext scope, and other behavior of the Cayenne runtime can be |
| customized via dependency injection. For this another filter init parameter called |
| "extra-modules" is used. "extra-modules" is a comma or space-separated list of class |
| names, with each class implementing Module interface. These optional custom modules are |
| loaded after the the standard ones, which allows users to override all standard |
| definitions.</p><p>For those interested in the DI container contents of the runtime created by CayenneFilter, |
| it is the same ServerRuntime as would've been created by other means, but with an extra |
| <code class="code">org.apache.cayenne.configuration.web.WebModule</code> module that provides |
| <code class="code">org.apache.cayenne.configuration.web.RequestHandler</code> service. This is |
| the service to override in the custom modules if you need to provide a different |
| ObjectContext scope, etc.</p><p> |
| </p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>You should not think of CayenneFilter as the only way to start and use Cayenne in a web |
| application. In fact CayenneFilter is entirely optional. Use it if you don't |
| have any special design for application service management. If you do, simply |
| integrate Cayenne into that design.</p></div><p> |
| </p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="including-cayenne-in-project.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="cayenne-guide-part2.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="persistent-objects-objectcontext.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 4. Including Cayenne in a Project </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 6. Persistent Objects and ObjectContext</td></tr></table></div></body></html> |