| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" |
| "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
| <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> |
| <head> |
| <!-- Matomo --> |
| <script> |
| var _paq = window._paq = window._paq || []; |
| /* tracker methods like "setCustomDimension" should be called before "trackPageView" */ |
| _paq.push(["setDoNotTrack", true]); |
| _paq.push(["disableCookies"]); |
| _paq.push(['trackPageView']); |
| _paq.push(['enableLinkTracking']); |
| (function() { |
| var u="https://analytics.apache.org/"; |
| _paq.push(['setTrackerUrl', u+'matomo.php']); |
| _paq.push(['setSiteId', '79']); |
| var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; |
| g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s); |
| })(); |
| </script> |
| <!-- End Matomo Code --> |
| <title>4 Configuration 6.2.3</title> |
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> |
| <link rel="stylesheet" href="../css/main.css" type="text/css" media="screen, print" title="Style" charset="utf-8"/> |
| <link rel="stylesheet" href="../css/pdf.css" type="text/css" media="print" title="PDF" charset="utf-8"/> |
| <script type="text/javascript"> |
| function addJsClass() { |
| var classes = document.body.className.split(" "); |
| classes.push("js"); |
| document.body.className = classes.join(" "); |
| } |
| </script> |
| </head> |
| |
| <body class="body" onload="addJsClass();"> |
| <div id="navigation"> |
| <div class="navTitle"> |
| |
| The Grails Framework |
| </div> |
| <div class="navLinks"> |
| <ul> |
| <li> |
| <div id="nav-summary" onmouseover="toggleNavSummary(false)" onmouseout="toggleNavSummary(true)"> |
| <a href="../guide/index.html" class="button">Table of contents</a> |
| |
| <div id="nav-summary-childs" style="display:none;"> |
| |
| <div class="toc-item" style="margin-left:0"><a href="../guide/introduction.html"><strong>1</strong><span>Introduction</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:0"><a href="../guide/gettingStarted.html"><strong>2</strong><span>Getting Started</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:0"><a href="../guide/upgrading.html"><strong>3</strong><span>Upgrading from the previous versions</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:0"><a href="../guide/conf.html"><strong>4</strong><span>Configuration</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:0"><a href="../guide/commandLine.html"><strong>5</strong><span>The Command Line</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:0"><a href="../guide/profiles.html"><strong>6</strong><span>Application Profiles</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:0"><a href="../guide/GORM.html"><strong>7</strong><span>Object Relational Mapping (GORM)</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:0"><a href="../guide/theWebLayer.html"><strong>8</strong><span>The Web Layer</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:0"><a href="../guide/traits.html"><strong>9</strong><span>Traits</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:0"><a href="../guide/REST.html"><strong>10</strong><span>REST</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:0"><a href="../guide/async.html"><strong>11</strong><span>Asynchronous Programming</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:0"><a href="../guide/validation.html"><strong>12</strong><span>Validation</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:0"><a href="../guide/services.html"><strong>13</strong><span>The Service Layer</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:0"><a href="../guide/staticTypeCheckingAndCompilation.html"><strong>14</strong><span>Static Type Checking And Compilation</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:0"><a href="../guide/testing.html"><strong>15</strong><span>Testing</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:0"><a href="../guide/i18n.html"><strong>16</strong><span>Internationalization</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:0"><a href="../guide/security.html"><strong>17</strong><span>Security</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:0"><a href="../guide/plugins.html"><strong>18</strong><span>Plugins</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:0"><a href="../guide/spring.html"><strong>19</strong><span>Grails and Spring</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:0"><a href="../guide/scaffolding.html"><strong>20</strong><span>Scaffolding</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:0"><a href="../guide/deployment.html"><strong>21</strong><span>Deployment</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:0"><a href="../guide/contributing.html"><strong>22</strong><span>Contributing to Grails</span></a> |
| </div> |
| |
| </div> |
| </div> |
| </li> |
| <li class="separator selected"> |
| <a id="ref-button" onclick="localToggle(); return false;" href="#">Quick Reference</a> |
| </li> |
| </ul> |
| </div> |
| |
| |
| </div> |
| |
| <table id="colset" border="0" cellpadding="0" cellspacing="0"> |
| <tr> |
| <td id="col1"> |
| <div id="main" class="corner-all"> |
| |
| |
| <div class="toc-item prev-left"><a href="../guide/upgrading.html"><< <strong>3</strong><span>Upgrading from the previous versions</span></a></div> |
| |
| |
| <span id='toggle-col1' class="toggle">(<a href="#" onclick="localToggle(); return false;">Quick Reference</a>)</span> |
| |
| |
| <div class="toc-item next-right"><a href="../guide/commandLine.html"><strong>5</strong><span>The Command Line</span> >></a></div> |
| |
| |
| |
| <div class="project"> |
| <h1>4 Configuration</h1> |
| |
| <p><strong>Version:</strong> 6.2.3</p> |
| </div> |
| |
| |
| <div id="table-of-content"> |
| <h2>Table of Contents</h2> |
| |
| <div class="toc-item" style="margin-left:0px"><a href="#config"><strong>4.1</strong><span>Basic Configuration</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:10px"><a href="#ymlOptions"><strong>4.1.1</strong><span>Options for the YML format Config</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:10px"><a href="#builtInOptions"><strong>4.1.2</strong><span>Built in options</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:10px"><a href="#logging"><strong>4.1.3</strong><span>Logging</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:20px"><a href="#loggerName"><strong>4.1.3.1</strong><span>Logger Names</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:20px"><a href="#maskingRequestParametersFromStacktraceLogs"><strong>4.1.3.2</strong><span>Masking Request Parameters From Stacktrace Logs</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:20px"><a href="#externalLoggingConfiguration"><strong>4.1.3.3</strong><span>External Configuration File</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:10px"><a href="#configGORM"><strong>4.1.4</strong><span>GORM</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:10px"><a href="#proxyConfig"><strong>4.1.5</strong><span>Configuring an HTTP proxy</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:0px"><a href="#applicationClass"><strong>4.2</strong><span>The Application Class</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:10px"><a href="#executing"><strong>4.2.1</strong><span>Executing the Application Class</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:10px"><a href="#customizing"><strong>4.2.2</strong><span>Customizing the Application Class</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:10px"><a href="#applicationLifeCycle"><strong>4.2.3</strong><span>The Application LifeCycle</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:0px"><a href="#environments"><strong>4.3</strong><span>Environments</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:0px"><a href="#dataSource"><strong>4.4</strong><span>The DataSource</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:10px"><a href="#dataSourcesAndEnvironments"><strong>4.4.1</strong><span>DataSources and Environments</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:10px"><a href="#automaticDatabaseMigration"><strong>4.4.2</strong><span>Automatic Database Migration</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:10px"><a href="#transactionAwareDataSourceProxy"><strong>4.4.3</strong><span>Transaction-aware DataSource Proxy</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:10px"><a href="#databaseConsole"><strong>4.4.4</strong><span>Database Console</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:10px"><a href="#multipleDatasources"><strong>4.4.5</strong><span>Multiple Datasources</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:0px"><a href="#versioning"><strong>4.5</strong><span>Versioning</span></a> |
| </div> |
| |
| <div class="toc-item" style="margin-left:0px"><a href="#dependencyResolution"><strong>4.6</strong><span>Dependency Resolution</span></a> |
| </div> |
| |
| </div> |
| |
| |
| |
| <a name="3. Configuration"><!-- Legacy link --></a> |
| <h1 id="conf">4 Configuration</h1> |
| |
| <div class='contribute-btn'> |
| <button type='button' class='btn btn-default' onclick='window.location.href="https://github.com/grails/grails-doc/edit/6.2.x/src/en/guide/conf.adoc"'> |
| <i class='fa fa-pencil-square-o'></i> Improve this doc |
| </button> |
| </div> |
| |
| |
| <div class="paragraph"> |
| <p>It may seem odd that in a framework that embraces "convention-over-configuration" that we tackle this topic now. With Grails' default settings you can actually develop an application without doing any configuration whatsoever, as the quick start demonstrates, but it’s important to learn where and how to override the conventions when you need to. Later sections of the user guide will mention what configuration settings you can use, but not how to set them. The assumption is that you have at least read the first section of this chapter!</p> |
| </div> |
| |
| <a name="3.1 Basic Configuration"><!-- Legacy link --></a> |
| <h2 id="config">4.1 Basic Configuration</h2> |
| |
| <div class='contribute-btn'> |
| <button type='button' class='btn btn-default' onclick='window.location.href="https://github.com/grails/grails-doc/edit/6.2.x/src/en/guide/conf/config.adoc"'> |
| <i class='fa fa-pencil-square-o'></i> Improve this doc |
| </button> |
| </div> |
| |
| |
| <div class="paragraph"> |
| <p>Configuration in Grails is generally split across 2 areas: build configuration and runtime configuration.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Build configuration is generally done via Gradle and the <code>build.gradle</code> file. Runtime configuration is by default specified in YAML in the <code>grails-app/conf/application.yml</code> file.</p> |
| </div> |
| <div class="paragraph"> |
| <p>If you prefer to use Grails 2.0-style Groovy configuration then it is possible to specify configuration using Groovy’s <a href="http://docs.groovy-lang.org/latest/html/documentation/#_configslurper">ConfigSlurper</a> syntax. Two Groovy configuration files are available: <code>grails-app/conf/application.groovy</code> and <code>grails-app/conf/runtime.groovy</code>:</p> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Use <code>application.groovy</code> for configuration that doesn’t depend on application classes</p> |
| </li> |
| <li> |
| <p>Use <code>runtime.groovy</code> for configuration that does depend on application classes</p> |
| </li> |
| </ol> |
| </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>This separation is necessary because configuration values defined in <code>application.groovy</code> are available to the Grails CLI, which needs to be able to load <code>application.groovy</code> before the application has been compiled. References to application classes in <code>application.groovy</code> will cause an exception when these commands are executed by the CLI:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre>Error occurred running Grails CLI: |
| startup failed:script14738267015581837265078.groovy: 13: unable to resolve class com.foo.Bar</pre> |
| </div> |
| </div> |
| </td> |
| </tr> |
| </table> |
| </div> |
| <div class="paragraph"> |
| <p>For Groovy configuration the following variables are available to the configuration script:</p> |
| </div> |
| <table class="tableblock frame-all grid-all stretch"> |
| <colgroup> |
| <col style="width: 50%;"> |
| <col style="width: 50%;"> |
| </colgroup> |
| <thead> |
| <tr> |
| <th class="tableblock halign-left valign-top"><strong>Variable</strong></th> |
| <th class="tableblock halign-left valign-top"><strong>Description</strong></th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">userHome</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">Location of the home directory for the account that is running the Grails application.</p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">grailsHome</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">Location of the directory where you installed Grails. If the <code>GRAILS_HOME</code> environment variable is set, it is used.</p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">appName</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">The application name as it appears in build.gradle.</p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">appVersion</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">The application version as it appears in build.gradle.</p></td> |
| </tr> |
| </tbody> |
| </table> |
| <div class="paragraph"> |
| <p>For example:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy">my.tmp.dir = <span class="string"><span class="delimiter">"</span><span class="inline"><span class="inline-delimiter">${</span>userHome<span class="inline-delimiter">}</span></span><span class="content">/.grails/tmp</span><span class="delimiter">"</span></span></code></pre> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="_accessing_configuration_with_grailsapplication">Accessing Configuration with GrailsApplication</h3> |
| <div class="paragraph"> |
| <p>If you want to read runtime configuration settings, i.e. those defined in <code>application.yml</code>, use the <a href="https://grails.apache.org/docs/6.2.3/api/grails/core/GrailsApplication.html">grailsApplication</a> object, which is available as a variable in controllers and tag libraries:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy"><span class="type">class</span> <span class="class">MyController</span> { |
| <span class="keyword">def</span> <span class="function">hello</span>() { |
| <span class="keyword">def</span> recipient = grailsApplication.config.getProperty(<span class="string"><span class="delimiter">'</span><span class="content">foo.bar.hello</span><span class="delimiter">'</span></span>) |
| |
| render <span class="string"><span class="delimiter">"</span><span class="content">Hello </span><span class="inline"><span class="inline-delimiter">${</span>recipient<span class="inline-delimiter">}</span></span><span class="delimiter">"</span></span> |
| } |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>The <code>config</code> property of the <code>grailsApplication</code> object is an instance of the <a href="https://grails.apache.org/docs/6.2.3/api/grails/config/Config.html">Config</a> interface and provides a number of useful methods to read the configuration of the application.</p> |
| </div> |
| <div class="paragraph"> |
| <p>In particular, the <code>getProperty</code> method (seen above) is useful for efficiently retrieving configuration properties, while specifying the property type (the default type is String) and/or providing a default fallback value.</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy"><span class="type">class</span> <span class="class">MyController</span> { |
| |
| <span class="keyword">def</span> <span class="function">hello</span>(Recipient recipient) { |
| <span class="comment">//Retrieve Integer property 'foo.bar.max.hellos', otherwise use value of 5</span> |
| <span class="keyword">def</span> max = grailsApplication.config.getProperty(<span class="string"><span class="delimiter">'</span><span class="content">foo.bar.max.hellos</span><span class="delimiter">'</span></span>, <span class="predefined-type">Integer</span>, <span class="integer">5</span>) |
| |
| <span class="comment">//Retrieve property 'foo.bar.greeting' without specifying type (default is String), otherwise use value "Hello"</span> |
| <span class="keyword">def</span> greeting = grailsApplication.config.getProperty(<span class="string"><span class="delimiter">'</span><span class="content">foo.bar.greeting</span><span class="delimiter">'</span></span>, <span class="string"><span class="delimiter">"</span><span class="content">Hello</span><span class="delimiter">"</span></span>) |
| |
| <span class="keyword">def</span> message = (recipient.receivedHelloCount >= max) ? |
| <span class="string"><span class="delimiter">"</span><span class="content">Sorry, you've been greeted the max number of times</span><span class="delimiter">"</span></span> : <span class="string"><span class="delimiter">"</span><span class="inline"><span class="inline-delimiter">${</span>greeting<span class="inline-delimiter">}</span></span><span class="content">, </span><span class="inline"><span class="inline-delimiter">${</span>recipient<span class="inline-delimiter">}</span></span><span class="delimiter">"</span></span> |
| } |
| |
| render message |
| } |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>Notice that the <code>Config</code> instance is a merged configuration based on Spring’s <a href="https://docs.spring.io/spring/docs/5.3.39/javadoc-api/org/springframework/context/annotation/PropertySource.html">PropertySource</a> concept and reads configuration from the environment, system properties and the local application configuration merging them into a single object.</p> |
| </div> |
| <div class="paragraph"> |
| <p><code>GrailsApplication</code> can be easily injected into services and other Grails artifacts:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy"><span class="keyword">import</span> <span class="include">grails.core.*</span> |
| |
| <span class="type">class</span> <span class="class">MyService</span> { |
| GrailsApplication grailsApplication |
| |
| <span class="predefined-type">String</span> greeting() { |
| <span class="keyword">def</span> recipient = grailsApplication.config.getProperty(<span class="string"><span class="delimiter">'</span><span class="content">foo.bar.hello</span><span class="delimiter">'</span></span>) |
| <span class="keyword">return</span> <span class="string"><span class="delimiter">"</span><span class="content">Hello </span><span class="inline"><span class="inline-delimiter">${</span>recipient<span class="inline-delimiter">}</span></span><span class="delimiter">"</span></span> |
| } |
| }</code></pre> |
| </div> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="_grailsconfigurationaware_interface">GrailsConfigurationAware Interface</h3> |
| <div class="paragraph"> |
| <p>Accessing configuration dynamically at runtime can have a small effect on application performance. An alternative approach is to implement the <a href="https://grails.apache.org/docs/6.2.3/api/grails/core/support/GrailsConfigurationAware.html">GrailsConfigurationAware</a> interface, which provides a <code>setConfiguration</code> method that accepts the application configuration as a parameter when the class is initialized. You can then assign relevant configuration properties to instance properties on the class for later usage.</p> |
| </div> |
| <div class="paragraph"> |
| <p>The <code>Config</code> instance has the same properties and usage as the injected <code>GrailsApplication</code> config object. Here is the service class from the previous example, using <code>GrailsConfigurationAware</code> instead of injecting <code>GrailsApplication</code>:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy"><span class="keyword">import</span> <span class="include">grails.core.support.GrailsConfigurationAware</span> |
| |
| <span class="type">class</span> <span class="class">MyService</span> <span class="directive">implements</span> GrailsConfigurationAware { |
| |
| <span class="predefined-type">String</span> recipient |
| |
| <span class="predefined-type">String</span> greeting() { |
| <span class="keyword">return</span> <span class="string"><span class="delimiter">"</span><span class="content">Hello </span><span class="inline"><span class="inline-delimiter">${</span>recipient<span class="inline-delimiter">}</span></span><span class="delimiter">"</span></span> |
| } |
| |
| <span class="type">void</span> setConfiguration(Config config) { |
| recipient = config.getProperty(<span class="string"><span class="delimiter">'</span><span class="content">foo.bar.hello</span><span class="delimiter">'</span></span>) |
| } |
| |
| }</code></pre> |
| </div> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="_spring_value_annotation">Spring Value Annotation</h3> |
| <div class="paragraph"> |
| <p>You can use Spring’s <a href="https://docs.spring.io/spring/docs/5.3.39/javadoc-api/org/springframework/beans/factory/annotation/Value.html">Value</a> annotation to inject configuration values:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy"><span class="keyword">import</span> <span class="include">org.springframework.beans.factory.annotation.*</span> |
| |
| <span class="type">class</span> <span class="class">MyController</span> { |
| <span class="annotation">@Value</span>(<span class="string"><span class="delimiter">'</span><span class="content">${foo.bar.hello}</span><span class="delimiter">'</span></span>) |
| <span class="predefined-type">String</span> recipient |
| |
| <span class="keyword">def</span> <span class="function">hello</span>() { |
| render <span class="string"><span class="delimiter">"</span><span class="content">Hello </span><span class="inline"><span class="inline-delimiter">${</span>recipient<span class="inline-delimiter">}</span></span><span class="delimiter">"</span></span> |
| } |
| }</code></pre> |
| </div> |
| </div> |
| <div class="admonitionblock note"> |
| <table> |
| <tr> |
| <td class="icon"> |
| <i class="fa icon-note" title="Note"></i> |
| </td> |
| <td class="content"> |
| In Groovy code you must use single quotes around the string for the value of the <code>Value</code> annotation otherwise it is interpreted as a GString not a Spring expression. |
| </td> |
| </tr> |
| </table> |
| </div> |
| <div class="paragraph"> |
| <p>As you can see, when accessing configuration settings you use the same dot notation as when you define them.</p> |
| </div> |
| </div> |
| |
| |
| <h2 id="ymlOptions">4.1.1 Options for the YML format Config</h2> |
| |
| <div class='contribute-btn'> |
| <button type='button' class='btn btn-default' onclick='window.location.href="https://github.com/grails/grails-doc/edit/6.2.x/src/en/guide/conf/config/ymlOptions.adoc"'> |
| <i class='fa fa-pencil-square-o'></i> Improve this doc |
| </button> |
| </div> |
| |
| |
| <div class="paragraph"> |
| <p>The <code>application.yml</code> file was introduced in Grails 3.0, and YAML is now the preferred format for configuration files.</p> |
| </div> |
| <div class="sect2"> |
| <h3 id="_using_system_properties_command_line_arguments">Using system properties / command line arguments</h3> |
| <div class="paragraph"> |
| <p>Suppose you are using the <code>JDBC_CONNECTION_STRING</code> command line argument and you want to access the same in the yml file then it can be done in the following manner:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="yaml"><span class="key">production</span>: |
| <span class="key">dataSource</span>: |
| <span class="key">url</span>: <span class="string"><span class="content">'${JDBC_CONNECTION_STRING}'</span></span></code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>Similarly system arguments can be accessed.</p> |
| </div> |
| <div class="paragraph"> |
| <p>You will need to have this in <code>build.gradle</code> to modify the <code>bootRun</code> target if <code>grails run-app</code> or <code>./gradlew bootRun</code> is used to start the application</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy">bootRun { |
| systemProperties = <span class="predefined-type">System</span>.properties |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>For testing the following will need to change the <code>test</code> task as follows</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy">test { |
| systemProperties = <span class="predefined-type">System</span>.properties |
| }</code></pre> |
| </div> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="_external_configuration">External configuration</h3> |
| <div class="paragraph"> |
| <p>Grails will read <code>application.(properties|yml)</code> from the <code>./config</code> or the current directory by default. |
| As Grails is a SpringBoot configuration options are available as well, for documentation please consult: <a href="https://docs.spring.io/spring-boot/docs/2.7.18/reference/html/features.html#features.external-config.files" class="bare">https://docs.spring.io/spring-boot/docs/2.7.18/reference/html/features.html#features.external-config.files</a></p> |
| </div> |
| </div> |
| |
| <a name="3.1.1 Built in options"><!-- Legacy link --></a> |
| <h2 id="builtInOptions">4.1.2 Built in options</h2> |
| |
| <div class='contribute-btn'> |
| <button type='button' class='btn btn-default' onclick='window.location.href="https://github.com/grails/grails-doc/edit/6.2.x/src/en/guide/conf/config/builtInOptions.adoc"'> |
| <i class='fa fa-pencil-square-o'></i> Improve this doc |
| </button> |
| </div> |
| |
| |
| <div class="paragraph"> |
| <p>Grails has a set of core settings that are worth knowing about. Their defaults are suitable for most projects, but it’s important to understand what they do because you may need one or more of them later.</p> |
| </div> |
| <div class="sect2"> |
| <h3 id="_runtime_settings">Runtime settings</h3> |
| <div class="paragraph"> |
| <p>On the runtime front, i.e. <code>grails-app/conf/application.yml</code>, there are quite a few more core settings:</p> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p><code>grails.enable.native2ascii</code> - Set this to false if you do not require native2ascii conversion of Grails i18n properties files (default: true).</p> |
| </li> |
| <li> |
| <p><code>grails.views.default.codec</code> - Sets the default encoding regime for GSPs - can be one of 'none', 'html', or 'base64' (default: 'none'). To reduce risk of XSS attacks, set this to 'html'.</p> |
| </li> |
| <li> |
| <p><code>grails.views.gsp.encoding</code> - The file encoding used for GSP source files (default: 'utf-8').</p> |
| </li> |
| <li> |
| <p><code>grails.mime.file.extensions</code> - Whether to use the file extension to dictate the mime type in <a href="theWebLayer.html#contentNegotiation">Content Negotiation</a> (default: true).</p> |
| </li> |
| <li> |
| <p><code>grails.mime.types</code> - A map of supported mime types used for <a href="theWebLayer.html#contentNegotiation">Content Negotiation</a>.</p> |
| </li> |
| <li> |
| <p><code>grails.serverURL</code> - A string specifying the server URL portion of absolute links, including server name e.g. grails.serverURL="http://my.yourportal.com". See <a href="https://gsp.grails.org/6.2.4/ref/Tags/createLink.html">createLink</a>. Also used by redirects.</p> |
| </li> |
| <li> |
| <p><code>grails.views.gsp.sitemesh.preprocess</code> - Determines whether SiteMesh preprocessing happens. Disabling this slows down page rendering, but if you need SiteMesh to parse the generated HTML from a GSP view then disabling it is the right option. Don’t worry if you don’t understand this advanced property: leave it set to true.</p> |
| </li> |
| <li> |
| <p><code>grails.reload.excludes</code> and <code>grails.reload.includes</code> - Configuring these directives determines the reload behavior for project specific source files. Each directive takes a list of strings that are the class names for project source files that should be excluded from reloading behavior or included accordingly when running the application in development with the <code>bootRun</code> task. If the <code>grails.reload.includes</code> directive is configured, then only the classes in that list will be reloaded.</p> |
| </li> |
| </ul> |
| </div> |
| </div> |
| |
| <a name="3.1.2 Logging"><!-- Legacy link --></a> |
| <h2 id="logging">4.1.3 Logging</h2> |
| |
| <div class='contribute-btn'> |
| <button type='button' class='btn btn-default' onclick='window.location.href="https://github.com/grails/grails-doc/edit/6.2.x/src/en/guide/conf/config/logging.adoc"'> |
| <i class='fa fa-pencil-square-o'></i> Improve this doc |
| </button> |
| </div> |
| |
| |
| <div class="paragraph"> |
| <p>Since Grails 3.0, logging is handled by the <a href="http://logback.qos.ch">Logback logging framework</a> and can be configured with the <code>grails-app/conf/logback.xml</code> file.</p> |
| </div> |
| <div class="admonitionblock note"> |
| <table> |
| <tr> |
| <td class="icon"> |
| <i class="fa icon-note" title="Note"></i> |
| </td> |
| <td class="content"> |
| Since Grails 5.1.2 support for groovy configuration (<code>grails-app/conf/logback.groovy</code>) has been removed (by logback 1.2.9). It is possible to add back groovy configuration by adding the <a href="https://github.com/virtualdogbert/logback-groovy-config">logback-groovy-config</a> library to your project. |
| </td> |
| </tr> |
| </table> |
| </div> |
| <div class="paragraph"> |
| <p>For more information on configuring logging refer to the <a href="http://logback.qos.ch/manual/groovy.html">Logback documentation</a> on the subject.</p> |
| </div> |
| |
| |
| <h2 id="loggerName">4.1.3.1 Logger Names</h2> |
| |
| <div class='contribute-btn'> |
| <button type='button' class='btn btn-default' onclick='window.location.href="https://github.com/grails/grails-doc/edit/6.2.x/src/en/guide/conf/config/logging/loggerName.adoc"'> |
| <i class='fa fa-pencil-square-o'></i> Improve this doc |
| </button> |
| </div> |
| |
| |
| <div class="paragraph"> |
| <p>Grails artifacts (controllers, services …​) get injected a <code>log</code> property automatically.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Prior to Grails 3.3.0, the name of the |
| logger for Grails Artifact followed the convention <code>grails.app.<type>.<className></code>, where type is the |
| type of the artifact, for example, <code>controllers</code> or <code>services</code>, and <code>className</code> is the fully |
| qualified name of the artifact.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Grails 3.3.x simplifies logger names. The next examples illustrate the changes:</p> |
| </div> |
| <div class="paragraph"> |
| <p><code>BookController.groovy</code> located at <code>grails-app/controllers/com/company</code> NOT annotated with <code><a href="http://docs.groovy-lang.org/latest/html/gapi/groovy/util/logging/Slf4j.html">@Slf4j</a></code></p> |
| </div> |
| <table class="tableblock frame-all grid-all stretch"> |
| <colgroup> |
| <col style="width: 50%;"> |
| <col style="width: 50%;"> |
| </colgroup> |
| <tbody> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>Logger Name (Grails 3.3.x or higher)</strong></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>Logger Name (Grails 3.2.x or lower)</strong></p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>com.company.BookController</code></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>grails.app.controllers.com.company.BookController</code></p></td> |
| </tr> |
| </tbody> |
| </table> |
| <div class="paragraph"> |
| <p><code>BookController.groovy</code> located at <code>grails-app/controllers/com/company</code> annotated with <code><a href="http://docs.groovy-lang.org/latest/html/gapi/groovy/util/logging/Slf4j.html">@Slf4j</a></code></p> |
| </div> |
| <table class="tableblock frame-all grid-all stretch"> |
| <colgroup> |
| <col style="width: 50%;"> |
| <col style="width: 50%;"> |
| </colgroup> |
| <tbody> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>Logger Name (Grails 3.3.x or higher)</strong></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>Logger Name (Grails 3.2.x or lower)</strong></p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>com.company.BookController</code></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>com.company.BookController</code></p></td> |
| </tr> |
| </tbody> |
| </table> |
| <div class="paragraph"> |
| <p><code>BookService.groovy</code> located at <code>grails-app/services/com/company</code> NOT annotated with <code><a href="http://docs.groovy-lang.org/latest/html/gapi/groovy/util/logging/Slf4j.html">@Slf4j</a></code></p> |
| </div> |
| <table class="tableblock frame-all grid-all stretch"> |
| <colgroup> |
| <col style="width: 50%;"> |
| <col style="width: 50%;"> |
| </colgroup> |
| <tbody> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>Logger Name (Grails 3.3.x or higher)</strong></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>Logger Name (Grails 3.2.x or lower)</strong></p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>com.company.BookService</code></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>grails.app.services.com.company.BookService</code></p></td> |
| </tr> |
| </tbody> |
| </table> |
| <div class="paragraph"> |
| <p><code>BookService.groovy</code> located at <code>grails-app/services/com/company</code> annotated with <code><a href="http://docs.groovy-lang.org/latest/html/gapi/groovy/util/logging/Slf4j.html">@Slf4j</a></code></p> |
| </div> |
| <table class="tableblock frame-all grid-all stretch"> |
| <colgroup> |
| <col style="width: 50%;"> |
| <col style="width: 50%;"> |
| </colgroup> |
| <tbody> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>Logger Name (Grails 3.3.x or higher)</strong></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>Logger Name (Grails 3.2.x or lower)</strong></p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>com.company.BookService</code></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>com.company.BookService</code></p></td> |
| </tr> |
| </tbody> |
| </table> |
| <div class="paragraph"> |
| <p><code>BookDetail.groovy</code> located at <code>src/main/groovy/com/company</code> annotated with <code><a href="http://docs.groovy-lang.org/latest/html/gapi/groovy/util/logging/Slf4j.html">@Slf4j</a></code></p> |
| </div> |
| <table class="tableblock frame-all grid-all stretch"> |
| <colgroup> |
| <col style="width: 50%;"> |
| <col style="width: 50%;"> |
| </colgroup> |
| <tbody> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>Logger Name (Grails 3.3.x or higher)</strong></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>Logger Name (Grails 3.2.x or lower)</strong></p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>com.company.BookDetail</code></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>com.company.BookDetail</code></p></td> |
| </tr> |
| </tbody> |
| </table> |
| |
| |
| <h2 id="maskingRequestParametersFromStacktraceLogs">4.1.3.2 Masking Request Parameters From Stacktrace Logs</h2> |
| |
| <div class='contribute-btn'> |
| <button type='button' class='btn btn-default' onclick='window.location.href="https://github.com/grails/grails-doc/edit/6.2.x/src/en/guide/conf/config/logging/maskingRequestParametersFromStacktraceLogs.adoc"'> |
| <i class='fa fa-pencil-square-o'></i> Improve this doc |
| </button> |
| </div> |
| |
| |
| <div class="paragraph"> |
| <p>When Grails logs a stacktrace, the log message may include the names and values of all of the request parameters for the current request. |
| To mask out the values of secure request parameters, specify the parameter names in the <code>grails.exceptionresolver.params.exclude</code> config property:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="title">grails-app/conf/application.yml</div> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="yaml"><span class="key">grails</span>: |
| <span class="key">exceptionresolver</span>: |
| <span class="key">params</span>: |
| <span class="key">exclude</span>: |
| - <span class="string"><span class="content">password</span></span> |
| - <span class="string"><span class="content">creditCard</span></span></code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>Request parameter logging may be turned off altogether by setting the <code>grails.exceptionresolver.logRequestParameters</code> |
| config property to false. The default value is true when the application is running in DEVELOPMENT mode and false for all other |
| environments.</p> |
| </div> |
| <div class="listingblock"> |
| <div class="title">grails-app/conf/application.yml</div> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="yaml"><span class="key">grails</span>: |
| <span class="key">exceptionresolver</span>: |
| <span class="key">logRequestParameters</span>: <span class="string"><span class="content">false</span></span></code></pre> |
| </div> |
| </div> |
| |
| |
| <h2 id="externalLoggingConfiguration">4.1.3.3 External Configuration File</h2> |
| |
| <div class='contribute-btn'> |
| <button type='button' class='btn btn-default' onclick='window.location.href="https://github.com/grails/grails-doc/edit/6.2.x/src/en/guide/conf/config/logging/externalLoggingConfiguration.adoc"'> |
| <i class='fa fa-pencil-square-o'></i> Improve this doc |
| </button> |
| </div> |
| |
| |
| <div class="paragraph"> |
| <p>If you set the configuration property <code>logging.config</code>, you can instruct <code>Logback</code> to use an external configuration file.</p> |
| </div> |
| <div class="listingblock"> |
| <div class="title">grails-app/conf/application.yml</div> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="yaml"><span class="key">logging</span>: |
| <span class="key">config</span>: <span class="string"><span class="content">/Users/me/config/logback.groovy</span></span></code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>Alternatively, you can supply the configuration file location with a system property:</p> |
| </div> |
| <div class="paragraph"> |
| <p><code>$ ./gradlew -Dlogging.config=/Users/me/config/logback.groovy bootRun</code></p> |
| </div> |
| <div class="paragraph"> |
| <p>Or, you could use an environment variable:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="bash">$ export LOGGING_CONFIG=/Users/me/config/logback.groovy |
| $ ./gradlew bootRun</code></pre> |
| </div> |
| </div> |
| |
| <a name="3.1.3 GORM"><!-- Legacy link --></a> |
| <h2 id="configGORM">4.1.4 GORM</h2> |
| |
| <div class='contribute-btn'> |
| <button type='button' class='btn btn-default' onclick='window.location.href="https://github.com/grails/grails-doc/edit/6.2.x/src/en/guide/conf/config/configGORM.adoc"'> |
| <i class='fa fa-pencil-square-o'></i> Improve this doc |
| </button> |
| </div> |
| |
| |
| <div class="paragraph"> |
| <p>Grails provides the following GORM configuration options:</p> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p><code>grails.gorm.failOnError</code> - If set to <code>true</code>, causes the <code>save()</code> method on domain classes to throw a <code>grails.validation.ValidationException</code> if <a href="validation.html">validation</a> fails during a save. This option may also be assigned a list of Strings representing package names. If the value is a list of Strings then the failOnError behavior will only be applied to domain classes in those packages (including sub-packages). See the <a href="../ref/Domain%20Classes/save.html">save</a> method docs for more information.</p> |
| </li> |
| </ul> |
| </div> |
| <div class="paragraph"> |
| <p>For example, to enable failOnError for all domain classes:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="yaml"><span class="key">grails</span>: |
| <span class="key">gorm</span>: |
| <span class="key">failOnError</span>: <span class="string"><span class="content">true</span></span></code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>and to enable failOnError for domain classes by package:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="yaml"><span class="key">grails</span>: |
| <span class="key">gorm</span>: |
| <span class="key">failOnError</span>: |
| - <span class="string"><span class="content">com.companyname.somepackage</span></span> |
| - <span class="string"><span class="content">com.companyname.someotherpackage</span></span></code></pre> |
| </div> |
| </div> |
| |
| |
| <h2 id="proxyConfig">4.1.5 Configuring an HTTP proxy</h2> |
| |
| <div class='contribute-btn'> |
| <button type='button' class='btn btn-default' onclick='window.location.href="https://github.com/grails/grails-doc/edit/6.2.x/src/en/guide/conf/config/proxyConfig.adoc"'> |
| <i class='fa fa-pencil-square-o'></i> Improve this doc |
| </button> |
| </div> |
| |
| |
| <div class="paragraph"> |
| <p>To setup Grails to use an HTTP proxy there are two steps. Firstly you need to configure the <code>grails</code> CLI to be aware of the proxy if you wish to use it to create applications and so on. This can be done using the <code>GRAILS_OPTS</code> environment variable, for example on Unix systems:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="bash">export GRAILS_OPTS="-Dhttps.proxyHost=127.0.0.1 -Dhttps.proxyPort=3128 -Dhttp.proxyUser=test -Dhttp.proxyPassword=test"</code></pre> |
| </div> |
| </div> |
| <div class="admonitionblock note"> |
| <table> |
| <tr> |
| <td class="icon"> |
| <i class="fa icon-note" title="Note"></i> |
| </td> |
| <td class="content"> |
| The default profile repository is resolved over HTTPS so <code>https.proxyPort</code> and <code>https.proxyUser</code> are used, however the username and password are specified with <code>http.proxyUser</code> and <code>http.proxyPassword</code> |
| </td> |
| </tr> |
| </table> |
| </div> |
| <div class="paragraph"> |
| <p>For Windows systems the environment variable can be configured under <code>My Computer/Advanced/Environment Variables</code>.</p> |
| </div> |
| <div class="paragraph"> |
| <p>With this configuration in place the <code>grails</code> command can connect and authenticate via a proxy.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Secondly, since Grails uses Gradle as the build system, you need to configure Gradle to authenticate via the proxy. For instructions on how to do this see the <a href="https://docs.gradle.org/current/userguide/build_environment.html#sec:accessing_the_web_via_a_proxy">Gradle user guide section on the topic</a>.</p> |
| </div> |
| |
| |
| <h2 id="applicationClass">4.2 The Application Class</h2> |
| |
| <div class='contribute-btn'> |
| <button type='button' class='btn btn-default' onclick='window.location.href="https://github.com/grails/grails-doc/edit/6.2.x/src/en/guide/conf/applicationClass.adoc"'> |
| <i class='fa fa-pencil-square-o'></i> Improve this doc |
| </button> |
| </div> |
| |
| |
| <div class="paragraph"> |
| <p>Every new Grails application features an <code>Application</code> class within the <code>grails-app/init</code> directory.</p> |
| </div> |
| <div class="paragraph"> |
| <p>The <code>Application</code> class subclasses the <a href="https://grails.apache.org/docs/6.2.3/api/grails/boot/config/GrailsAutoConfiguration.html">GrailsAutoConfiguration</a> class and features a <code>static void main</code> method, meaning it can be run as a regular application.</p> |
| </div> |
| |
| |
| <h2 id="executing">4.2.1 Executing the Application Class</h2> |
| |
| <div class='contribute-btn'> |
| <button type='button' class='btn btn-default' onclick='window.location.href="https://github.com/grails/grails-doc/edit/6.2.x/src/en/guide/conf/applicationClass/executing.adoc"'> |
| <i class='fa fa-pencil-square-o'></i> Improve this doc |
| </button> |
| </div> |
| |
| |
| <div class="paragraph"> |
| <p>There are several ways to execute the <code>Application</code> class, if you are using an IDE then you can simply right click on the class and run it directly from your IDE which will start your Grails application.</p> |
| </div> |
| <div class="paragraph"> |
| <p>This is also useful for debugging since you can debug directly from the IDE without having to connect a remote debugger when using the <code>run-app --debug-jvm</code> or <code>./gradlew bootRun --debug-jvm</code> command from the command line.</p> |
| </div> |
| <div class="paragraph"> |
| <p>You can also package your application into a runnable WAR file, for example:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="bash">$ grails package |
| $ java -jar build/libs/myapp-0.1.war</code></pre> |
| </div> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="bash">$ ./gradlew bootWar |
| $ java -jar build/libs/myapp-0.1.war</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>This is useful if you plan to deploy your application using a container-less approach.</p> |
| </div> |
| |
| |
| <h2 id="customizing">4.2.2 Customizing the Application Class</h2> |
| |
| <div class='contribute-btn'> |
| <button type='button' class='btn btn-default' onclick='window.location.href="https://github.com/grails/grails-doc/edit/6.2.x/src/en/guide/conf/applicationClass/customizing.adoc"'> |
| <i class='fa fa-pencil-square-o'></i> Improve this doc |
| </button> |
| </div> |
| |
| |
| <div class="paragraph"> |
| <p>There are several ways in which you can customize the <code>Application</code> class.</p> |
| </div> |
| <div class="sect2"> |
| <h3 id="_customizing_scanning">Customizing Scanning</h3> |
| <div class="paragraph"> |
| <p>By default Grails will scan all known source directories for controllers, domain class etc., however if there are packages in other JAR files you wish to scan you can do so by overriding the <code>packageNames()</code> method of the <code>Application</code> class:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy"><span class="type">class</span> <span class="class">Application</span> <span class="directive">extends</span> GrailsAutoConfiguration { |
| <span class="annotation">@Override</span> |
| <span class="predefined-type">Collection</span><<span class="predefined-type">String</span>> packageNames() { |
| <span class="local-variable">super</span>.packageNames() + [<span class="string"><span class="delimiter">'</span><span class="content">my.additional.package</span><span class="delimiter">'</span></span>] |
| } |
| |
| ... |
| }</code></pre> |
| </div> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="_registering_additional_beans">Registering Additional Beans</h3> |
| <div class="paragraph"> |
| <p>The <code>Application</code> class can also be used as a source for Spring bean definitions, simply define a method annotated with the <a href="https://docs.spring.io/spring/docs/5.3.39/javadoc-api/org/springframework/context/annotation/Bean.html">Bean</a> and the returned object will become a Spring bean. The name of the method is used as the bean name:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy"><span class="type">class</span> <span class="class">Application</span> <span class="directive">extends</span> GrailsAutoConfiguration { |
| <span class="annotation">@Bean</span> |
| MyType myBean() { |
| <span class="keyword">return</span> <span class="keyword">new</span> MyType() |
| } |
| |
| ... |
| }</code></pre> |
| </div> |
| </div> |
| </div> |
| |
| |
| <h2 id="applicationLifeCycle">4.2.3 The Application LifeCycle</h2> |
| |
| <div class='contribute-btn'> |
| <button type='button' class='btn btn-default' onclick='window.location.href="https://github.com/grails/grails-doc/edit/6.2.x/src/en/guide/conf/applicationClass/applicationLifeCycle.adoc"'> |
| <i class='fa fa-pencil-square-o'></i> Improve this doc |
| </button> |
| </div> |
| |
| |
| <div class="paragraph"> |
| <p>The <code>Application</code> class also implements the <a href="https://grails.apache.org/docs/6.2.3/api/grails/core/GrailsApplicationLifeCycle.html">GrailsApplicationLifeCycle</a> interface which all plugins implement.</p> |
| </div> |
| <div class="paragraph"> |
| <p>This means that the <code>Application</code> class can be used to perform the same functions as a plugin. You can override the <a href="plugins.html#hookingIntoRuntimeConfiguration">regular plugins hooks</a> such as <code>doWithSpring</code>, <code>doWithApplicationContext</code> and so on by overriding the appropriate method:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy"><span class="type">class</span> <span class="class">Application</span> <span class="directive">extends</span> GrailsAutoConfiguration { |
| <span class="annotation">@Override</span> |
| Closure doWithSpring() { |
| {-> |
| mySpringBean(MyType) |
| } |
| } |
| |
| ... |
| }</code></pre> |
| </div> |
| </div> |
| |
| <a name="3.2 Environments"><!-- Legacy link --></a> |
| <h2 id="environments">4.3 Environments</h2> |
| |
| <div class='contribute-btn'> |
| <button type='button' class='btn btn-default' onclick='window.location.href="https://github.com/grails/grails-doc/edit/6.2.x/src/en/guide/conf/environments.adoc"'> |
| <i class='fa fa-pencil-square-o'></i> Improve this doc |
| </button> |
| </div> |
| |
| |
| <div class="sect2"> |
| <h3 id="_per_environment_configuration">Per Environment Configuration</h3> |
| <div class="paragraph"> |
| <p>Grails supports the concept of per environment configuration. The <code>application.yml</code> and <code>application.groovy</code> files in the <code>grails-app/conf</code> directory can use per-environment configuration using either YAML or the syntax provided by <a href="http://docs.groovy-lang.org/latest/html/documentation/#_configslurper">ConfigSlurper</a>. As an example consider the following default <code>application.yml</code> definition provided by Grails:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="yaml"><span class="key">environments</span>: |
| <span class="key">development</span>: |
| <span class="key">dataSource</span>: |
| <span class="key">dbCreate</span>: <span class="string"><span class="content">create-drop</span></span> |
| <span class="key">url</span>: <span class="string"><span class="content">jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE</span></span> |
| <span class="key">test</span>: |
| <span class="key">dataSource</span>: |
| <span class="key">dbCreate</span>: <span class="string"><span class="content">update</span></span> |
| <span class="key">url</span>: <span class="string"><span class="content">jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE</span></span> |
| <span class="key">production</span>: |
| <span class="key">dataSource</span>: |
| <span class="key">dbCreate</span>: <span class="string"><span class="content">update</span></span> |
| <span class="key">url</span>: <span class="string"><span class="content">jdbc:h2:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE</span></span> |
| <span class="key">properties</span>: |
| <span class="key">jmxEnabled</span>: <span class="string"><span class="content">true</span></span> |
| <span class="key">initialSize</span>: <span class="string"><span class="content">5</span></span> |
| <span class="error">...</span></code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>The above can be expressed in Groovy syntax in <code>application.groovy</code> as follows:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy">dataSource { |
| pooled = <span class="predefined-constant">false</span> |
| driverClassName = <span class="string"><span class="delimiter">"</span><span class="content">org.h2.Driver</span><span class="delimiter">"</span></span> |
| username = <span class="string"><span class="delimiter">"</span><span class="content">sa</span><span class="delimiter">"</span></span> |
| password = <span class="string"><span class="delimiter">"</span><span class="delimiter">"</span></span> |
| } |
| environments { |
| development { |
| dataSource { |
| dbCreate = <span class="string"><span class="delimiter">"</span><span class="content">create-drop</span><span class="delimiter">"</span></span> |
| url = <span class="string"><span class="delimiter">"</span><span class="content">jdbc:h2:mem:devDb</span><span class="delimiter">"</span></span> |
| } |
| } |
| test { |
| dataSource { |
| dbCreate = <span class="string"><span class="delimiter">"</span><span class="content">update</span><span class="delimiter">"</span></span> |
| url = <span class="string"><span class="delimiter">"</span><span class="content">jdbc:h2:mem:testDb</span><span class="delimiter">"</span></span> |
| } |
| } |
| production { |
| dataSource { |
| dbCreate = <span class="string"><span class="delimiter">"</span><span class="content">update</span><span class="delimiter">"</span></span> |
| url = <span class="string"><span class="delimiter">"</span><span class="content">jdbc:h2:prodDb</span><span class="delimiter">"</span></span> |
| properties { |
| jmxEnabled = <span class="predefined-constant">true</span> |
| initialSize = <span class="integer">5</span> |
| } |
| } |
| } |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>Notice how the common configuration is provided at the top level and then an <code>environments</code> block specifies per environment settings for the <code>dbCreate</code> and <code>url</code> properties of the <code>DataSource</code>.</p> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="_packaging_and_running_for_different_environments">Packaging and Running for Different Environments</h3> |
| <div class="paragraph"> |
| <p>Grails' <a href="commandLine.html">command line</a> has built in capabilities to execute any command within the context of a specific environment. The format is:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="bash">grails <<environment>> <<command name>></code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>In addition, there are 3 preset environments known to Grails: <code>dev</code>, <code>prod</code>, and <code>test</code> for <code>development</code>, <code>production</code> and <code>test</code>. For example to create a WAR for the <code>test</code> environment you would run:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="bash">grails test war</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>To target other environments you can pass a <code>grails.env</code> variable to any command:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="bash">grails -Dgrails.env=UAT run-app</code></pre> |
| </div> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="bash">./gradlew bootRun -Dgrails.env=UAT</code></pre> |
| </div> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="_programmatic_environment_detection">Programmatic Environment Detection</h3> |
| <div class="paragraph"> |
| <p>Within your code, such as in a Gant script or a bootstrap class you can detect the environment using the <a href="https://grails.apache.org/docs/6.2.3/api/grails/util/Environment.html">Environment</a> class:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy"><span class="keyword">import</span> <span class="include">grails.util.Environment</span> |
| |
| ... |
| |
| switch (Environment.current) { |
| <span class="keyword">case</span> Environment.DEVELOPMENT: |
| configureForDevelopment() |
| <span class="keyword">break</span> |
| <span class="keyword">case</span> Environment.PRODUCTION: |
| configureForProduction() |
| <span class="keyword">break</span> |
| }</code></pre> |
| </div> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="_per_environment_bootstrapping">Per Environment Bootstrapping</h3> |
| <div class="paragraph"> |
| <p>It’s often desirable to run code when your application starts up on a per-environment basis. To do so you can use the <code>grails-app/init/BootStrap.groovy</code> file’s support for per-environment execution:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy"><span class="keyword">def</span> init = { ServletContext ctx -> |
| environments { |
| production { |
| ctx.setAttribute(<span class="string"><span class="delimiter">"</span><span class="content">env</span><span class="delimiter">"</span></span>, <span class="string"><span class="delimiter">"</span><span class="content">prod</span><span class="delimiter">"</span></span>) |
| } |
| development { |
| ctx.setAttribute(<span class="string"><span class="delimiter">"</span><span class="content">env</span><span class="delimiter">"</span></span>, <span class="string"><span class="delimiter">"</span><span class="content">dev</span><span class="delimiter">"</span></span>) |
| } |
| } |
| ctx.setAttribute(<span class="string"><span class="delimiter">"</span><span class="content">foo</span><span class="delimiter">"</span></span>, <span class="string"><span class="delimiter">"</span><span class="content">bar</span><span class="delimiter">"</span></span>) |
| }</code></pre> |
| </div> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="_generic_per_environment_execution">Generic Per Environment Execution</h3> |
| <div class="paragraph"> |
| <p>The previous <code>BootStrap</code> example uses the <code>grails.util.Environment</code> class internally to execute. You can also use this class yourself to execute your own environment specific logic:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy">Environment.executeForCurrentEnvironment { |
| production { |
| <span class="comment">// do something in production</span> |
| } |
| development { |
| <span class="comment">// do something only in development</span> |
| } |
| }</code></pre> |
| </div> |
| </div> |
| </div> |
| |
| <a name="3.3 The DataSource"><!-- Legacy link --></a> |
| <h2 id="dataSource">4.4 The DataSource</h2> |
| |
| <div class='contribute-btn'> |
| <button type='button' class='btn btn-default' onclick='window.location.href="https://github.com/grails/grails-doc/edit/6.2.x/src/en/guide/conf/dataSource.adoc"'> |
| <i class='fa fa-pencil-square-o'></i> Improve this doc |
| </button> |
| </div> |
| |
| |
| <div class="paragraph"> |
| <p>Since Grails is built on Java technology setting up a data source requires some knowledge of JDBC (the technology that stands for Java Database Connectivity).</p> |
| </div> |
| <div class="paragraph"> |
| <p>If you use a database other than H2 you need a JDBC driver. For example for MySQL you would need <a href="http://www.mysql.com/downloads/connector/j/">Connector/J</a>.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Drivers typically come in the form of a JAR archive. It’s best to use the dependency resolution to resolve the jar if it’s available in a Maven repository, for example you could add a dependency for the MySQL driver like this:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy">dependencies { |
| runtimeOnly <span class="string"><span class="delimiter">'</span><span class="content">mysql:mysql-connector-java:5.1.29</span><span class="delimiter">'</span></span> |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>Once you have the JAR resolved you need to get familiar with how Grails manages its database configuration. The configuration can be maintained in either <code>grails-app/conf/application.groovy</code> or <code>grails-app/conf/application.yml</code>. These files contain the dataSource definition which includes the following settings:</p> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p><code>driverClassName</code> - The class name of the JDBC driver</p> |
| </li> |
| <li> |
| <p><code>username</code> - The username used to establish a JDBC connection</p> |
| </li> |
| <li> |
| <p><code>password</code> - The password used to establish a JDBC connection</p> |
| </li> |
| <li> |
| <p><code>url</code> - The JDBC URL of the database</p> |
| </li> |
| <li> |
| <p><code>dbCreate</code> - Whether to auto-generate the database from the domain model - one of 'create-drop', 'create', 'update', 'validate', or 'none'</p> |
| </li> |
| <li> |
| <p><code>pooled</code> - Whether to use a pool of connections (defaults to true)</p> |
| </li> |
| <li> |
| <p><code>logSql</code> - Enable SQL logging to stdout</p> |
| </li> |
| <li> |
| <p><code>formatSql</code> - Format logged SQL</p> |
| </li> |
| <li> |
| <p><code>dialect</code> - A String or Class that represents the Hibernate dialect used to communicate with the database. See the <a href="http://docs.jboss.org/hibernate/core/3.6/javadocs/org/hibernate/dialect/package-summary.html">org.hibernate.dialect</a> package for available dialects.</p> |
| </li> |
| <li> |
| <p><code>readOnly</code> - If <code>true</code> makes the DataSource read-only, which results in the connection pool calling <code>setReadOnly(true)</code> on each <code>Connection</code></p> |
| </li> |
| <li> |
| <p><code>transactional</code> - If <code>false</code> leaves the DataSource’s transactionManager bean outside the chained BE1PC transaction manager implementation. This only applies to additional datasources.</p> |
| </li> |
| <li> |
| <p><code>persistenceInterceptor</code> - The default datasource is automatically wired up to the persistence interceptor, other datasources are not wired up automatically unless this is set to <code>true</code></p> |
| </li> |
| <li> |
| <p><code>properties</code> - Extra properties to set on the DataSource bean. See the <a href="http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html#Common_Attributes">Tomcat Pool</a> documentation. There is also a Javadoc format <a href="https://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/tomcat/jdbc/pool/PoolConfiguration.html">documentation of the properties</a>.</p> |
| </li> |
| <li> |
| <p><code>jmxExport</code> - If <code>false</code>, will disable registration of JMX MBeans for all DataSources. By default JMX MBeans are added for DataSources with <code>jmxEnabled = true</code> in properties.</p> |
| </li> |
| <li> |
| <p><code>type</code> - The connection pool class if you want to force Grails to use it when there are more than one available.</p> |
| </li> |
| </ul> |
| </div> |
| <div class="paragraph"> |
| <p>A typical configuration for MySQL in <code>application.groovy</code> may be something like:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy">dataSource { |
| pooled = <span class="predefined-constant">true</span> |
| dbCreate = <span class="string"><span class="delimiter">"</span><span class="content">update</span><span class="delimiter">"</span></span> |
| url = <span class="string"><span class="delimiter">"</span><span class="content">jdbc:mysql://localhost:3306/my_database</span><span class="delimiter">"</span></span> |
| driverClassName = <span class="string"><span class="delimiter">"</span><span class="content">com.mysql.jdbc.Driver</span><span class="delimiter">"</span></span> |
| dialect = org.hibernate.dialect.MySQL5InnoDBDialect |
| username = <span class="string"><span class="delimiter">"</span><span class="content">username</span><span class="delimiter">"</span></span> |
| password = <span class="string"><span class="delimiter">"</span><span class="content">password</span><span class="delimiter">"</span></span> |
| type = <span class="string"><span class="delimiter">"</span><span class="content">com.zaxxer.hikari.HikariDataSource</span><span class="delimiter">"</span></span> |
| properties { |
| jmxEnabled = <span class="predefined-constant">true</span> |
| initialSize = <span class="integer">5</span> |
| maxActive = <span class="integer">50</span> |
| minIdle = <span class="integer">5</span> |
| maxIdle = <span class="integer">25</span> |
| maxWait = <span class="integer">10000</span> |
| maxAge = <span class="integer">10</span> * <span class="integer">60000</span> |
| timeBetweenEvictionRunsMillis = <span class="integer">5000</span> |
| minEvictableIdleTimeMillis = <span class="integer">60000</span> |
| validationQuery = <span class="string"><span class="delimiter">"</span><span class="content">SELECT 1</span><span class="delimiter">"</span></span> |
| validationQueryTimeout = <span class="integer">3</span> |
| validationInterval = <span class="integer">15000</span> |
| testOnBorrow = <span class="predefined-constant">true</span> |
| testWhileIdle = <span class="predefined-constant">true</span> |
| testOnReturn = <span class="predefined-constant">false</span> |
| jdbcInterceptors = <span class="string"><span class="delimiter">"</span><span class="content">ConnectionState;StatementCache(max=200)</span><span class="delimiter">"</span></span> |
| defaultTransactionIsolation = java.sql.Connection.TRANSACTION_READ_COMMITTED |
| } |
| }</code></pre> |
| </div> |
| </div> |
| <div class="admonitionblock warning"> |
| <table> |
| <tr> |
| <td class="icon"> |
| <i class="fa icon-warning" title="Warning"></i> |
| </td> |
| <td class="content"> |
| When configuring the DataSource do not include the type or the def keyword before any of the configuration settings as Groovy will treat these as local variable definitions and they will not be processed. For example the following is invalid: |
| </td> |
| </tr> |
| </table> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy">dataSource { |
| <span class="type">boolean</span> pooled = <span class="predefined-constant">true</span> <span class="comment">// type declaration results in ignored local variable</span> |
| ... |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>Example of advanced configuration using extra properties:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy">dataSource { |
| pooled = <span class="predefined-constant">true</span> |
| dbCreate = <span class="string"><span class="delimiter">"</span><span class="content">update</span><span class="delimiter">"</span></span> |
| url = <span class="string"><span class="delimiter">"</span><span class="content">jdbc:mysql://localhost:3306/my_database</span><span class="delimiter">"</span></span> |
| driverClassName = <span class="string"><span class="delimiter">"</span><span class="content">com.mysql.jdbc.Driver</span><span class="delimiter">"</span></span> |
| dialect = org.hibernate.dialect.MySQL5InnoDBDialect |
| username = <span class="string"><span class="delimiter">"</span><span class="content">username</span><span class="delimiter">"</span></span> |
| password = <span class="string"><span class="delimiter">"</span><span class="content">password</span><span class="delimiter">"</span></span> |
| type = <span class="string"><span class="delimiter">"</span><span class="content">com.zaxxer.hikari.HikariDataSource</span><span class="delimiter">"</span></span> |
| properties { |
| <span class="comment">// Documentation for Tomcat JDBC Pool</span> |
| <span class="comment">// http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html#Common_Attributes</span> |
| <span class="comment">// https://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/tomcat/jdbc/pool/PoolConfiguration.html</span> |
| jmxEnabled = <span class="predefined-constant">true</span> |
| initialSize = <span class="integer">5</span> |
| maxActive = <span class="integer">50</span> |
| minIdle = <span class="integer">5</span> |
| maxIdle = <span class="integer">25</span> |
| maxWait = <span class="integer">10000</span> |
| maxAge = <span class="integer">10</span> * <span class="integer">60000</span> |
| timeBetweenEvictionRunsMillis = <span class="integer">5000</span> |
| minEvictableIdleTimeMillis = <span class="integer">60000</span> |
| validationQuery = <span class="string"><span class="delimiter">"</span><span class="content">SELECT 1</span><span class="delimiter">"</span></span> |
| validationQueryTimeout = <span class="integer">3</span> |
| validationInterval = <span class="integer">15000</span> |
| testOnBorrow = <span class="predefined-constant">true</span> |
| testWhileIdle = <span class="predefined-constant">true</span> |
| testOnReturn = <span class="predefined-constant">false</span> |
| ignoreExceptionOnPreLoad = <span class="predefined-constant">true</span> |
| <span class="comment">// http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html#JDBC_interceptors</span> |
| jdbcInterceptors = <span class="string"><span class="delimiter">"</span><span class="content">ConnectionState;StatementCache(max=200)</span><span class="delimiter">"</span></span> |
| defaultTransactionIsolation = java.sql.Connection.TRANSACTION_READ_COMMITTED <span class="comment">// safe default</span> |
| <span class="comment">// controls for leaked connections</span> |
| abandonWhenPercentageFull = <span class="integer">100</span> <span class="comment">// settings are active only when pool is full</span> |
| removeAbandonedTimeout = <span class="integer">120</span> |
| removeAbandoned = <span class="predefined-constant">true</span> |
| <span class="comment">// use JMX console to change this setting at runtime</span> |
| logAbandoned = <span class="predefined-constant">false</span> <span class="comment">// causes stacktrace recording overhead, use only for debugging</span> |
| <span class="comment">// JDBC driver properties</span> |
| <span class="comment">// Mysql as example</span> |
| dbProperties { |
| <span class="comment">// Mysql specific driver properties</span> |
| <span class="comment">// http://dev.mysql.com/doc/connector-j/en/connector-j-reference-configuration-properties.html</span> |
| <span class="comment">// let Tomcat JDBC Pool handle reconnecting</span> |
| autoReconnect=<span class="predefined-constant">false</span> |
| <span class="comment">// truncation behaviour</span> |
| jdbcCompliantTruncation=<span class="predefined-constant">false</span> |
| <span class="comment">// mysql 0-date conversion</span> |
| zeroDateTimeBehavior=<span class="string"><span class="delimiter">'</span><span class="content">convertToNull</span><span class="delimiter">'</span></span> |
| <span class="comment">// Tomcat JDBC Pool's StatementCache is used instead, so disable mysql driver's cache</span> |
| cachePrepStmts=<span class="predefined-constant">false</span> |
| cacheCallableStmts=<span class="predefined-constant">false</span> |
| <span class="comment">// Tomcat JDBC Pool's StatementFinalizer keeps track</span> |
| dontTrackOpenResources=<span class="predefined-constant">true</span> |
| <span class="comment">// performance optimization: reduce number of SQLExceptions thrown in mysql driver code</span> |
| holdResultsOpenOverStatementClose=<span class="predefined-constant">true</span> |
| <span class="comment">// enable MySQL query cache - using server prep stmts will disable query caching</span> |
| useServerPrepStmts=<span class="predefined-constant">false</span> |
| <span class="comment">// metadata caching</span> |
| cacheServerConfiguration=<span class="predefined-constant">true</span> |
| cacheResultSetMetadata=<span class="predefined-constant">true</span> |
| metadataCacheSize=<span class="integer">100</span> |
| <span class="comment">// timeouts for TCP/IP</span> |
| connectTimeout=<span class="integer">15000</span> |
| socketTimeout=<span class="integer">120000</span> |
| <span class="comment">// timer tuning (disable)</span> |
| maintainTimeStats=<span class="predefined-constant">false</span> |
| enableQueryTimeouts=<span class="predefined-constant">false</span> |
| <span class="comment">// misc tuning</span> |
| noDatetimeStringSync=<span class="predefined-constant">true</span> |
| } |
| } |
| }</code></pre> |
| </div> |
| </div> |
| <div class="sect3"> |
| <h4 id="_more_on_dbcreate">More on dbCreate</h4> |
| <div class="paragraph"> |
| <p>Hibernate can automatically create the database tables required for your domain model. You have some control over when and how it does this through the <code>dbCreate</code> property, which can take these values:</p> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p><strong>create</strong> - Drops the existing schema and creates the schema on startup, dropping existing tables, indexes, etc. first.</p> |
| </li> |
| <li> |
| <p><strong>create-drop</strong> - Same as <strong>create</strong>, but also drops the tables when the application shuts down cleanly.</p> |
| </li> |
| <li> |
| <p><strong>update</strong> - Creates missing tables and indexes, and updates the current schema without dropping any tables or data. Note that this can’t properly handle many schema changes like column renames (you’re left with the old column containing the existing data).</p> |
| </li> |
| <li> |
| <p><strong>validate</strong> - Makes no changes to your database. Compares the configuration with the existing database schema and reports warnings.</p> |
| </li> |
| <li> |
| <p>any other value - does nothing</p> |
| </li> |
| </ul> |
| </div> |
| <div class="paragraph"> |
| <p>Setting the <code>dbCreate</code> setting to "none" is recommended once your schema is relatively stable and definitely when your application and database are deployed in production. Database changes are then managed through proper migrations, either with SQL scripts or a migration tool like <a href="https://flywaydb.org/">Flyway</a> or <a href="http://www.liquibase.org/">Liquibase</a>. The <a href="http://plugins.grails.org/plugin/grails/database-migration">Database Migration</a> plugin uses Liquibase.</p> |
| </div> |
| </div> |
| |
| <a name="3.3.1 DataSources and Environments"><!-- Legacy link --></a> |
| <h2 id="dataSourcesAndEnvironments">4.4.1 DataSources and Environments</h2> |
| |
| <div class='contribute-btn'> |
| <button type='button' class='btn btn-default' onclick='window.location.href="https://github.com/grails/grails-doc/edit/6.2.x/src/en/guide/conf/dataSource/dataSourcesAndEnvironments.adoc"'> |
| <i class='fa fa-pencil-square-o'></i> Improve this doc |
| </button> |
| </div> |
| |
| |
| <div class="paragraph"> |
| <p>The previous example configuration assumes you want the same config for all environments: production, test, development etc.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Grails' DataSource definition is "environment aware", however, so you can do:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy">dataSource { |
| pooled = <span class="predefined-constant">true</span> |
| driverClassName = <span class="string"><span class="delimiter">"</span><span class="content">com.mysql.jdbc.Driver</span><span class="delimiter">"</span></span> |
| dialect = org.hibernate.dialect.MySQL5InnoDBDialect |
| <span class="comment">// other common settings here</span> |
| } |
| |
| environments { |
| production { |
| dataSource { |
| url = <span class="string"><span class="delimiter">"</span><span class="content">jdbc:mysql://liveip.com/liveDb</span><span class="delimiter">"</span></span> |
| <span class="comment">// other environment-specific settings here</span> |
| } |
| } |
| }</code></pre> |
| </div> |
| </div> |
| |
| <a name="3.3.3 Automatic Database Migration"><!-- Legacy link --></a> |
| <h2 id="automaticDatabaseMigration">4.4.2 Automatic Database Migration</h2> |
| |
| <div class='contribute-btn'> |
| <button type='button' class='btn btn-default' onclick='window.location.href="https://github.com/grails/grails-doc/edit/6.2.x/src/en/guide/conf/dataSource/automaticDatabaseMigration.adoc"'> |
| <i class='fa fa-pencil-square-o'></i> Improve this doc |
| </button> |
| </div> |
| |
| |
| <div class="paragraph"> |
| <p>The <code>dbCreate</code> property of the <code>DataSource</code> definition is important as it dictates what Grails should do at runtime with regards to automatically generating the database tables from <a href="GORM.html">GORM</a> classes. The options are described in the <a href="#dataSource">DataSource</a> section:</p> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p><code>create</code></p> |
| </li> |
| <li> |
| <p><code>create-drop</code></p> |
| </li> |
| <li> |
| <p><code>update</code></p> |
| </li> |
| <li> |
| <p><code>validate</code></p> |
| </li> |
| <li> |
| <p>no value</p> |
| </li> |
| </ul> |
| </div> |
| <div class="paragraph"> |
| <p>In <a href="#environments">development</a> mode <code>dbCreate</code> is by default set to "create-drop", but at some point in development (and certainly once you go to production) you’ll need to stop dropping and re-creating the database every time you start up your server.</p> |
| </div> |
| <div class="paragraph"> |
| <p>It’s tempting to switch to <code>update</code> so you retain existing data and only update the schema when your code changes, but Hibernate’s update support is very conservative. It won’t make any changes that could result in data loss, and doesn’t detect renamed columns or tables, so you’ll be left with the old one and will also have the new one.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Grails supports migrations with Liquibase or Flyway via plugins.</p> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p><a href="http://plugins.grails.org/plugin/grails/database-migration">Database Migration</a></p> |
| </li> |
| <li> |
| <p><a href="http://plugins.grails.org/plugin/saw303/org.grails.plugins%3Agrails-flyway">Flyway</a></p> |
| </li> |
| </ul> |
| </div> |
| |
| <a name="3.3.4 Transaction-aware DataSource Proxy"><!-- Legacy link --></a> |
| <h2 id="transactionAwareDataSourceProxy">4.4.3 Transaction-aware DataSource Proxy</h2> |
| |
| <div class='contribute-btn'> |
| <button type='button' class='btn btn-default' onclick='window.location.href="https://github.com/grails/grails-doc/edit/6.2.x/src/en/guide/conf/dataSource/transactionAwareDataSourceProxy.adoc"'> |
| <i class='fa fa-pencil-square-o'></i> Improve this doc |
| </button> |
| </div> |
| |
| |
| <div class="paragraph"> |
| <p>The actual <code>dataSource</code> bean is wrapped in a transaction-aware proxy so you will be given the connection that’s being used by the current transaction or Hibernate <code>Session</code> if one is active.</p> |
| </div> |
| <div class="paragraph"> |
| <p>If this were not the case, then retrieving a connection from the <code>dataSource</code> would be a new connection, and you wouldn’t be able to see changes that haven’t been committed yet (assuming you have a sensible transaction isolation setting, e.g. <code>READ_COMMITTED</code> or better).</p> |
| </div> |
| |
| <a name="3.3.5 Database Console"><!-- Legacy link --></a> |
| <h2 id="databaseConsole">4.4.4 Database Console</h2> |
| |
| <div class='contribute-btn'> |
| <button type='button' class='btn btn-default' onclick='window.location.href="https://github.com/grails/grails-doc/edit/6.2.x/src/en/guide/conf/dataSource/databaseConsole.adoc"'> |
| <i class='fa fa-pencil-square-o'></i> Improve this doc |
| </button> |
| </div> |
| |
| |
| <div class="paragraph"> |
| <p>The <a href="http://h2database.com/html/quickstart.html#h2_console">H2 database console</a> is a convenient feature of H2 that provides a web-based interface to any database that you have a JDBC driver for, and it’s very useful to view the database you’re developing against. It’s especially useful when running against an in-memory database.</p> |
| </div> |
| <div class="paragraph"> |
| <p>You can access the console by navigating to <a href="http://localhost:8080/h2-console" class="bare">http://localhost:8080/h2-console</a> in a browser. See the <a href="https://docs.spring.io/spring-boot/docs/2.7.18/reference/htmlsingle/#data.sql.h2-web-console">Spring Boot H2 Console Documentation</a> for more information on the options available.</p> |
| </div> |
| <div class="admonitionblock tip"> |
| <table> |
| <tr> |
| <td class="icon"> |
| <i class="fa icon-tip" title="Tip"></i> |
| </td> |
| <td class="content"> |
| The H2 console is disabled by default (unless you are using Spring Boot’s developer tools) and must be enabled by configuring the <code>spring.h2.console.enabled</code> property with a value of <code>true</code>. |
| </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"> |
| The H2 console is only intended for use during development so care should be taken to ensure that <code>spring.h2.console.enabled</code> is not set to <code>true</code> in production. |
| </td> |
| </tr> |
| </table> |
| </div> |
| |
| <a name="3.3.6 Multiple Datasources"><!-- Legacy link --></a> |
| <h2 id="multipleDatasources">4.4.5 Multiple Datasources</h2> |
| |
| <div class='contribute-btn'> |
| <button type='button' class='btn btn-default' onclick='window.location.href="https://github.com/grails/grails-doc/edit/6.2.x/src/en/guide/conf/dataSource/multipleDatasources.adoc"'> |
| <i class='fa fa-pencil-square-o'></i> Improve this doc |
| </button> |
| </div> |
| |
| |
| <div class="paragraph"> |
| <p>By default all domain classes share a single <code>DataSource</code> and a single database, but you have the option to partition your domain classes into two or more data sources.</p> |
| </div> |
| <div class="sect3"> |
| <h4 id="_configuring_additional_datasources">Configuring Additional DataSources</h4> |
| <div class="paragraph"> |
| <p>The default <code>DataSource</code> configuration in <code>grails-app/conf/application.yml</code> looks something like this:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="yaml"><span class="key">dataSource</span>: |
| <span class="key">pooled</span>: <span class="string"><span class="content">true</span></span> |
| <span class="key">jmxExport</span>: <span class="string"><span class="content">true</span></span> |
| <span class="key">driverClassName</span>: <span class="string"><span class="content">org.h2.Driver</span></span> |
| <span class="key">username</span>: <span class="string"><span class="content">sa</span></span> |
| <span class="key">password</span>: |
| |
| <span class="key">environments</span>: |
| <span class="key">development</span>: |
| <span class="key">dataSource</span>: |
| <span class="key">dbCreate</span>: <span class="string"><span class="content">create-drop</span></span> |
| <span class="key">url</span>: <span class="string"><span class="content">jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE</span></span> |
| <span class="key">test</span>: |
| <span class="key">dataSource</span>: |
| <span class="key">dbCreate</span>: <span class="string"><span class="content">update</span></span> |
| <span class="key">url</span>: <span class="string"><span class="content">jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE</span></span> |
| <span class="key">production</span>: |
| <span class="key">dataSource</span>: |
| <span class="key">dbCreate</span>: <span class="string"><span class="content">update</span></span> |
| <span class="key">url</span>: <span class="string"><span class="content">jdbc:h2:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE</span></span> |
| <span class="key">properties</span>: |
| <span class="key">jmxEnabled</span>: <span class="string"><span class="content">true</span></span> |
| <span class="key">initialSize</span>: <span class="string"><span class="content">5</span></span></code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>This configures a single <code>DataSource</code> with the Spring bean named <code>dataSource</code>. To configure extra data sources, add a <code>dataSources</code> block (at the top level, in an environment block, or both, just like the standard <code>DataSource</code> definition) with a custom name. For example, this configuration adds a second <code>DataSource</code>, using MySQL in the development environment and Oracle in production:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="yaml"><span class="key">dataSource</span>: |
| <span class="key">pooled</span>: <span class="string"><span class="content">true</span></span> |
| <span class="key">jmxExport</span>: <span class="string"><span class="content">true</span></span> |
| <span class="key">driverClassName</span>: <span class="string"><span class="content">org.h2.Driver</span></span> |
| <span class="key">username</span>: <span class="string"><span class="content">sa</span></span> |
| <span class="key">password</span>: |
| |
| <span class="key">dataSources</span>: |
| <span class="key">lookup</span>: |
| <span class="key">dialect</span>: <span class="string"><span class="content">org.hibernate.dialect.MySQLInnoDBDialect</span></span> |
| <span class="key">driverClassName</span>: <span class="string"><span class="content">com.mysql.jdbc.Driver</span></span> |
| <span class="key">username</span>: <span class="string"><span class="content">lookup</span></span> |
| <span class="key">password</span>: <span class="string"><span class="content">secret</span></span> |
| <span class="key">url</span>: <span class="string"><span class="content">jdbc:mysql://localhost/lookup</span></span> |
| <span class="key">dbCreate</span>: <span class="string"><span class="content">update</span></span> |
| |
| <span class="key">environments</span>: |
| <span class="key">development</span>: |
| <span class="key">dataSource</span>: |
| <span class="key">dbCreate</span>: <span class="string"><span class="content">create-drop</span></span> |
| <span class="key">url</span>: <span class="string"><span class="content">jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE</span></span> |
| <span class="key">test</span>: |
| <span class="key">dataSource</span>: |
| <span class="key">dbCreate</span>: <span class="string"><span class="content">update</span></span> |
| <span class="key">url</span>: <span class="string"><span class="content">jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE</span></span> |
| <span class="key">production</span>: |
| <span class="key">dataSource</span>: |
| <span class="key">dbCreate</span>: <span class="string"><span class="content">update</span></span> |
| <span class="key">url</span>: <span class="string"><span class="content">jdbc:h2:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE</span></span> |
| <span class="key">properties</span>: |
| <span class="key">jmxEnabled</span>: <span class="string"><span class="content">true</span></span> |
| <span class="key">initialSize</span>: <span class="string"><span class="content">5</span></span> |
| <span class="error">...</span> |
| <span class="key">dataSources</span>: |
| <span class="key">lookup</span>: |
| <span class="key">dialect</span>: <span class="string"><span class="content">org.hibernate.dialect.Oracle10gDialect</span></span> |
| <span class="key">driverClassName</span>: <span class="string"><span class="content">oracle.jdbc.driver.OracleDriver</span></span> |
| <span class="key">username</span>: <span class="string"><span class="content">lookup</span></span> |
| <span class="key">password</span>: <span class="string"><span class="content">secret</span></span> |
| <span class="key">url</span>: <span class="string"><span class="content">jdbc:oracle:thin:@localhost:1521:lookup</span></span> |
| <span class="key">dbCreate</span>: <span class="string"><span class="content">update</span></span></code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>You can use the same or different databases as long as they’re supported by Hibernate.</p> |
| </div> |
| <div class="paragraph"> |
| <p>If you need to inject the <code>lookup</code> datasource in a Grails artefact, you can do it like this:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy"><span class="predefined-type">DataSource</span> dataSource_lookup</code></pre> |
| </div> |
| </div> |
| <div class="admonitionblock note"> |
| <table> |
| <tr> |
| <td class="icon"> |
| <i class="fa icon-note" title="Note"></i> |
| </td> |
| <td class="content"> |
| While defining multiple data sources, one of them <strong>must</strong> be named "dataSource". This is required because Grails determines which data source is the default by determining which one is named "dataSource". |
| </td> |
| </tr> |
| </table> |
| </div> |
| </div> |
| <div class="sect3"> |
| <h4 id="_configuring_domain_classes">Configuring Domain Classes</h4> |
| <div class="paragraph"> |
| <p>If a domain class has no <code>DataSource</code> configuration, it defaults to the standard <code>'dataSource'</code>. Set the <code>datasource</code> property in the <code>mapping</code> block to configure a non-default <code>DataSource</code>. For example, if you want to use the <code>ZipCode</code> domain to use the <code>'lookup'</code> <code>DataSource</code>, configure it like this:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy"><span class="type">class</span> <span class="class">ZipCode</span> { |
| |
| <span class="predefined-type">String</span> code |
| |
| <span class="directive">static</span> mapping = { |
| datasource <span class="string"><span class="delimiter">'</span><span class="content">lookup</span><span class="delimiter">'</span></span> |
| } |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>A domain class can also use two or more data sources. Use the <code>datasources</code> property with a list of names to configure more than one, for example:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy"><span class="type">class</span> <span class="class">ZipCode</span> { |
| |
| <span class="predefined-type">String</span> code |
| |
| <span class="directive">static</span> mapping = { |
| datasources([<span class="string"><span class="delimiter">'</span><span class="content">lookup</span><span class="delimiter">'</span></span>, <span class="string"><span class="delimiter">'</span><span class="content">auditing</span><span class="delimiter">'</span></span>]) |
| } |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>If a domain class uses the default <code>DataSource</code> and one or more others, use the special name <code>'DEFAULT'</code> to indicate the default <code>DataSource</code>:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy"><span class="type">class</span> <span class="class">ZipCode</span> { |
| |
| <span class="predefined-type">String</span> code |
| |
| <span class="directive">static</span> mapping = { |
| datasources([<span class="string"><span class="delimiter">'</span><span class="content">lookup</span><span class="delimiter">'</span></span>, <span class="string"><span class="delimiter">'</span><span class="content">DEFAULT</span><span class="delimiter">'</span></span>]) |
| } |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>If a domain class uses all configured data sources, use the special value <code>'ALL'</code>:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy"><span class="type">class</span> <span class="class">ZipCode</span> { |
| |
| <span class="predefined-type">String</span> code |
| |
| <span class="directive">static</span> mapping = { |
| datasource <span class="string"><span class="delimiter">'</span><span class="content">ALL</span><span class="delimiter">'</span></span> |
| } |
| }</code></pre> |
| </div> |
| </div> |
| </div> |
| <div class="sect3"> |
| <h4 id="_namespaces_and_gorm_methods">Namespaces and GORM Methods</h4> |
| <div class="paragraph"> |
| <p>If a domain class uses more than one <code>DataSource</code> then you can use the namespace implied by each <code>DataSource</code> name to make GORM calls for a particular <code>DataSource</code>. For example, consider this class which uses two data sources:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy"><span class="type">class</span> <span class="class">ZipCode</span> { |
| |
| <span class="predefined-type">String</span> code |
| |
| <span class="directive">static</span> mapping = { |
| datasources([<span class="string"><span class="delimiter">'</span><span class="content">lookup</span><span class="delimiter">'</span></span>, <span class="string"><span class="delimiter">'</span><span class="content">auditing</span><span class="delimiter">'</span></span>]) |
| } |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>The first <code>DataSource</code> specified is the default when not using an explicit namespace, so in this case we default to <code>'lookup'</code>. But you can call GORM methods on the 'auditing' <code>DataSource</code> with the <code>DataSource</code> name, for example:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy"><span class="keyword">def</span> zipCode = ZipCode.auditing.get(<span class="integer">42</span>) |
| ... |
| zipCode.auditing.save()</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>As you can see, you add the <code>DataSource</code> to the method call in both the static case and the instance case.</p> |
| </div> |
| </div> |
| <div class="sect3"> |
| <h4 id="_hibernate_mapped_domain_classes">Hibernate Mapped Domain Classes</h4> |
| <div class="paragraph"> |
| <p>You can also partition annotated Java classes into separate datasources. Classes using the default datasource are registered in <code>grails-app/conf/hibernate.cfg.xml</code>. To specify that an annotated class uses a non-default datasource, create a <code>hibernate.cfg.xml</code> file for that datasource with the file name prefixed with the datasource name.</p> |
| </div> |
| <div class="paragraph"> |
| <p>For example if the <code>Book</code> class is in the default datasource, you would register that in <code>grails-app/conf/hibernate.cfg.xml</code>:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="xml"><span class="preprocessor"><?xml version='1.0' encoding='UTF-8'?></span> |
| <span class="doctype"><!DOCTYPE hibernate-configuration PUBLIC |
| '-//Hibernate/Hibernate Configuration DTD 3.0//EN' |
| 'http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd'></span> |
| <span class="tag"><hibernate-configuration></span> |
| <span class="tag"><session-factory></span> |
| <span class="tag"><mapping</span> <span class="attribute-name">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">org.example.Book</span><span class="delimiter">'</span></span><span class="tag">/></span> |
| <span class="tag"></session-factory></span> |
| <span class="tag"></hibernate-configuration></span></code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>and if the <code>Library</code> class is in the "ds2" datasource, you would register that in <code>grails-app/conf/ds2_hibernate.cfg.xml</code>:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="xml"><span class="preprocessor"><?xml version='1.0' encoding='UTF-8'?></span> |
| <span class="doctype"><!DOCTYPE hibernate-configuration PUBLIC |
| '-//Hibernate/Hibernate Configuration DTD 3.0//EN' |
| 'http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd'></span> |
| <span class="tag"><hibernate-configuration></span> |
| <span class="tag"><session-factory></span> |
| <span class="tag"><mapping</span> <span class="attribute-name">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">org.example.Library</span><span class="delimiter">'</span></span><span class="tag">/></span> |
| <span class="tag"></session-factory></span> |
| <span class="tag"></hibernate-configuration></span></code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>The process is the same for classes mapped with hbm.xml files - just list them in the appropriate hibernate.cfg.xml file.</p> |
| </div> |
| </div> |
| <div class="sect3"> |
| <h4 id="_services">Services</h4> |
| <div class="paragraph"> |
| <p>Like Domain classes, by default Services use the default <code>DataSource</code> and <code>PlatformTransactionManager</code>. To configure a Service to use a different <code>DataSource</code>, use the static <code>datasource</code> property, for example:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy"><span class="type">class</span> <span class="class">DataService</span> { |
| |
| <span class="directive">static</span> datasource = <span class="string"><span class="delimiter">'</span><span class="content">lookup</span><span class="delimiter">'</span></span> |
| |
| <span class="type">void</span> someMethod(...) { |
| ... |
| } |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>A transactional service can only use a single <code>DataSource</code>, so be sure to only make changes for domain classes whose <code>DataSource</code> is the same as the Service.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Note that the datasource specified in a service has no bearing on which datasources are used for domain classes; that’s determined by their declared datasources in the domain classes themselves. It’s used to declare which transaction manager to use.</p> |
| </div> |
| <div class="paragraph"> |
| <p>If you have a <code>Foo</code> domain class in <code>dataSource1</code> and a <code>Bar</code> domain class in <code>dataSource2</code>, if <code>WahooService</code> uses <code>dataSource1</code>, a service method that saves a new <code>Foo</code> and a new <code>Bar</code> will only be transactional for <code>Foo</code> since they share the same datasource. The transaction won’t affect the <code>Bar</code> instance. If you want both to be transactional you’d need to use two services and XA datasources for two-phase commit, e.g. with the Atomikos plugin.</p> |
| </div> |
| </div> |
| <div class="sect3"> |
| <h4 id="_transactions_across_multiple_data_sources">Transactions across multiple data sources</h4> |
| <div class="paragraph"> |
| <p>Grails does not by default try to handle transactions that span multiple data sources.</p> |
| </div> |
| <div class="paragraph"> |
| <p>You can enable Grails to use the Best Effort 1PC pattern for handling transactions across multiple datasources. To do so you must set the <code>grails.transaction.chainedTransactionManager.enabled</code> setting to <code>true</code> in <code>application.yml</code>:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="yaml"><span class="key">grails</span>: |
| <span class="key">transaction</span>: |
| <span class="key">chainedTransactionManager</span>: |
| <span class="key">enabled</span>: <span class="string"><span class="content">true</span></span></code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>The <a href="https://www.javaworld.com/article/2077963/open-source-tools/distributed-transactions-in-spring-with-and-without-xa.html">Best Efforts 1PC pattern</a> is fairly general but can fail in some circumstances that the developer must be aware of.</p> |
| </div> |
| <div class="paragraph"> |
| <p>This is a non-XA pattern that involves a synchronized single-phase commit of a number of resources. Because the <a href="#ref-orgwiki-twophasecommit-2PC">2PC</a> is not used, it can never be as safe as an <a href="#ref-orgwiki-x-open-xa-XA">XA</a> transaction, but is often good enough if the participants are aware of the compromises.</p> |
| </div> |
| <div class="paragraph"> |
| <p>The basic idea is to delay the commit of all resources as late as possible in a transaction so that the only thing that can go wrong is an infrastructure failure (not a business-processing error). Systems that rely on Best Efforts 1PC reason that infrastructure failures are rare enough that they can afford to take the risk in return for higher throughput. If business-processing services are also designed to be idempotent, then little can go wrong in practice.</p> |
| </div> |
| <div class="paragraph"> |
| <p>The BE1PC implementation was added in Grails 2.3.6. . Before this change additional datasources didn’t take part in transactions initiated in Grails. The transactions in additional datasources were basically in auto commit mode. In some cases this might be the wanted behavior. One reason might be performance: on the start of each new transaction, the BE1PC transaction manager creates a new transaction to each datasource. It’s possible to leave an additional datasource out of the BE1PC transaction manager by setting <code>transactional = false</code> in the respective configuration block of the additional dataSource. Datasources with <code>readOnly = true</code> will also be left out of the chained transaction manager (since 2.3.7).</p> |
| </div> |
| <div class="paragraph"> |
| <p>By default, the BE1PC implementation will add all beans implementing the Spring <code><a href="https://docs.spring.io/spring/docs/5.3.39/javadoc-api//org/springframework/transaction/PlatformTransactionManager.html">PlatformTransactionManager</a></code> interface to the chained BE1PC transaction manager. For example, a possible <code><a href="https://docs.spring.io/spring/docs/5.3.39/javadoc-api//org/springframework/jms/connection/JmsTransactionManager.html">JMSTransactionManager</a></code> bean in the Grails application context would be added to the Grails BE1PC transaction manager’s chain of transaction managers.</p> |
| </div> |
| <div class="paragraph"> |
| <p>You can exclude transaction manager beans from the BE1PC implementation with this configuration option:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="yaml"><span class="key">grails</span>: |
| <span class="key">transaction</span>: |
| <span class="key">chainedTransactionManager</span>: |
| <span class="key">enabled</span>: <span class="string"><span class="content">true</span></span> |
| <span class="key">blacklistPattern</span>: <span class="string"><span class="content">'.*'</span></span></code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>The exclude matching is done on the name of the transaction manager bean. The transaction managers of datasources with <code>transactional = false</code> or <code>readOnly = true</code> will be skipped and using this configuration option is not required in that case.</p> |
| </div> |
| </div> |
| <div class="sect3"> |
| <h4 id="_xa_and_two_phase_commit">XA and Two-phase Commit</h4> |
| <div class="paragraph"> |
| <p>When the Best Efforts 1PC pattern isn’t suitable for handling transactions across multiple transactional resources (not only datasources), there are several options available for adding XA/2PC support to Grails applications.</p> |
| </div> |
| <div class="paragraph"> |
| <p>The <a href="https://docs.spring.io/spring/docs/5.3.39//transaction.html#transaction-application-server-integration">Spring transactions documentation</a> contains information about integrating the JTA/XA transaction manager of different application servers. In this case, you can configure a bean with the name <code>transactionManager</code> manually in <code>resources.groovy</code> or <code>resources.xml</code> file.</p> |
| </div> |
| </div> |
| |
| <a name="3.5 Versioning"><!-- Legacy link --></a> |
| <h2 id="versioning">4.5 Versioning</h2> |
| |
| <div class='contribute-btn'> |
| <button type='button' class='btn btn-default' onclick='window.location.href="https://github.com/grails/grails-doc/edit/6.2.x/src/en/guide/conf/versioning.adoc"'> |
| <i class='fa fa-pencil-square-o'></i> Improve this doc |
| </button> |
| </div> |
| |
| |
| <div class="sect3"> |
| <h4 id="_detecting_versions_at_runtime">Detecting Versions at Runtime</h4> |
| <div class="paragraph"> |
| <p>You can detect the application version using Grails' support for application metadata using the <a href="https://grails.apache.org/docs/6.2.3/api/grails/core/GrailsApplication.html">GrailsApplication</a> class. For example within <a href="theWebLayer.html#controllers">controllers</a> there is an implicit <a href="../ref/Controllers/grailsApplication.html">grailsApplication</a> variable that can be used:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy"><span class="keyword">def</span> version = grailsApplication.metadata.getApplicationVersion()</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>You can retrieve the version of Grails that is running with:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy"><span class="keyword">def</span> grailsVersion = grailsApplication.metadata.getGrailsVersion()</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>or the <code>GrailsUtil</code> class:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="groovy"><span class="keyword">import</span> <span class="include">grails.util.GrailsUtil</span> |
| ... |
| def grailsVersion = GrailsUtil.grailsVersion</code></pre> |
| </div> |
| </div> |
| </div> |
| |
| <a name="3.7 Dependency Resolution"><!-- Legacy link --></a> |
| <h2 id="dependencyResolution">4.6 Dependency Resolution</h2> |
| |
| <div class='contribute-btn'> |
| <button type='button' class='btn btn-default' onclick='window.location.href="https://github.com/grails/grails-doc/edit/6.2.x/src/en/guide/conf/dependencyResolution.adoc"'> |
| <i class='fa fa-pencil-square-o'></i> Improve this doc |
| </button> |
| </div> |
| |
| |
| <div class="paragraph"> |
| <p>Dependency resolution is handled by the <a href="http://gradle.org">Gradle build tool</a>, all dependencies are defined in the <code>build.gradle</code> file. Refer to the <a href="commandLine.html#gradleBuild">Gradle user guide</a> for more information.</p> |
| </div> |
| |
| |
| <div style="clear:both;margin-top:15px;"></div> |
| |
| <div class="toc-item prev-left"><a href="../guide/upgrading.html"><< <strong>3</strong><span>Upgrading from the previous versions</span></a></div> |
| |
| <div class="toc-item next-right"><a href="../guide/commandLine.html"><strong>5</strong><span>The Command Line</span> >></a></div> |
| |
| <div style="clear:both"></div> |
| </div> |
| </td> |
| <td id="col2"> |
| <div class="local clearfix"> |
| <div class="local-title"> |
| <a href="../guide/index.html" target="mainFrame">Quick Reference</a> |
| <span class="toggle">(<a href="#" onclick="localToggle(); return false;">hide</a>)</span> |
| </div> |
| <div class="menu"> |
| |
| <div class="menu-block"><h1 class="menu-title" onclick="toggleRef(this.parentNode.childNodes[1])">Command Line</h1><div class="menu-sub"> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/Usage.html">Usage</a></div> |
| |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/assemble.html">assemble</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/bootRun.html">bootRun</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/bug-report.html">bug-report</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/clean.html">clean</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/compile.html">compile</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/console.html">console</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/create-app.html">create-app</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/create-command.html">create-command</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/create-controller.html">create-controller</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/create-domain-class.html">create-domain-class</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/create-functional-test.html">create-functional-test</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/create-hibernate-cfg-xml.html">create-hibernate-cfg-xml</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/create-integration-test.html">create-integration-test</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/create-interceptor.html">create-interceptor</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/create-job.html">create-job</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/create-plugin.html">create-plugin</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/create-profile.html">create-profile</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/create-restapi.html">create-restapi</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/create-script.html">create-script</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/create-service.html">create-service</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/create-taglib.html">create-taglib</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/create-unit-test.html">create-unit-test</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/create-web-plugin.html">create-web-plugin</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/dependency-report.html">dependency-report</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/docs.html">docs</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/generate-all.html">generate-all</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/generate-controller.html">generate-controller</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/generate-views.html">generate-views</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/help.html">help</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/install-templates.html">install-templates</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/list-features.html">list-features</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/list-plugins.html">list-plugins</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/list-profiles.html">list-profiles</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/package-plugin.html">package-plugin</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/package.html">package</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/plugin-info.html">plugin-info</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/profile-info.html">profile-info</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/run-app.html">run-app</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/run-command.html">run-command</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/run-script.html">run-script</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/schema-export.html">schema-export</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/shell.html">shell</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/stats.html">stats</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/stop-app.html">stop-app</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/test-app.html">test-app</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Command%20Line/war.html">war</a> |
| </div> |
| |
| </div> |
| </div> |
| |
| <div class="menu-block"><h1 class="menu-title" onclick="toggleRef(this.parentNode.childNodes[1])">Constraints</h1><div class="menu-sub"> |
| |
| <div class="menu-item"><a href="../ref/Constraints/Usage.html">Usage</a></div> |
| |
| |
| <div class="menu-item"><a href="../ref/Constraints/attributes.html">attributes</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Constraints/bindable.html">bindable</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Constraints/blank.html">blank</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Constraints/creditCard.html">creditCard</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Constraints/email.html">email</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Constraints/inList.html">inList</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Constraints/matches.html">matches</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Constraints/max.html">max</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Constraints/maxSize.html">maxSize</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Constraints/min.html">min</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Constraints/minSize.html">minSize</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Constraints/notEqual.html">notEqual</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Constraints/nullable.html">nullable</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Constraints/range.html">range</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Constraints/scale.html">scale</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Constraints/size.html">size</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Constraints/unique.html">unique</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Constraints/url.html">url</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Constraints/validator.html">validator</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Constraints/widget.html">widget</a> |
| </div> |
| |
| </div> |
| </div> |
| |
| <div class="menu-block"><h1 class="menu-title" onclick="toggleRef(this.parentNode.childNodes[1])">Controllers</h1><div class="menu-sub"> |
| |
| <div class="menu-item"><a href="../ref/Controllers/Usage.html">Usage</a></div> |
| |
| |
| <div class="menu-item"><a href="../ref/Controllers/actionName.html">actionName</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Controllers/allowedMethods.html">allowedMethods</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Controllers/bindData.html">bindData</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Controllers/chain.html">chain</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Controllers/controllerName.html">controllerName</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Controllers/defaultAction.html">defaultAction</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Controllers/errors.html">errors</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Controllers/flash.html">flash</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Controllers/forward.html">forward</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Controllers/grailsApplication.html">grailsApplication</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Controllers/hasErrors.html">hasErrors</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Controllers/header.html">header</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Controllers/namespace.html">namespace</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Controllers/params.html">params</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Controllers/redirect.html">redirect</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Controllers/render.html">render</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Controllers/request.html">request</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Controllers/respond.html">respond</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Controllers/response.html">response</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Controllers/responseFormats.html">responseFormats</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Controllers/scope.html">scope</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Controllers/servletContext.html">servletContext</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Controllers/session.html">session</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Controllers/withForm.html">withForm</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Controllers/withFormat.html">withFormat</a> |
| </div> |
| |
| </div> |
| </div> |
| |
| <div class="menu-block"><h1 class="menu-title" onclick="toggleRef(this.parentNode.childNodes[1])">Database Mapping</h1><div class="menu-sub"> |
| |
| <div class="menu-item"><a href="../ref/Database%20Mapping/Usage.html">Usage</a></div> |
| |
| |
| <div class="menu-item"><a href="../ref/Database%20Mapping/autoImport.html">autoImport</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Database%20Mapping/autoTimestamp.html">autoTimestamp</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Database%20Mapping/batchSize.html">batchSize</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Database%20Mapping/cache.html">cache</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Database%20Mapping/cascade.html">cascade</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Database%20Mapping/column.html">column</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Database%20Mapping/comment.html">comment</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Database%20Mapping/discriminator.html">discriminator</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Database%20Mapping/dynamicInsert.html">dynamicInsert</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Database%20Mapping/dynamicUpdate.html">dynamicUpdate</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Database%20Mapping/fetch.html">fetch</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Database%20Mapping/id.html">id</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Database%20Mapping/ignoreNotFound.html">ignoreNotFound</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Database%20Mapping/indexColumn.html">indexColumn</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Database%20Mapping/insertable.html">insertable</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Database%20Mapping/joinTable.html">joinTable</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Database%20Mapping/lazy.html">lazy</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Database%20Mapping/order.html">order</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Database%20Mapping/sort.html">sort</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Database%20Mapping/table.html">table</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Database%20Mapping/type.html">type</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Database%20Mapping/updateable.html">updateable</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Database%20Mapping/version.html">version</a> |
| </div> |
| |
| </div> |
| </div> |
| |
| <div class="menu-block"><h1 class="menu-title" onclick="toggleRef(this.parentNode.childNodes[1])">Dependency Versions</h1><div class="menu-sub"> |
| |
| <div class="menu-item"><a href="../ref/Dependency%20Versions/Usage.html">Usage</a></div> |
| |
| |
| <div class="menu-item"><a href="../ref/Dependency%20Versions/Grails%20BOM.html">Grails BOM</a> |
| </div> |
| |
| </div> |
| </div> |
| |
| <div class="menu-block"><h1 class="menu-title" onclick="toggleRef(this.parentNode.childNodes[1])">Domain Classes</h1><div class="menu-sub"> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/Usage.html">Usage</a></div> |
| |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/addTo.html">addTo</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/attach.html">attach</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/belongsTo.html">belongsTo</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/clearErrors.html">clearErrors</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/constraints.html">constraints</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/count.html">count</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/countBy.html">countBy</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/createCriteria.html">createCriteria</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/delete.html">delete</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/discard.html">discard</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/embedded.html">embedded</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/errors.html">errors</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/executeQuery.html">executeQuery</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/executeUpdate.html">executeUpdate</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/exists.html">exists</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/fetchMode.html">fetchMode</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/find.html">find</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/findAll.html">findAll</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/findAllBy.html">findAllBy</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/findAllWhere.html">findAllWhere</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/findBy.html">findBy</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/findOrCreateBy.html">findOrCreateBy</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/findOrCreateWhere.html">findOrCreateWhere</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/findOrSaveBy.html">findOrSaveBy</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/findOrSaveWhere.html">findOrSaveWhere</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/findWhere.html">findWhere</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/first.html">first</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/get.html">get</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/getAll.html">getAll</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/getDirtyPropertyNames.html">getDirtyPropertyNames</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/getPersistentValue.html">getPersistentValue</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/hasErrors.html">hasErrors</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/hasMany.html">hasMany</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/hasOne.html">hasOne</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/ident.html">ident</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/instanceOf.html">instanceOf</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/isAttached.html">isAttached</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/isDirty.html">isDirty</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/last.html">last</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/list.html">list</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/listOrderBy.html">listOrderBy</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/load.html">load</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/lock.html">lock</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/mapWith.html">mapWith</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/mappedBy.html">mappedBy</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/mapping.html">mapping</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/merge.html">merge</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/namedQueries.html">namedQueries</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/properties.html">properties</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/read.html">read</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/refresh.html">refresh</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/removeFrom.html">removeFrom</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/save.html">save</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/transients.html">transients</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/validate.html">validate</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/where.html">where</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/whereAny.html">whereAny</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/withCriteria.html">withCriteria</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/withNewSession.html">withNewSession</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/withSession.html">withSession</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Domain%20Classes/withTransaction.html">withTransaction</a> |
| </div> |
| |
| </div> |
| </div> |
| |
| <div class="menu-block"><h1 class="menu-title" onclick="toggleRef(this.parentNode.childNodes[1])">Plug-ins</h1><div class="menu-sub"> |
| |
| <div class="menu-item"><a href="../ref/Plug-ins/Usage.html">Usage</a></div> |
| |
| |
| <div class="menu-item"><a href="../ref/Plug-ins/URL%20mappings.html">URL mappings</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Plug-ins/codecs.html">codecs</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Plug-ins/controllers.html">controllers</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Plug-ins/core.html">core</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Plug-ins/dataSource.html">dataSource</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Plug-ins/domainClasses.html">domainClasses</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Plug-ins/hibernate.html">hibernate</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Plug-ins/i18n.html">i18n</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Plug-ins/logging.html">logging</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Plug-ins/scaffolding.html">scaffolding</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Plug-ins/services.html">services</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Plug-ins/servlets.html">servlets</a> |
| </div> |
| |
| </div> |
| </div> |
| |
| <div class="menu-block"><h1 class="menu-title" onclick="toggleRef(this.parentNode.childNodes[1])">Services</h1><div class="menu-sub"> |
| |
| <div class="menu-item"><a href="../ref/Services/Usage.html">Usage</a></div> |
| |
| |
| <div class="menu-item"><a href="../ref/Services/scope.html">scope</a> |
| </div> |
| |
| </div> |
| </div> |
| |
| <div class="menu-block"><h1 class="menu-title" onclick="toggleRef(this.parentNode.childNodes[1])">Servlet API</h1><div class="menu-sub"> |
| |
| |
| <div class="menu-item"><a href="../ref/Servlet%20API/request.html">request</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Servlet%20API/response.html">response</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Servlet%20API/servletContext.html">servletContext</a> |
| </div> |
| |
| <div class="menu-item"><a href="../ref/Servlet%20API/session.html">session</a> |
| </div> |
| |
| </div> |
| </div> |
| |
| </div> |
| </div> |
| </td> |
| </tr> |
| </table> |
| |
| <div id="footer"> |
| Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically. |
| |
| </div> |
| |
| <script type="text/javascript" src="../js/docs.js"></script> |
| |
| </body> |
| </html> |