blob: 686f70f86f0a1b2d0940635fcd6ba75c41dfee02 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.3">
<link rel="apple-touch-icon" sizes="180x180" href="/img/favicon/apple-touch-icon-04cb17e028.png">
<link rel="icon" type="image/png" sizes="32x32" href="/img/favicon/favicon-32x32-12431ee8eb.png">
<link rel="icon" type="image/png" sizes="16x16" href="/img/favicon/favicon-16x16-4f316e4d55.png">
<link rel="manifest" href="/img/favicon/manifest-65e6aaa49e.json">
<link rel="mask-icon" href="/img/favicon/safari-pinned-tab-558c1991b1.svg" color="#dc5656">
<link rel="shortcut icon" href="/img/favicon/favicon-6cef91375b.ico">
<meta name="msapplication-TileColor" content="#ffffff">
<meta name="msapplication-TileImage" content="/img/favicon/mstile-144x144-34e7696278.png">
<meta name="msapplication-config" content="/img/favicon/browserconfig-82ff158058.xml">
<meta name="theme-color" content="#ffffff">
<link rel="stylesheet" href="https://cayenne.apache.org/css/styles-9ee2e6e330.css"/>
<script src="https://cayenne.apache.org/js/bundle-c0e6356367.js"></script>
<title>Cayenne Database First tutorial &middot; Apache Cayenne</title>
</head>
<body data-spy="scroll" data-target=".toc-side" class="cd-head">
<header class="page-header">
<nav id="topbar" class="bg-dark" aria-label="breadcrumb" role="navigation">
<ul class="breadcrumb breadcrumb-sm breadcrumb-dark container mb-0">
<li class="breadcrumb-item dropdown">
<a class="dropdown-toggle text-nowrap pr-1" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<img class="mw-15px mr-1" src="/img/feather-641aa69d09.svg" />Apache Software Foundation</a>
<div class="dropdown-menu rounded-0" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="https://www.apache.org">Apache Homepage</a>
<a class="dropdown-item" href="https://www.apache.org/licenses/">License</a>
<a class="dropdown-item" href="https://www.apache.org/foundation/sponsorship.html">Sponsorship</a>
<a class="dropdown-item" href="https://www.apache.org/foundation/thanks.html">Thanks</a>
<a class="dropdown-item" href="https://www.apache.org/security/">Security</a>
<a class="dropdown-item" href="https://privacy.apache.org/policies/privacy-policy-public.html">Privacy</a>
<a class="ml-1 mt-1 acevent" data-format="wide" data-mode="dark" data-width="120"></a>
</div>
</li>
</ul>
</nav>
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<div class="container">
<a class="navbar-brand" href="https://cayenne.apache.org/">
<img src="/img/logo_mono_full-d7a19eef61.svg" alt="Apache Cayenne" />
</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#mainMenu" aria-controls="mainMenu" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="mainMenu">
<ul class="navbar-nav mt-3 mt-lg-0 mr-auto">
<li class="nav-item">
<a class="nav-link" href="/download/">DOWNLOAD</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/docs/4.2/getting-started-guide/">DOCUMENTATION</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/about/support/">SUPPORT</a>
</li>
</ul>
<ul class="navbar-nav flex-row justify-content-center mt-2 mt-lg-0 mb-2 mb-lg-0 " id="social-links-menu">
<li class="nav-item d-flex">
<a class="nav-link d-flex justify-content-center align-items-center" href="https://github.com/apache/cayenne">
<img src="/img/icon_octocat_stars-c24dac94b8.svg" alt="GitHub" />
</a>
</li>
<li class="nav-item d-flex">
<a class="nav-link d-flex justify-content-center align-items-center" href="https://twitter.com/ApacheCayenne">
<img src="/img/icon_twitter-220a129d14.svg" alt="Twitter" />
</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<main>
<div class="cd-top-sidebar bb">
<div class="container">
<div class="row no-gutters">
<div class="col-12 col-lg-4 col-xl-3 br cd-sidebar1">
<ul class="nav" role="tablist">
<li class="nav-item dropdown mw-100">
<a class="nav-link dropdown-toggle text-truncate" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">
Cayenne Version 4.1
</a>
<div class="dropdown-menu">
<a class="dropdown-item" href="/docs/5.0/cayenne-guide/">Version 5.0 (Alpha)</a><a class="dropdown-item" href="/docs/4.2/getting-started-guide/">Version 4.2 (Stable)</a><a class="dropdown-item" href="/docs/4.1/getting-started-guide/">Version 4.1 (Stable)</a><a class="dropdown-item" href="/docs/4.0/getting-started-guide/">Version 4.0 (Aging)</a><a class="dropdown-item" href="/docs/3.1/getting-started-guide/">Version 3.1 (Legacy)</a>
</div>
</li>
</ul>
</div>
<div class="col-12 col-lg-8 col-xl-9"> </div>
</div>
</div>
</div>
<div class="container">
<div class="row no-gutters ">
<div class="col-12 col-lg-4 col-xl-3 br py-2 bg-gray-100 cd-sidebar">
<div class="tab-content" id="cd-docs-nav">
<div class="cd-toc-item">
<a class="cd-toc-link" href="/docs/4.1/getting-started-guide/">Getting Started</a>
</div>
<div class="cd-toc-item">
<a class="cd-toc-link" href="/docs/4.1/cayenne-guide/">Cayenne Guide</a>
</div>
<div class="cd-toc-item">
<span class="cd-toc-link active">Database First Tutorial</span><div id="toc" class="toc toc-side">
<div id="toctitle">
Table of Contents
</div>
<ul class="sectlevel1 nav">
<li><a href="#setup" class="nav-link">1. Setup</a>
<ul class="sectlevel2 nav">
<li><a href="#prerequisites" class="nav-link">1.1. Prerequisites</a></li>
<li><a href="#maven-project" class="nav-link">1.2. Maven Project</a></li>
</ul> </li>
<li><a href="#importing-database" class="nav-link">2. Importing database</a>
<ul class="sectlevel2 nav">
<li><a href="#reverse-engineering-database" class="nav-link">2.1. Reverse engineering database</a></li>
</ul> </li>
<li><a href="#advanced-usage-of-cdbimport" class="nav-link">3. Advanced usage of cdbimport</a>
<ul class="sectlevel2 nav">
<li><a href="#updating-model" class="nav-link">3.1. Updating model</a></li>
<li><a href="#advanced-filtering" class="nav-link">3.2. Advanced filtering</a></li>
</ul> </li>
<li><a href="#java-code" class="nav-link">4. Java code</a>
<ul class="sectlevel2 nav">
<li><a href="#generating-java-classes" class="nav-link">4.1. Generating Java classes</a></li>
<li><a href="#getting-started-with-objectcontext" class="nav-link">4.2. Getting started with ObjectContext</a></li>
</ul> </li>
<li><a href="#whats-next" class="nav-link">5. What’s next</a></li>
</ul>
</div>
</div>
<div class="cd-toc-item">
<a class="cd-toc-link" href="/docs/4.1/getting-started-rop/">Getting Started ROP</a>
</div>
<div class="cd-toc-item">
<a class="cd-toc-link" href="/docs/4.1/upgrade-guide/">Upgrade Guide</a>
</div>
<div class="cd-toc-item">
<a class="cd-toc-link" href="/docs/4.1/api/">JavaDoc</a></div>
</div>
</div>
<div class="col-12 col-lg-8 col-xl-9 py-3 pl-lg-5 cd-content">
<article>
<header>
<h1>Cayenne Database First tutorial</h1>
</header>
<section>
<div class="sect1">
<h2 id="setup"><a class="anchor" href="#setup"></a>1. Setup</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="prerequisites"><a class="anchor" href="#prerequisites"></a>1.1. Prerequisites</h3>
<div class="paragraph">
<p>You can start with this tutorial, or you can do "Getting Started with Cayenne" first and then continue with this tutorial.</p>
</div>
<div class="paragraph">
<p>This chapter lists the recommended software used in the tutorial.</p>
</div>
<div class="sect3">
<h4 id="java"><a class="anchor" href="#java"></a>1.1.1. Java</h4>
<div class="paragraph">
<p>Cayenne 4.1 requires JDK 1.8 or newer.</p>
</div>
</div>
<div class="sect3">
<h4 id="intellij-idea-ide"><a class="anchor" href="#intellij-idea-ide"></a>1.1.2. IntelliJ IDEA IDE</h4>
<div class="paragraph">
<p>Download and install the free IntelliJ IDEA Community Edition IDE. This tutorial uses version 2017.1, but any recent IntelliJ IDEA version and edition will do.</p>
</div>
</div>
<div class="sect3">
<h4 id="maven"><a class="anchor" href="#maven"></a>1.1.3. Maven</h4>
<div class="paragraph">
<p>Two Maven plugins are used:</p>
</div>
<div class="ulist">
<ul>
<li> <p><strong>cayenne-maven-plugin</strong> - among other things, allows to reverse-engineer the Cayenne model from the database and to update the model after the database has been changed.</p> </li>
<li> <p><strong>cayenne-modeler-maven-plugin</strong> - provides a convenient way of starting the Cayenne Modeler</p> </li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="mysql"><a class="anchor" href="#mysql"></a>1.1.4. MySQL</h4>
<div class="paragraph">
<p>MySQL database server is used for demonstrating Cayenne’s ability to read the DB schema and to build/update the Cayenne model from it.</p>
</div>
<div class="paragraph">
<p>You can create test database with any tools you comfortable with, here is full DB schema that will be used in this tutorial:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-sql sql" data-lang="sql">CREATE SCHEMA IF NOT EXISTS cayenne_demo; USE cayenne_demo;
CREATE TABLE artist (DATE_OF_BIRTH DATE NULL, ID INT NOT NULL AUTO_INCREMENT, NAME VARCHAR(200) NULL, PRIMARY KEY (ID)) ENGINE=InnoDB;
CREATE TABLE gallery (ID INT NOT NULL AUTO_INCREMENT, NAME VARCHAR(200) NULL, PRIMARY KEY (ID)) ENGINE=InnoDB;
CREATE TABLE painting (ARTIST_ID INT NULL, GALLERY_ID INT NULL, ID INT NOT NULL AUTO_INCREMENT, NAME VARCHAR(200) NULL, PRIMARY KEY (ID)) ENGINE=InnoDB;
ALTER TABLE painting ADD FOREIGN KEY (ARTIST_ID) REFERENCES artist (ID) ON DELETE CASCADE;
ALTER TABLE painting ADD FOREIGN KEY (GALLERY_ID) REFERENCES gallery (ID) ON DELETE CASCADE;</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can save it to <code>cayenne_demo.sql</code> file and import to your database with following command:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>$ mysql &lt; cayenne_demo.sql</pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="maven-project"><a class="anchor" href="#maven-project"></a>1.2. Maven Project</h3>
<div class="paragraph">
<p>The goal of this chapter is to create a new Java project in IntelliJ IDEA and to setup Maven Cayenne plugin</p>
</div>
<div class="sect3">
<h4 id="create-a-new-project-in-intellij-idea"><a class="anchor" href="#create-a-new-project-in-intellij-idea"></a>1.2.1. Create a new Project in IntelliJ IDEA</h4>
<div class="paragraph">
<p>In IntelliJ IDEA select <code>File &gt; New &gt; Project…​</code> and then select "Maven" and click "Next". In the dialog shown on the screenshot below, fill the "Group Id" and "Artifact Id" fields and click "Next".</p>
</div>
<div class="imageblock" style="text-align: center">
<div class="content">
<img src="images/tutorial-idea-project.png" alt="tutorial idea project">
</div>
</div>
<div class="paragraph">
<p>On next dialog screen you can customize directory for your project and click "Finish". Now you should have a new empty project.</p>
</div>
</div>
<div class="sect3">
<h4 id="plugin-setup"><a class="anchor" href="#plugin-setup"></a>1.2.2. Plugin setup</h4>
<div class="paragraph">
<p>Next step is setting up Cayenne plugin in <code>pom.xml</code> file. For the convenience let’s define Cayenne version that we will use across project file:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml xml" data-lang="xml">&lt;properties&gt;
&lt;cayenne.version&gt;4.1.1&lt;/cayenne.version&gt;
&lt;/properties&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Next step is to include plugin. Here is code snippet that enable <code>cayenne-maven-plugin</code> in our demo project:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml xml" data-lang="xml">&lt;build&gt;
&lt;plugins&gt;
&lt;plugin&gt;
&lt;groupId&gt;org.apache.cayenne.plugins&lt;/groupId&gt;
&lt;artifactId&gt;cayenne-maven-plugin&lt;/artifactId&gt;
&lt;version&gt;${cayenne.version}&lt;/version&gt;
&lt;/plugin&gt;
&lt;/plugins&gt;
&lt;/build&gt;</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="importing-database"><a class="anchor" href="#importing-database"></a>2. Importing database</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="reverse-engineering-database"><a class="anchor" href="#reverse-engineering-database"></a>2.1. Reverse engineering database</h3>
<div class="paragraph">
<p>Now we have everything ready and can proceed to importing Cayenne model from our Mysql database</p>
</div>
<div class="sect3">
<h4 id="configuring-plugin"><a class="anchor" href="#configuring-plugin"></a>2.1.1. Configuring plugin</h4>
<div class="paragraph">
<p>To let Cayenne plugin do its job we must tell it what to import and where it should get data. So let’s begin, here is sample settings for the data source:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml xml" data-lang="xml">&lt;plugin&gt;
...
&lt;configuration&gt;
&lt;dataSource&gt;
&lt;driver&gt;com.mysql.jdbc.Driver&lt;/driver&gt;
&lt;url&gt;jdbc:mysql://127.0.0.1:3306/cayenne_demo&lt;/url&gt;
&lt;username&gt;root&lt;/username&gt;
&lt;password&gt;your-mysql-password&lt;/password&gt;
&lt;/dataSource&gt;
&lt;/configuration&gt;
&lt;dependencies&gt;
&lt;dependency&gt;
&lt;groupId&gt;mysql&lt;/groupId&gt;
&lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;
&lt;version&gt;6.0.5&lt;/version&gt;
&lt;/dependency&gt;
&lt;/dependencies&gt;</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa fa-info-circle fa-2x" title="Note"></i> </td>
<td class="content"> Don’t forget to set your actual MySQL login and password </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>We have told plugin where it should load data from, now let’s set where it should store Cayenne model:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml xml" data-lang="xml">&lt;configuration&gt;
...
&lt;/dataSource&gt;
&lt;cayenneProject&gt;${project.basedir}/src/main/resources/cayenne/cayenne-project.xml&lt;/cayenneProject&gt;
&lt;map&gt;${project.basedir}/src/main/resources/datamap.map.xml&lt;/map&gt;
...</code></pre>
</div>
</div>
<div class="paragraph">
<p>And a last small step we need to do is to set default package where our model classes will be and catalog where our tables are:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml xml" data-lang="xml">&lt;configuration&gt;
...&lt;/map&gt;
&lt;dbImport&gt;
&lt;defaultPackage&gt;org.apache.cayenne.tutorial.persistent&lt;/defaultPackage&gt;
&lt;catalog&gt;cayenne_demo&lt;/catalog&gt;
&lt;/dbImport&gt;</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="running-plugin"><a class="anchor" href="#running-plugin"></a>2.1.2. Running plugin</h4>
<div class="paragraph">
<p>Finally we can run db import, it is as easy as just running this command in terminal:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>$ mvn cayenne:cdbimport</pre>
</div>
</div>
<div class="paragraph">
<p>If everything was setup properly you should see output like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>...
[INFO] +++ Connecting: SUCCESS.
[INFO] Detected and installed adapter: org.apache.cayenne.dba.mysql.MySQLAdapter
[INFO] Table: cayenne_demo.artist
[INFO] Table: cayenne_demo.gallery
[INFO] Table: cayenne_demo.painting
[INFO] Db Relationship : toOne (painting.GALLERY_ID, gallery.ID)
[INFO] Db Relationship : toMany (gallery.ID, painting.GALLERY_ID)
[INFO] Db Relationship : toOne (painting.ARTIST_ID, artist.ID)
[INFO] Db Relationship : toMany (artist.ID, painting.ARTIST_ID)
[INFO]
[INFO] Map file does not exist. Loaded db model will be saved into '~/work/cayenne/db-first-tutorial/src/main/resources/datamap.map.xml'
[INFO]
[INFO] Detected changes:
[INFO] Create Table artist
[INFO] Create Table painting
[INFO] Create Table gallery
[INFO]
[WARNING] Can't find ObjEntity for painting
[WARNING] Db Relationship (Db Relationship : toMany (artist.ID, painting.ARTIST_ID)) will have GUESSED Obj Relationship reflection.
[WARNING] Can't find ObjEntity for gallery
[WARNING] Db Relationship (Db Relationship : toOne (painting.GALLERY_ID, gallery.ID)) will have GUESSED Obj Relationship reflection.
[INFO] Migration Complete Successfully.</pre>
</div>
</div>
<div class="paragraph">
<p>You can open created <code>datamap.map.xml</code> file and check it’s content in IDEA:</p>
</div>
<div class="imageblock" style="text-align: center">
<div class="content">
<img src="images/tutorial-new-datamap.png" alt="tutorial new datamap">
</div>
</div>
<div class="paragraph">
<p>Great! We now have Cayenne DataMap file that describe model from our database and cayenne-project.xml file.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa fa-info-circle fa-2x" title="Note"></i> </td>
<td class="content"> If you have some problems with configuration you can always delete <code>datamap.map.xml</code> file and try again. </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="setup-modeler-maven-plugin"><a class="anchor" href="#setup-modeler-maven-plugin"></a>2.1.3. Setup Modeler Maven plugin</h4>
<div class="paragraph">
<p>Cayenne Modeler can be helpful in case you want to make some customizations to your model, though it’s usage optional.</p>
</div>
<div class="paragraph">
<p>To launch Modeler we’ll use <code>cayenne-modeler-maven-plugin</code>. Just include it in <code>pom.xml</code> like we did with <code>cayenne-maven-plugin</code> and tell where your project is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml xml" data-lang="xml">&lt;plugin&gt;
&lt;groupId&gt;org.apache.cayenne.plugins&lt;/groupId&gt;
&lt;artifactId&gt;cayenne-modeler-maven-plugin&lt;/artifactId&gt;
&lt;version&gt;${cayenne.version}&lt;/version&gt;
&lt;configuration&gt;
&lt;modelFile&gt;${project.basedir}/src/main/resources/cayenne-project.xml&lt;/modelFile&gt;
&lt;/configuration&gt;
&lt;/plugin&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>To launch it simply run:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>$ mvn cayenne-modeler:run</pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="advanced-usage-of-cdbimport"><a class="anchor" href="#advanced-usage-of-cdbimport"></a>3. Advanced usage of cdbimport</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="updating-model"><a class="anchor" href="#updating-model"></a>3.1. Updating model</h3>
<div class="paragraph">
<p>We now have everything we need, let’s try some more features of plugin.</p>
</div>
<div class="sect3">
<h4 id="update-ddl"><a class="anchor" href="#update-ddl"></a>3.1.1. Update DDL</h4>
<div class="paragraph">
<p>To show next feature let’s imagine that over some time our database schema has evolved and we need to synchronize it with our model, no problem we can simply run <code>cdbimport</code> again and all changes will be loaded to model. We use following SQL script to alter our demo database:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-sql sql" data-lang="sql">CREATE TABLE cayenne_demo.painting_info (INFO VARCHAR(255) NULL, PAINTING_ID INT NOT NULL, PRIMARY KEY (PAINTING_ID)) ENGINE=InnoDB;
ALTER TABLE cayenne_demo.gallery ADD COLUMN FOUNDED_DATE DATE;
ALTER TABLE cayenne_demo.painting_info ADD FOREIGN KEY (PAINTING_ID) REFERENCES cayenne_demo.painting (ID);</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="run-cdbimport"><a class="anchor" href="#run-cdbimport"></a>3.1.2. Run cdbimport</h4>
<div class="paragraph">
<p>Now we can simply run again</p>
</div>
<div class="listingblock">
<div class="content">
<pre>$ mvn cayenne:cdbimport</pre>
</div>
</div>
<div class="paragraph">
<p>You should see output similar to this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>...
[INFO] Table: cayenne_demo.artist
[INFO] Table: cayenne_demo.gallery
[INFO] Table: cayenne_demo.painting
[INFO] Table: cayenne_demo.painting_info
[INFO] Db Relationship : toOne (painting_info.PAINTING_ID, painting.ID)
[INFO] Db Relationship : toOne (painting.ID, painting_info.PAINTING_ID)
[INFO] Db Relationship : toOne (painting.GALLERY_ID, gallery.ID)
[INFO] Db Relationship : toMany (gallery.ID, painting.GALLERY_ID)
[INFO] Db Relationship : toOne (painting.ARTIST_ID, artist.ID)
[INFO] Db Relationship : toMany (artist.ID, painting.ARTIST_ID)
[INFO]
[INFO] Detected changes:
[INFO] Create Table painting_info
[INFO] Add Column gallery.FOUNDED_DATE
[INFO] Add Relationship paintingInfo painting-&gt;painting_info.PAINTING_ID
[INFO]
[INFO] Migration Complete Successfully.</pre>
</div>
</div>
<div class="paragraph">
<p>Let’s run Modeler and check that all changes are present in our model:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>$ mvn cayenne-modeler:run</pre>
</div>
</div>
<div class="imageblock" style="text-align: center">
<div class="content">
<img src="images/tutorial-update-model.png" alt="tutorial update model">
</div>
</div>
<div class="paragraph">
<p>Great! New table and ObjEntity are in place, as well as a new field.</p>
</div>
</div>
<div class="sect3">
<h4 id="customizing-model"><a class="anchor" href="#customizing-model"></a>3.1.3. Customizing Model</h4>
<div class="paragraph">
<p>There is often a need to customize model to better fit it to your application requirements, such customization can be simple removal of toMany part of a relationship between two objects. Let’s do it, in a Modeler just select and remove relationship <code>paintings</code> in Artist object:</p>
</div>
<div class="imageblock" style="text-align: center">
<div class="content">
<img src="images/tutorial-drop-relationship.png" alt="tutorial drop relationship">
</div>
</div>
<div class="paragraph">
<p>Now if you run</p>
</div>
<div class="listingblock">
<div class="content">
<pre>$ mvn cayenne:cdbimport</pre>
</div>
</div>
<div class="paragraph">
<p>it still find nothing to do:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>...
[INFO] Detected changes: No changes to import.</pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa fa-info-circle fa-2x" title="Note"></i> </td>
<td class="content"> <code>cdbimport</code> will skip only modifications in Object layer (e.g. ObjEntities, ObjAttributes and ObjRelationships), if you modify Db layer your changes will be overridden by next run of <code>cdbimport</code>. </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="sect2">
<h3 id="advanced-filtering"><a class="anchor" href="#advanced-filtering"></a>3.2. Advanced filtering</h3>
<div class="paragraph">
<p>Final part of our tutorial is about fine-tuning what you load from DB into your model.</p>
</div>
<div class="sect3">
<h4 id="update-schema"><a class="anchor" href="#update-schema"></a>3.2.1. Update schema</h4>
<div class="paragraph">
<p>Let’s add some information to our database, that we don’t need in our model:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-sql sql" data-lang="sql">CREATE TABLE cayenne_demo.legacy_painting_info (ID INT NOT NULL AUTO_INCREMENT, INFO VARCHAR(255) NULL, PAINTING_ID INT NOT NULL, PRIMARY KEY (ID)) ENGINE=InnoDB;
ALTER TABLE cayenne_demo.artist ADD COLUMN __service_column INT;
ALTER TABLE cayenne_demo.gallery ADD COLUMN __service_column INT;
ALTER TABLE cayenne_demo.painting ADD COLUMN __service_column INT;</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="configure-filtering"><a class="anchor" href="#configure-filtering"></a>3.2.2. Configure filtering</h4>
<div class="paragraph">
<p>Now we need to tell <code>cdbimport</code> what we don’t need in our model, for that we’ll just add following into <code>&lt;configuration&gt;</code> section:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml xml" data-lang="xml">&lt;excludeTable&gt;legacy_painting_info&lt;/excludeTable&gt;
&lt;excludeColumn&gt;__service_column&lt;/excludeColumn&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>After runing</p>
</div>
<div class="listingblock">
<div class="content">
<pre>$ mvn cayenne:cdbimport</pre>
</div>
</div>
<div class="paragraph">
<p>we still don’t get any changes, exactly as expected:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>...
[INFO] Detected changes: No changes to import.</pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="java-code"><a class="anchor" href="#java-code"></a>4. Java code</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="generating-java-classes"><a class="anchor" href="#generating-java-classes"></a>4.1. Generating Java classes</h3>
<div class="paragraph">
<p>Now as we have our model ready let’s generate Java code that actually will be used in application. In order to do that we’ll use same maven plugin, but different goal, namely <code>cgen</code>. It has many options to configure but default values will do for our case, so we can just call it:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>$ mvn cayenne:cgen</pre>
</div>
</div>
<div class="paragraph">
<p>You should see output telling that everything is done, like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>[INFO] Generating superclass file: .../src/main/java/org/apache/cayenne/tutorial/persistent/auto/_Artist.java
[INFO] Generating class file: .../src/main/java/org/apache/cayenne/tutorial/persistent/Artist.java
[INFO] Generating superclass file: .../src/main/java/org/apache/cayenne/tutorial/persistent/auto/_Gallery.java
[INFO] Generating class file: .../src/main/java/org/apache/cayenne/tutorial/persistent/Gallery.java
[INFO] Generating superclass file: .../src/main/java/org/apache/cayenne/tutorial/persistent/auto/_Painting.java
[INFO] Generating class file: .../src/main/java/org/apache/cayenne/tutorial/persistent/Painting.java
[INFO] Generating superclass file: .../src/main/java/org/apache/cayenne/tutorial/persistent/auto/_PaintingInfo.java
[INFO] Generating class file: .../src/main/java/org/apache/cayenne/tutorial/persistent/PaintingInfo.java
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------</pre>
</div>
</div>
<div class="paragraph">
<p>In IDEA you should be able to see these newly generated classes:</p>
</div>
<div class="imageblock" style="text-align: center">
<div class="content">
<img src="images/tutorial-java-classes.png" alt="tutorial java classes">
</div>
</div>
<div class="paragraph">
<p>Note that Cayenne code is unrecognized, that’s because we need to include Cayenne as dependency, let’s do this in <code>pom.xml</code> file:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml xml" data-lang="xml">&lt;project&gt;
...
&lt;dependencies&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.apache.cayenne&lt;/groupId&gt;
&lt;artifactId&gt;cayenne-server&lt;/artifactId&gt;
&lt;version&gt;${cayenne.version}&lt;/version&gt;
&lt;/dependency&gt;
&lt;/dependencies&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Additionally we need to tell <code>Maven compiler plugin</code> that our code uses Java 8:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml xml" data-lang="xml">&lt;build&gt;
&lt;plugins&gt;
...
&lt;plugin&gt;
&lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
&lt;configuration&gt;
&lt;source&gt;1.8&lt;/source&gt;
&lt;target&gt;1.8&lt;/target&gt;
&lt;/configuration&gt;
&lt;/plugin&gt;
...</code></pre>
</div>
</div>
<div class="paragraph">
<p>If all done right your code now shouldn’t have any errors. To be sure you can build it:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>$ mvn compile</pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="getting-started-with-objectcontext"><a class="anchor" href="#getting-started-with-objectcontext"></a>4.2. Getting started with ObjectContext</h3>
<div class="paragraph">
<p>In this section we’ll write a simple main class to run our application, and get a brief introduction to Cayenne <code>ObjectContext</code>.</p>
</div>
<div class="sect3">
<h4 id="creating-the-main-class"><a class="anchor" href="#creating-the-main-class"></a>4.2.1. Creating the Main Class</h4>
<div class="ulist">
<ul>
<li> <p>In IDEA create a new class called <code>Main</code> in the <code>org.apache.cayenne.tutorial</code> package.</p> </li>
<li> <p>Create a standard <code>main()</code> method to make it a runnable class:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java java" data-lang="java">package org.apache.cayenne.tutorial;
public class Main {
public static void main(String[] args) {
}
}</code></pre>
</div>
</div> </li>
<li> <p>The first thing you need to be able to access the database is to create a <code>ServerRuntime</code> object (which is essentially a wrapper around Cayenne stack) and use it to obtain an instance of an <code>ObjectContext</code>.</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java java" data-lang="java">package org.apache.cayenne.tutorial;
import org.apache.cayenne.ObjectContext;
import org.apache.cayenne.configuration.server.ServerRuntime;
public class Main {
public static void main(String[] args) {
ServerRuntime cayenneRuntime = ServerRuntime.builder()
.dataSource(DataSourceBuilder
.url("jdbc:mysql://127.0.0.1:3306/cayenne_demo")
.driver("com.mysql.cj.jdbc.Driver")
.userName("root") // TODO: change to your actual username and password
.password("your-password").build())
.addConfig("cayenne-project.xml")
.build();
ObjectContext context = cayenneRuntime.newContext();
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p><code>ObjectContext</code> is an isolated "session" in Cayenne that provides all needed API to work with data. <code>ObjectContext</code> has methods to execute queries and manage persistent objects. We’ll discuss them in the following sections. When the first ObjectContext is created in the application, Cayenne loads XML mapping files and creates a shared access stack that is later reused by other ObjectContexts.</p>
</div> </li>
<li> <p>Let’s now add some code that will create persistent object:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java java" data-lang="java">Artist artist = context.newObject(Artist.class);
artist.setName("Picasso");
context.commitChanges();</code></pre>
</div>
</div> </li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="running-application"><a class="anchor" href="#running-application"></a>4.2.2. Running Application</h4>
<div class="paragraph">
<p>Let’s check what happens when you run the application. But before we do that we need to add another dependencies to the <code>pom.xml</code> - MySQL Jdbc driver and simple logger. The following piece of XML needs to be added to the <code>&lt;dependencies&gt;…​&lt;/dependencies&gt;</code> section, where we already have Cayenne jars:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml xml" data-lang="xml">&lt;dependency&gt;
&lt;groupId&gt;mysql&lt;/groupId&gt;
&lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;
&lt;version&gt;6.0.5&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.slf4j&lt;/groupId&gt;
&lt;artifactId&gt;slf4j-simple&lt;/artifactId&gt;
&lt;version&gt;1.7.25&lt;/version&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa fa-info-circle fa-2x" title="Note"></i> </td>
<td class="content"> Cayenne uses Slf4j logging API, here we will use simple backend that prints everything to console </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>Now we are ready to run. Right click the "Main" class in IDEA and select "Run 'Main.main()'".</p>
</div>
<div class="imageblock" style="text-align: center">
<div class="content">
<img src="images/idea-file-run-menu.png" alt="idea file run menu">
</div>
</div>
<div class="paragraph">
<p>In the console you’ll see output similar to this, indicating that Cayenne stack has been started:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>[main] INFO: Loading XML configuration resource from file:/.../cayenne-project.xml
[main] INFO: Loading XML DataMap resource from file:/.../datamap.map.xml
...
[main] INFO org.apache.cayenne.datasource.DriverDataSource - +++ Connecting: SUCCESS.
[main] INFO org.apache.cayenne.log.JdbcEventLogger - --- transaction started.
[main] INFO org.apache.cayenne.log.JdbcEventLogger - INSERT INTO cayenne_demo.artist (DATE_OF_BIRTH, NAME) VALUES (?, ?)
[main] INFO org.apache.cayenne.log.JdbcEventLogger - [bind: 1-&gt;DATE_OF_BIRTH:NULL, 2-&gt;NAME:'Picasso']
[main] INFO org.apache.cayenne.log.JdbcEventLogger - Generated PK: ARTIST.ID = 2
[main] INFO org.apache.cayenne.log.JdbcEventLogger - === updated 1 row.
[main] INFO org.apache.cayenne.log.JdbcEventLogger - +++ transaction committed.</pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="whats-next"><a class="anchor" href="#whats-next"></a>5. What’s next</h2>
<div class="sectionbody">
<div class="paragraph">
<p>That’s all for this tutorial! Now you know how to setup and use <code>cayenne-maven-plugin</code>.</p>
</div>
<div class="paragraph">
<p>Next step will be creating your first application with Cayenne. If you not passed yet, you can try out <a href="/docs/4.1/getting-started-guide/">getting-started</a> tutorial.</p>
</div>
<div class="paragraph">
<p>You can find detailed information about configuring this plugin in <a href="/docs/4.1/cayenne-guide/#include">documentation</a> available on Cayenne site.</p>
</div>
</div>
</div>
</section>
<footer>
<div class="row">
<div class="col-6 col-md-3 text-center text-md-left">
&nbsp;
</div>
<div class="col-18 col-md-9 text-center text-md-right">
<a class="btn btn-link" href='/docs/4.1/getting-started-rop/'>
<span class="d-block d-md-none text-muted">Next: </span>
Next: Cayenne Getting Started ROP
<i class="small fa fa-chevron-right ml-3l2 d-none d-md-inline"></i>
</a>
</div>
</div>
</footer>
</article>
<img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=5c836e39-be6b-4a21-a946-a97b5b69f172" />
</div>
</div>
</div>
</main>
<footer class="bg-dark">
<div class="footer-nav container text-center text-lg-left pb-3">
<div class="row pt-5 pb-3">
<div class="col-sm-6 col-lg-3">
<h4>About</h4>
<ul class="list-unstyled">
<li>
<a href="/why-cayenne.html">Why Cayenne?</a>
</li>
<li>
<a href="/download/">Download</a>
</li>
<li>
<a href="/success-stories.html">Success Stories</a>
</li>
<li>
<a href="/about/support/">Support</a>
</li>
</ul>
</div>
<div class="col-sm-6 col-lg-3">
<h4>Documentation</h4>
<ul class="list-unstyled">
<li>
<a href="/docs/4.0/getting-started-guide/">Getting Started (4.0)</a>
</li>
<li>
<a href="/docs/4.1/getting-started-guide/">Getting Started (4.1)</a>
</li>
<li>
<a href="/docs/4.2/getting-started-guide/">Getting Started (4.2)</a>
</li>
<li>
<a href="/docs/4.0/cayenne-guide/">Cayenne Guide (4.0)</a>
</li>
<li>
<a href="/docs/4.1/cayenne-guide/">Cayenne Guide (4.1)</a>
</li>
<li>
<a href="/docs/4.2/cayenne-guide/">Cayenne Guide (4.2)</a>
</li>
<li>
<a href="/docs/4.1/getting-started-db-first/">Database First tutorial (4.1)</a>
</li>
<li>
<a href="/docs/4.2/getting-started-db-first/">Database First tutorial (4.2)</a>
</li>
<li>
<a href="/legacy/legacy-docs/">Legacy Documentation</a>
</li>
</ul>
</div>
<div class="col-sm-6 col-lg-3">
<h4>Collaboration</h4>
<ul class="list-unstyled">
<li>
<a href="https://issues.apache.org/jira/browse/CAY">Bug/Feature Tracker</a>
</li>
<li>
<a href="/mailing-lists.html">Mailing Lists</a>
</li>
<li>
<a href="/dev/code-repository.html">Code Repository</a>
</li>
<li>
<a href="/dev/">Developer Guide</a>
</li>
<li>
<a href="/how-can-i-help.html">How can I help?</a>
</li>
<li>
<a href="/contributors.html">Contributors</a>
</li>
<li>
<a href="/thanks.html">Thanks</a>
</li>
</ul>
</div>
<div class="col-sm-6 col-lg-3">
<h4>News</h4>
<ul class="list-multiline-items list-unstyled mb-0">
<li>
<time datetime="2023-05-25 18:00:00 &#43;0300 &#43;0300" class="xsmall d-block">May 25, 2023</time>
<a href="/2023/05/cayenne-42-final-released/">Cayenne 4.2 Final Released</a>
</li>
<li>
<time datetime="2023-03-02 12:00:00 &#43;0300 &#43;0300" class="xsmall d-block">Mar 02, 2023</time>
<a href="/2023/03/cayenne-403-released/">Cayenne 4.0.3 Released</a>
</li>
<li>
<time datetime="2022-12-05 12:00:00 &#43;0300 &#43;0300" class="xsmall d-block">Dec 05, 2022</time>
<a href="/2022/12/cayenne-42rc2-released/">Cayenne 4.2 Release Candidate 2 Released</a>
</li>
</ul>
<a class="btn-link text-uppercase xsmall" href="https://cayenne.apache.org/news">
More news
<i class="fa fa-lg fa-long-arrow-right" aria-hidden="true"></i>
</a>
</div>
</div>
<hr class="mt-0 mb-3" />
<p class="copy xsmall text-center mw-75 mx-auto mb-0">
Copyright © 2001-2024 Apache Software Foundation. Apache Cayenne, Cayenne, Apache, the Apache feather logo, and the Apache Cayenne project logo are trademarks of The Apache Software Foundation.
<a href="https://privacy.apache.org/policies/privacy-policy-public.html">Privacy policy</a>.
<img class="d-block mx-auto mt-2" src="/img/logo_mono-3302daa3cf.svg" alt="Apache Cayenne" />
</p>
</div>
</footer>
</body>
</html>