| <html><head> |
| <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> |
| <title xmlns:d="http://docbook.org/ns/docbook">Chapter 3. Learning Cayenne API</title><link rel="stylesheet" type="text/css" href="css/cayenne-doc.css"><meta xmlns:d="http://docbook.org/ns/docbook" name="keywords" content="Cayenne 4.0 documentation"><meta xmlns:d="http://docbook.org/ns/docbook" name="description" content="User documentation for Apache Cayenne version 4.0"><link rel="home" href="index.html" title="Getting Started with Cayenne"><link rel="up" href="index.html" title="Getting Started with Cayenne"><link rel="prev" href="getting-started-part2.html" title="Chapter 2. Learning mapping basics"><link rel="next" href="getting-started-part4.html" title="Chapter 4. Converting to Web Application"><script xmlns:d="http://docbook.org/ns/docbook" type="text/javascript"> |
| var _gaq = _gaq || []; |
| _gaq.push(['_setAccount', 'UA-7036673-1']); |
| _gaq.push(['_trackPageview']); |
| (function() { |
| var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; |
| ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; |
| var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); |
| })(); |
| </script></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div xmlns:d="http://docbook.org/ns/docbook" class="navheader"><table width="100%" summary="Navigation header"><tr><th class="versioninfo">v.4.0 (4.0.M5)</th><th align="center">Chapter 3. Learning Cayenne API</th><th></th></tr><tr><td width="20%" align="left"><a accesskey="p" href="getting-started-part2.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="getting-started-part4.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="getting-started-part3"></a>Chapter 3. Learning Cayenne API</h1></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="section"><a href="getting-started-part3.html#d0e414">Getting started with ObjectContext</a></span></dt><dt><span class="section"><a href="getting-started-part3.html#d0e485">Getting started with persistent objects</a></span></dt><dt><span class="section"><a href="getting-started-part3.html#d0e565">Selecting Objects</a></span></dt><dt><span class="section"><a href="getting-started-part3.html#d0e610">Deleting Objects</a></span></dt></dl></div><div class="section"><div class="titlepage"><div><div><h2 class="title"><a name="d0e414"></a>Getting started with ObjectContext</h2></div></div></div><p>In this section we'll write a simple main class to run our application, and get a brief |
| introduction to Cayenne ObjectContext.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="creating-main-class"></a>Creating the Main Class</h3></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>In IDEA create a new class called "<code class="code">Main</code>" in the "<code class="code">org.example.cayenne</code>" |
| package.</p></li><li class="listitem"><p>Create a standard "main" method to make it a runnable |
| class:</p><pre class="programlisting"><span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">package</span> org.example.cayenne; |
| |
| <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">public</span> <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">class</span> Main { |
| |
| <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">public</span> <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">static</span> <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">void</span> main(String[] args) { |
| |
| } |
| }</pre></li><li class="listitem"><p>The first thing you need to be able to access the database is to create a |
| <code class="code">ServerRuntime</code> object (which is essentially a wrapper around Cayenne stack) and |
| use it to obtain an instance of an |
| <code class="code">ObjectContext</code>.</p><pre class="programlisting"><span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">package</span> org.example.cayenne; |
| |
| <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">import</span> org.apache.cayenne.ObjectContext; |
| <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">import</span> org.apache.cayenne.configuration.server.ServerRuntime; |
| |
| <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">public</span> <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">class</span> Main { |
| |
| <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">public</span> <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">static</span> <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">void</span> main(String[] args) { |
| ServerRuntime cayenneRuntime = ServerRuntime.builder() |
| .addConfig(<span xmlns="http://www.w3.org/1999/xhtml" class="hl-string">"cayenne-project.xml"</span>) |
| .build(); |
| ObjectContext context = cayenneRuntime.newContext(); |
| } |
| }</pre><p><code class="code">ObjectContext</code> is an isolated "session" in Cayenne that provides all needed API |
| to work with data. ObjectContext 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></li></ul></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="runnning-app"></a>Running Application</h3></div></div></div><p>Let's check what happens when you run the application. But before we do that we need |
| to add another dependency to the <code class="code">pom.xml</code> - Apache Derby, our embedded database engine. |
| The following piece of XML needs to be added to the |
| <code class="code"><dependencies>...</dependencies></code> section, where we already have Cayenne |
| jars:</p><pre class="programlisting"><span xmlns="http://www.w3.org/1999/xhtml" class="hl-tag"><dependency></span> |
| <span xmlns="http://www.w3.org/1999/xhtml" class="hl-tag"><groupId></span>org.apache.derby<span xmlns="http://www.w3.org/1999/xhtml" class="hl-tag"></groupId></span> |
| <span xmlns="http://www.w3.org/1999/xhtml" class="hl-tag"><artifactId></span>derby<span xmlns="http://www.w3.org/1999/xhtml" class="hl-tag"></artifactId></span> |
| <span xmlns="http://www.w3.org/1999/xhtml" class="hl-tag"><version></span>10.13.1.1<span xmlns="http://www.w3.org/1999/xhtml" class="hl-tag"></version></span> |
| <span xmlns="http://www.w3.org/1999/xhtml" class="hl-tag"></dependency></span></pre><p>Now |
| we are ready to run. Right click the "Main" class in IDEA and select "Run 'Main.main()'". |
| </p><p> |
| <span class="inlinemediaobject"><img src="images/idea-file-run-menu.png"></span> |
| </p><p> |
| In the console you'll see output similar to this, indicating that Cayenne stack has been started: |
| </p><pre class="screen">INFO: Loading XML configuration resource from file:/.../cayenne-project.xml |
| INFO: Loading XML DataMap resource from file:/.../datamap.map.xml |
| INFO: loading user name and password. |
| INFO: Connecting to 'jdbc:derby:memory:testdb;create=true' as 'null' |
| INFO: +++ Connecting: SUCCESS. |
| INFO: setting DataNode 'datanode' as default, used by all unlinked DataMaps</pre><p> |
| |
| </p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">How to Configure Cayenne Logging</h3><p>Follow the instructions in the logging chapter to tweak verbosity of the logging output.</p></div><p> |
| </p></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title"><a name="d0e485"></a>Getting started with persistent objects</h2></div></div></div><p>In this chapter we'll learn about persistent objects, how to customize them and how to |
| create and save them in DB.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="customizing-persistent-objects"></a>Inspecting and Customizing Persistent Objects</h3></div></div></div><p>Persistent classes in Cayenne implement a DataObject interface. If you inspect any of |
| the classes generated earlier in this tutorial (e.g. |
| <code class="code">org.example.cayenne.persistent.Artist</code>), you'll see that it extends a class with the name |
| that starts with underscore (<code class="code">org.example.cayenne.persistent.auto._Artist</code>), which in turn |
| extends from <code class="code">org.apache.cayenne.CayenneDataObject</code>. Splitting each persistent class into |
| user-customizable subclass (<code class="code">Xyz</code>) and a generated superclass (<code class="code">_Xyz</code>) is a useful technique |
| to avoid overwriting the custom code when refreshing classes from the mapping |
| model.</p><p>Let's for instance add a utility method to the Artist class that sets Artist date of |
| birth, taking a string argument for the date. It will be preserved even if the model |
| changes later:</p><pre class="programlisting"><span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">package</span> org.example.cayenne.persistent; |
| |
| <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">import</span> java.text.ParseException; |
| <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">import</span> java.text.SimpleDateFormat; |
| <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">import</span> java.util.Date; |
| |
| <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">import</span> org.example.cayenne.persistent.auto._Artist; |
| |
| <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">public</span> <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">class</span> Artist <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">extends</span> _Artist { |
| |
| <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">static</span> <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">final</span> String DEFAULT_DATE_FORMAT = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-string">"yyyyMMdd"</span>; |
| |
| <strong xmlns="http://www.w3.org/1999/xhtml" class="hl-tag">/** |
| * Sets date of birth using a string in format yyyyMMdd. |
| */</strong> |
| <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">public</span> <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">void</span> setDateOfBirthString(String yearMonthDay) { |
| <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">if</span> (yearMonthDay == null) { |
| setDateOfBirth(null); |
| } <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">else</span> { |
| |
| Date date; |
| <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">try</span> { |
| date = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">new</span> SimpleDateFormat(DEFAULT_DATE_FORMAT) |
| .parse(yearMonthDay); |
| } <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">catch</span> (ParseException e) { |
| <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">throw</span> <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">new</span> IllegalArgumentException( |
| <span xmlns="http://www.w3.org/1999/xhtml" class="hl-string">"A date argument must be in format '"</span> |
| + DEFAULT_DATE_FORMAT + <span xmlns="http://www.w3.org/1999/xhtml" class="hl-string">"': "</span> + yearMonthDay); |
| } |
| |
| setDateOfBirth(date); |
| } |
| } |
| }</pre></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="create-new-objects"></a>Create New Objects</h3></div></div></div><p>Now we'll create a bunch of objects and save them to the database. An object is |
| created and registered with <code class="code">ObjectContext</code> using "<code class="code">newObject</code>" method. Objects <span class="bold"><strong>must</strong></span> be registered with <code class="code">DataContext</code> to be persisted and to |
| allow setting relationships with other objects. Add this code to the "main" method of |
| the Main class:</p><pre class="programlisting">Artist picasso = context.newObject(Artist.<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">class</span>); |
| picasso.setName(<span xmlns="http://www.w3.org/1999/xhtml" class="hl-string">"Pablo Picasso"</span>); |
| picasso.setDateOfBirthString(<span xmlns="http://www.w3.org/1999/xhtml" class="hl-string">"18811025"</span>);</pre><p>Note that at this point "picasso" object is only stored in memory and is not saved in |
| the database. Let's continue by adding a Metropolitan Museum "<code class="code">Gallery</code>" object and a few |
| Picasso "Paintings":</p><pre class="programlisting">Gallery metropolitan = context.newObject(Gallery.<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">class</span>); |
| metropolitan.setName(<span xmlns="http://www.w3.org/1999/xhtml" class="hl-string">"Metropolitan Museum of Art"</span>); |
| |
| Painting girl = context.newObject(Painting.<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">class</span>); |
| girl.setName(<span xmlns="http://www.w3.org/1999/xhtml" class="hl-string">"Girl Reading at a Table"</span>); |
| |
| Painting stein = context.newObject(Painting.<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">class</span>); |
| stein.setName(<span xmlns="http://www.w3.org/1999/xhtml" class="hl-string">"Gertrude Stein"</span>);</pre><p>Now we can link the objects together, establishing relationships. Note that in each |
| case below relationships are automatically established in both directions (e.g. |
| <code class="code">picasso.addToPaintings(girl)</code> has exactly the same effect as |
| <code class="code">girl.setToArtist(picasso)</code>).</p><pre class="programlisting">picasso.addToPaintings(girl); |
| picasso.addToPaintings(stein); |
| |
| girl.setGallery(metropolitan); |
| stein.setGallery(metropolitan);</pre><p>Now lets save all five new objects, in a single method call:</p><pre class="programlisting">context.commitChanges();</pre><p>Now you can run the application again as described in the previous chapter. The new |
| output will show a few actual DB operations:</p><pre class="screen">org.apache.cayenne.configuration.XMLDataChannelDescriptorLoader load |
| INFO: Loading XML configuration resource from file:cayenne-project.xml |
| ... |
| INFO: Connecting to 'jdbc:derby:memory:testdb;create=true' as 'null' |
| INFO: +++ Connecting: SUCCESS. |
| INFO: setting DataNode 'datanode' as default, used by all unlinked DataMaps |
| INFO: Detected and installed adapter: org.apache.cayenne.dba.derby.DerbyAdapter |
| INFO: --- transaction started. |
| INFO: No schema detected, will create mapped tables |
| INFO: CREATE TABLE GALLERY (ID INTEGER NOT NULL, NAME VARCHAR (200), PRIMARY KEY (ID)) |
| INFO: CREATE TABLE ARTIST (DATE_OF_BIRTH DATE, ID INTEGER NOT NULL, NAME VARCHAR (200), PRIMARY KEY (ID)) |
| INFO: CREATE TABLE PAINTING (ARTIST_ID INTEGER, GALLERY_ID INTEGER, ID INTEGER NOT NULL, |
| NAME VARCHAR (200), PRIMARY KEY (ID)) |
| INFO: ALTER TABLE PAINTING ADD FOREIGN KEY (ARTIST_ID) REFERENCES ARTIST (ID) |
| INFO: ALTER TABLE PAINTING ADD FOREIGN KEY (GALLERY_ID) REFERENCES GALLERY (ID) |
| INFO: CREATE TABLE AUTO_PK_SUPPORT ( |
| TABLE_NAME CHAR(100) NOT NULL, NEXT_ID BIGINT NOT NULL, PRIMARY KEY(TABLE_NAME)) |
| INFO: DELETE FROM AUTO_PK_SUPPORT WHERE TABLE_NAME IN ('ARTIST', 'GALLERY', 'PAINTING') |
| INFO: INSERT INTO AUTO_PK_SUPPORT (TABLE_NAME, NEXT_ID) VALUES ('ARTIST', 200) |
| INFO: INSERT INTO AUTO_PK_SUPPORT (TABLE_NAME, NEXT_ID) VALUES ('GALLERY', 200) |
| INFO: INSERT INTO AUTO_PK_SUPPORT (TABLE_NAME, NEXT_ID) VALUES ('PAINTING', 200) |
| INFO: SELECT NEXT_ID FROM AUTO_PK_SUPPORT WHERE TABLE_NAME = ? FOR UPDATE [bind: 1:'ARTIST'] |
| INFO: SELECT NEXT_ID FROM AUTO_PK_SUPPORT WHERE TABLE_NAME = ? FOR UPDATE [bind: 1:'GALLERY'] |
| INFO: SELECT NEXT_ID FROM AUTO_PK_SUPPORT WHERE TABLE_NAME = ? FOR UPDATE [bind: 1:'PAINTING'] |
| INFO: INSERT INTO GALLERY (ID, NAME) VALUES (?, ?) |
| INFO: [batch bind: 1->ID:200, 2->NAME:'Metropolitan Museum of Art'] |
| INFO: === updated 1 row. |
| INFO: INSERT INTO ARTIST (DATE_OF_BIRTH, ID, NAME) VALUES (?, ?, ?) |
| INFO: [batch bind: 1->DATE_OF_BIRTH:'1881-10-25 00:00:00.0', 2->ID:200, 3->NAME:'Pablo Picasso'] |
| INFO: === updated 1 row. |
| INFO: INSERT INTO PAINTING (ARTIST_ID, GALLERY_ID, ID, NAME) VALUES (?, ?, ?, ?) |
| INFO: [batch bind: 1->ARTIST_ID:200, 2->GALLERY_ID:200, 3->ID:200, 4->NAME:'Gertrude Stein'] |
| INFO: [batch bind: 1->ARTIST_ID:200, 2->GALLERY_ID:200, 3->ID:201, 4->NAME:'Girl Reading at a Table'] |
| INFO: === updated 2 rows. |
| INFO: +++ transaction committed. |
| </pre><p>So first Cayenne creates the needed tables (remember, we used |
| "<code class="code">CreateIfNoSchemaStrategy</code>"). Then it runs a number of inserts, generating primary keys |
| on the fly. Not bad for just a few lines of code.</p></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title"><a name="d0e565"></a>Selecting Objects</h2></div></div></div><p>This chapter shows how to select objects from the database using <code class="code">ObjectSelect</code> query. </p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="introducing-select-query"></a>Introducing ObjectSelect</h3></div></div></div><p>It was shown before how to persist new objects. Cayenne queries are used to access |
| already saved objects. The primary query type used for selecting objects is <code class="code">ObjectSelect</code>. |
| It can be mapped in CayenneModeler or created |
| via the API. We'll use the latter approach in this section. We don't have too much data |
| in the database yet, but we can still demonstrate the main principles below.</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>Select all paintings (the code, and the log output it generates):</p></li></ul></div><pre class="programlisting">List<Painting> paintings1 = ObjectSelect.query(Painting.<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">class</span>).select(context); </pre><pre class="screen">INFO: SELECT t0.GALLERY_ID, t0.ARTIST_ID, t0.NAME, t0.ID FROM PAINTING t0 |
| INFO: === returned 2 rows. - took 18 ms.</pre><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>Select paintings that start with "<code class="code">gi</code>", ignoring case:</p></li></ul></div><pre class="programlisting">List<Painting> paintings2 = ObjectSelect.query(Painting.<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">class</span>) |
| .where(Painting.NAME.likeIgnoreCase(<span xmlns="http://www.w3.org/1999/xhtml" class="hl-string">"gi%"</span>)).select(context); </pre><pre class="screen">INFO: SELECT t0.GALLERY_ID, t0.NAME, t0.ARTIST_ID, t0.ID FROM PAINTING t0 WHERE UPPER(t0.NAME) LIKE UPPER(?) |
| [bind: 1->NAME:'gi%'] - prepared in 6 ms. |
| INFO: === returned 1 row. - took 18 ms.</pre><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>Select all paintings done by artists who were born more than a 100 years |
| ago:</p></li></ul></div><pre class="programlisting">Calendar c = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">new</span> GregorianCalendar(); |
| c.set(c.get(Calendar.YEAR) - <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">100</span>, <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0</span>, <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">1</span>, <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0</span>, <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0</span>, <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0</span>); |
| |
| List<Painting> paintings3 = ObjectSelect.query(Painting.<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">class</span>) |
| .where(Painting.ARTIST.dot(Artist.DATE_OF_BIRTH).lt(c.getTime())) |
| .select(context); </pre><pre class="screen">INFO: SELECT t0.GALLERY_ID, t0.NAME, t0.ARTIST_ID, t0.ID FROM PAINTING t0 JOIN ARTIST t1 ON (t0.ARTIST_ID = t1.ID) |
| WHERE t1.DATE_OF_BIRTH < ? [bind: 1->DATE_OF_BIRTH:'1911-01-01 00:00:00.493'] - prepared in 7 ms. |
| INFO: === returned 2 rows. - took 25 ms.</pre></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title"><a name="d0e610"></a>Deleting Objects</h2></div></div></div><p>This chapter explains how to model relationship delete rules and how to delete individual |
| objects as well as sets of objects. Also demonstrated the use of Cayenne class to run a |
| query.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="setup-delete-rules"></a>Setting Up Delete Rules</h3></div></div></div><p>Before we discuss the API for object deletion, lets go back to CayenneModeler and set |
| up some delete rules. Doing this is optional but will simplify correct handling of the |
| objects related to deleted objects.</p><p>In the Modeler go to "Artist" ObjEntity, "Relationships" tab and select "Cascade" for |
| the "paintings" relationship delete rule:</p><p><span class="inlinemediaobject"><img src="images/modeler-deleterule.png"></span> |
| </p><p>Repeat this step for other relationships:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>For Gallery set "paintings" relationship to be "Nullify", as a painting can |
| exist without being displayed in a gallery.</p></li><li class="listitem"><p>For Painting et both relationships rules to "Nullify".</p></li></ul></div><p>Now save the mapping.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="deleting-objects"></a>Deleting Objects</h3></div></div></div><p>While deleting objects is possible via SQL, qualifying a delete on one or more IDs, a |
| more common way in Cayenne (or ORM in general) is to get a hold of the object first, and |
| then delete it via the context. Let's use utility class Cayenne to find an |
| artist:</p><pre class="programlisting">Artist picasso = ObjectSelect.query(Artist.<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">class</span>).where(Artist.NAME.eq(<span xmlns="http://www.w3.org/1999/xhtml" class="hl-string">"Pablo Picasso"</span>)).selectOne(context);</pre><p>Now let's delete the artist:</p><pre class="programlisting"><span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">if</span> (picasso != null) { |
| context.deleteObject(picasso); |
| context.commitChanges(); |
| }</pre><p>Since we set up "Cascade" delete rule for the Artist.paintings relationships, Cayenne |
| will automatically delete all paintings of this artist. So when your run the app you'll |
| see this output:</p><pre class="screen">INFO: SELECT t0.DATE_OF_BIRTH, t0.NAME, t0.ID FROM ARTIST t0 |
| WHERE t0.NAME = ? [bind: 1->NAME:'Pablo Picasso'] - prepared in 6 ms. |
| INFO: === returned 1 row. - took 18 ms. |
| INFO: +++ transaction committed. |
| INFO: --- transaction started. |
| INFO: DELETE FROM PAINTING WHERE ID = ? |
| INFO: [batch bind: 1->ID:200] |
| INFO: [batch bind: 1->ID:201] |
| INFO: === updated 2 rows. |
| INFO: DELETE FROM ARTIST WHERE ID = ? |
| INFO: [batch bind: 1->ID:200] |
| INFO: === updated 1 row. |
| INFO: +++ transaction committed.</pre></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="getting-started-part2.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="getting-started-part4.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 2. Learning mapping basics </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 4. Converting to Web Application</td></tr></table></div></body></html> |