• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src/router/db-4.8.30/docs/java/com/sleepycat/persist/
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2<!--NewPage-->
3<HTML>
4<HEAD>
5<!-- Generated by javadoc (build 1.6.0_03) on Mon Apr 12 16:25:51 EDT 2010 -->
6<TITLE>
7com.sleepycat.persist (Oracle - Berkeley DB Java API)
8</TITLE>
9
10<META NAME="date" CONTENT="2010-04-12">
11
12<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../style.css" TITLE="Style">
13
14<SCRIPT type="text/javascript">
15function windowTitle()
16{
17    if (location.href.indexOf('is-external=true') == -1) {
18        parent.document.title="com.sleepycat.persist (Oracle - Berkeley DB Java API)";
19    }
20}
21</SCRIPT>
22<NOSCRIPT>
23</NOSCRIPT>
24
25</HEAD>
26
27<BODY BGCOLOR="white" onload="windowTitle();">
28<HR>
29
30
31<!-- ========= START OF TOP NAVBAR ======= -->
32<A NAME="navbar_top"><!-- --></A>
33<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
34<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
35<TR>
36<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
37<A NAME="navbar_top_firstrow"><!-- --></A>
38<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
39  <TR ALIGN="center" VALIGN="top">
40  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
41  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
42  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
43  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
44  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
45  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
46  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
47  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
48  </TR>
49</TABLE>
50</TD>
51<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
52<b>Berkeley DB</b><br><font size="-1"> version 4.8.30</font></EM>
53</TD>
54</TR>
55
56<TR>
57<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
58&nbsp;<A HREF="../../../com/sleepycat/db/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
59&nbsp;<A HREF="../../../com/sleepycat/persist/evolve/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
60<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
61  <A HREF="../../../index.html?com/sleepycat/persist/package-summary.html" target="_top"><B>FRAMES</B></A>  &nbsp;
62&nbsp;<A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
63&nbsp;<SCRIPT type="text/javascript">
64  <!--
65  if(window==top) {
66    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
67  }
68  //-->
69</SCRIPT>
70<NOSCRIPT>
71  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
72</NOSCRIPT>
73
74
75</FONT></TD>
76</TR>
77</TABLE>
78<A NAME="skip-navbar_top"></A>
79<!-- ========= END OF TOP NAVBAR ========= -->
80
81<HR>
82<H2>
83Package com.sleepycat.persist
84</H2>
85The Direct Persistence Layer (DPL) adds a persistent object model to the
86Berkeley DB transactional engine.
87<P>
88<B>See:</B>
89<BR>
90&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A HREF="#package_description"><B>Description</B></A>
91<P>
92
93<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
94<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
95<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
96<B>Interface Summary</B></FONT></TH>
97</TR>
98<TR BGCOLOR="white" CLASS="TableRowColor">
99<TD WIDTH="15%"><B><A HREF="../../../com/sleepycat/persist/DatabaseNamer.html" title="interface in com.sleepycat.persist">DatabaseNamer</A></B></TD>
100<TD>Determines the file names to use for primary and secondary databases.</TD>
101</TR>
102<TR BGCOLOR="white" CLASS="TableRowColor">
103<TD WIDTH="15%"><B><A HREF="../../../com/sleepycat/persist/EntityCursor.html" title="interface in com.sleepycat.persist">EntityCursor&lt;V&gt;</A></B></TD>
104<TD>Traverses entity values or key values and allows deleting or updating the
105 entity at the current cursor position.</TD>
106</TR>
107<TR BGCOLOR="white" CLASS="TableRowColor">
108<TD WIDTH="15%"><B><A HREF="../../../com/sleepycat/persist/EntityIndex.html" title="interface in com.sleepycat.persist">EntityIndex&lt;K,V&gt;</A></B></TD>
109<TD>The interface for accessing keys and entities via a primary or secondary
110 index.</TD>
111</TR>
112<TR BGCOLOR="white" CLASS="TableRowColor">
113<TD WIDTH="15%"><B><A HREF="../../../com/sleepycat/persist/ForwardCursor.html" title="interface in com.sleepycat.persist">ForwardCursor&lt;V&gt;</A></B></TD>
114<TD>Cursor operations limited to traversing forward.</TD>
115</TR>
116</TABLE>
117&nbsp;
118
119<P>
120
121<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
122<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
123<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
124<B>Class Summary</B></FONT></TH>
125</TR>
126<TR BGCOLOR="white" CLASS="TableRowColor">
127<TD WIDTH="15%"><B><A HREF="../../../com/sleepycat/persist/EntityJoin.html" title="class in com.sleepycat.persist">EntityJoin&lt;PK,E&gt;</A></B></TD>
128<TD>Performs an equality join on two or more secondary keys.</TD>
129</TR>
130<TR BGCOLOR="white" CLASS="TableRowColor">
131<TD WIDTH="15%"><B><A HREF="../../../com/sleepycat/persist/EntityStore.html" title="class in com.sleepycat.persist">EntityStore</A></B></TD>
132<TD>A store for managing persistent entity objects.</TD>
133</TR>
134<TR BGCOLOR="white" CLASS="TableRowColor">
135<TD WIDTH="15%"><B><A HREF="../../../com/sleepycat/persist/PrimaryIndex.html" title="class in com.sleepycat.persist">PrimaryIndex&lt;PK,E&gt;</A></B></TD>
136<TD>The primary index for an entity class and its primary key.</TD>
137</TR>
138<TR BGCOLOR="white" CLASS="TableRowColor">
139<TD WIDTH="15%"><B><A HREF="../../../com/sleepycat/persist/SecondaryIndex.html" title="class in com.sleepycat.persist">SecondaryIndex&lt;SK,PK,E&gt;</A></B></TD>
140<TD>The secondary index for an entity class and a secondary key.</TD>
141</TR>
142<TR BGCOLOR="white" CLASS="TableRowColor">
143<TD WIDTH="15%"><B><A HREF="../../../com/sleepycat/persist/StoreConfig.html" title="class in com.sleepycat.persist">StoreConfig</A></B></TD>
144<TD>Configuration properties used with an <A HREF="../../../com/sleepycat/persist/EntityStore.html" title="class in com.sleepycat.persist"><CODE>EntityStore</CODE></A> or <A HREF="../../../com/sleepycat/persist/raw/RawStore.html" title="class in com.sleepycat.persist.raw"><CODE>RawStore</CODE></A>.</TD>
145</TR>
146</TABLE>
147&nbsp;
148
149<P>
150
151<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
152<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
153<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
154<B>Exception Summary</B></FONT></TH>
155</TR>
156<TR BGCOLOR="white" CLASS="TableRowColor">
157<TD WIDTH="15%"><B><A HREF="../../../com/sleepycat/persist/StoreExistsException.html" title="class in com.sleepycat.persist">StoreExistsException</A></B></TD>
158<TD>Thrown by the <A HREF="../../../com/sleepycat/persist/EntityStore.html" title="class in com.sleepycat.persist"><CODE>EntityStore</CODE></A> constructor when the <A HREF="../../../com/sleepycat/persist/StoreConfig.html#setExclusiveCreate(boolean)"><CODE>ExclusiveCreate</CODE></A> configuration parameter is
159 true and the store's internal catalog database already exists.</TD>
160</TR>
161<TR BGCOLOR="white" CLASS="TableRowColor">
162<TD WIDTH="15%"><B><A HREF="../../../com/sleepycat/persist/StoreNotFoundException.html" title="class in com.sleepycat.persist">StoreNotFoundException</A></B></TD>
163<TD>Thrown by the <A HREF="../../../com/sleepycat/persist/EntityStore.html" title="class in com.sleepycat.persist"><CODE>EntityStore</CODE></A> constructor when the <A HREF="../../../com/sleepycat/persist/StoreConfig.html#setAllowCreate(boolean)"><CODE>AllowCreate</CODE></A> configuration parameter is false and
164 the store's internal catalog database does not exist.</TD>
165</TR>
166</TABLE>
167&nbsp;
168
169<P>
170<A NAME="package_description"><!-- --></A><H2>
171Package com.sleepycat.persist Description
172</H2>
173
174<P>
175The Direct Persistence Layer (DPL) adds a persistent object model to the
176Berkeley DB transactional engine.
177
178<h1>Package Specification</h1>
179
180<ul>
181<li><a href="#intro">Introduction</a></li>
182<li><a href="#model">The Entity Model</a></li>
183<li><a href="#example">A brief example</a></li>
184<li><a href="#whichAPI">Which API to use?</a></li>
185<li><a href="#java14and15">Java 1.5 dependencies</a>
186    <ul>
187    <li><a href="#genericTypes">Generic Types</a></li>
188    <li><a href="#annotations">Annotations</a></li>
189    </ul>
190</li>
191<li><a href="#bytecode">Bytecode Enhancement</a></li>
192</ul>
193
194<a name="intro"><h2>Introduction</h2></a>
195
196<p>The Direct Persistence Layer (DPL) was designed to meet the following
197requirements.</p>
198<ul>
199<li>A type safe and convenient API is provided for accessing persistent
200objects.  The use of Java generic types, although optional, is fully exploited
201to provide type safety.  For example:
202<pre class="code">
203PrimaryIndex&lt;Long,Employer&gt; employerById = ...;
204long employerId = ...;
205Employer employer = employerById.get(employerId);</pre>
206</li>
207<li>All Java types are allowed to be persistent without requiring that they
208implement special interfaces.  Persistent fields may be <code>private</code>,
209package-private (default access), <code>protected</code>, or <code>public</code>.  No
210hand-coding of bindings is required.  However, each persistent class must have
211a default constructor.  For example:
212<pre class="code">
213@Persistent
214class Address {
215    String street;
216    String city;
217    String state;
218    int zipCode;
219    private Address() {}
220}</pre>
221</li>
222<li>Bytecode enhancement provides fully optimized bindings that do not use Java
223reflection.</li>
224<li>It is easy to define primary and secondary keys.  No external schema is
225required and Java annotations may be used for defining all metadata.
226Extensions may derive metadata from other sources.  For example, the following
227Employer class is defined as a persistent entity with a primary key field
228<code>id</code> and the secondary key field <code>name</code>:</li>
229<pre class="code">
230@Entity
231class Employer {
232
233    @PrimaryKey(sequence="ID")
234    long id;
235
236    @SecondaryKey(relate=ONE_TO_ONE)
237    String name;
238
239    Address address;
240
241    private Employer() {}
242}</pre>
243<li>Interoperability with external components is supported via the Java
244collections framework.  Any primary or secondary index can be accessed using a
245standard <code>java.util</code> collection.  For example:
246<pre class="code">java.util.SortedMap&lt;String,Employer&gt; map = employerByName.sortedMap();</pre>
247</li>
248<li>Class evolution is explicitly supported.  Compatible changes (adding fields
249and type widening) are performed automatically and transparently.  For example,
250without any special configuration a <code>street2</code> field may be added to the
251<code>Address</code> class and the type of the <code>zipCode</code> field may be changed
252from <code>int</code> to <code>long</code>:
253<pre class="code">
254@Persistent
255class Address {
256    String street;
257    String street2;
258    String city;
259    String state;
260    long zipCode;
261    private Address() {}
262}</pre>
263Many incompatible class changes, such as renaming fields or refactoring a
264single class, can be performed using <A HREF="../../../com/sleepycat/persist/evolve/Mutations.html" title="class in com.sleepycat.persist.evolve"><CODE>Mutations</CODE></A>.  Mutations are automatically
265applied lazily as data is accessed, avoiding downtime to convert large
266databases during a software upgrade.
267<p>Complex refactoring involving multiple classes may be performed using the a
268<a href="package-summary.html#storeConversion">store conversion</a>.  The DPL
269always provides access to your data via a <code>RawStore</code>, no matter what
270changes have been made to persistent classes.</p>
271</li>
272<br>
273<li>The performance of the Berkeley DB transactional engine is not compromised.
274Operations are internally mapped directly to the engine API, object bindings
275are lightweight, and all engine tuning parameters are available.  For example,
276a "dirty read" may be performed using an optional <A HREF="../../../com/sleepycat/db/LockMode.html" title="class in com.sleepycat.db"><CODE>LockMode</CODE></A> parameter:
277<pre class="code">Employer employer = employerByName.get(null, "Gizmo Inc", LockMode.READ_UNCOMMITTED);</pre>
278For high performance applications, <A HREF="../../../com/sleepycat/db/DatabaseConfig.html" title="class in com.sleepycat.db"><CODE>DatabaseConfig</CODE></A> parameters may be used to tune the performance of the Berkeley
279DB engine.  For example, the size of an internal Btree node can be specified
280as follows:
281<pre class="code">
282DatabaseConfig config = store.getPrimaryConfig(Employer.class);
283config.setNodeMaxEntries(64);
284store.setPrimaryConfig(config);</pre>
285</li>
286</ul>
287
288<a name="model"><h2>The Entity Model</h2></a>
289
290<p>The DPL is intended for applications that represent persistent domain
291objects using Java classes.  An <em>entity class</em> is an ordinary Java class
292that has a primary key and is stored and accessed using a primary index.  It
293may also have any number of secondary keys, and entities may be accessed by
294secondary key using a secondary index.</p>
295
296<p>An entity class may be defined with the <A HREF="../../../com/sleepycat/persist/model/Entity.html" title="annotation in com.sleepycat.persist.model"><CODE>Entity</CODE></A> annotation.  For each entity class,
297its primary key may be defined using the <A HREF="../../../com/sleepycat/persist/model/PrimaryKey.html" title="annotation in com.sleepycat.persist.model"><CODE>PrimaryKey</CODE></A> annotation and any number of
298secondary keys may be defined using the <A HREF="../../../com/sleepycat/persist/model/SecondaryKey.html" title="annotation in com.sleepycat.persist.model"><CODE>SecondaryKey</CODE></A> annotation.</p>
299
300<p>In the following example, the <code>Person.ssn</code> (social security number)
301field is the primary key and the <code>Person.employerIds</code> field is a
302many-to-many secondary key.</p>
303<pre class="code">
304@Entity
305class Person {
306
307    @PrimaryKey
308    String ssn;
309
310    String name;
311    Address address;
312
313    @SecondaryKey(relate=MANY_TO_MANY, relatedEntity=Employer.class)
314    Set&lt;Long&gt; employerIds = new HashSet&lt;Long&gt;();
315
316    private Person() {} // For bindings
317}</pre>
318
319<p>A set of entity classes constitutes an <em>entity model</em>.  In addition
320to isolated entity classes, an entity model may contain relationships between
321entities.  Relationships may be defined using the <A HREF="../../../com/sleepycat/persist/model/SecondaryKey.html" title="annotation in com.sleepycat.persist.model"><CODE>SecondaryKey</CODE></A> annotation.
322Many-to-one, one-to-many, many-to-many and one-to-one relationships are
323supported, as well as foreign key constraints.</p>
324
325<p>In the example above, a relationship between the <code>Person</code> and <code>Employer</code> entities is defined via the <code>Person.employerIds</code> field.  The
326<code>relatedEntity=Employer.class</code> annotation property establishes foreign
327key constraints to guarantee that every element of the <code>employerIds</code> set
328is a valid <code>Employer</code> primary key.</p>
329
330<p>For more information on the entity model, see the <A HREF="../../../com/sleepycat/persist/model/AnnotationModel.html" title="class in com.sleepycat.persist.model"><CODE>AnnotationModel</CODE></A> and the <A HREF="../../../com/sleepycat/persist/model/Entity.html" title="annotation in com.sleepycat.persist.model"><CODE>Entity</CODE></A> annotation.</p>
331
332<p>The root object in the DPL is the <A HREF="../../../com/sleepycat/persist/EntityStore.html" title="class in com.sleepycat.persist"><CODE>EntityStore</CODE></A>.  An entity store manages any number of objects for each entity
333class defined in the model.  The store provides access to the primary and
334secondary indices for each entity class, for example:</p>
335
336<pre class="code">
337EntityStore store = new EntityStore(...);
338
339PrimaryIndex&lt;String,Person&gt; personBySsn =
340    store.getPrimaryIndex(String.class, Person.class);</pre>
341
342<a name="example"><h2>A brief example</h2></a>
343
344<p>The following example shows how to define an entity model and how to store
345and access persistent objects.  Exception handling is omitted for brevity.</p>
346
347<pre class="code">
348import java.io.File;
349import java.util.HashSet;
350import java.util.Set;
351
352import com.sleepycat.db.DatabaseException;
353import com.sleepycat.db.Environment;
354import com.sleepycat.db.EnvironmentConfig;
355import com.sleepycat.persist.EntityCursor;
356import com.sleepycat.persist.EntityIndex;
357import com.sleepycat.persist.EntityStore;
358import com.sleepycat.persist.PrimaryIndex;
359import com.sleepycat.persist.SecondaryIndex;
360import com.sleepycat.persist.StoreConfig;
361import com.sleepycat.persist.model.Entity;
362import com.sleepycat.persist.model.Persistent;
363import com.sleepycat.persist.model.PrimaryKey;
364import com.sleepycat.persist.model.SecondaryKey;
365import static com.sleepycat.persist.model.DeleteAction.NULLIFY;
366import static com.sleepycat.persist.model.Relationship.ONE_TO_ONE;
367import static com.sleepycat.persist.model.Relationship.ONE_TO_MANY;
368import static com.sleepycat.persist.model.Relationship.MANY_TO_ONE;
369import static com.sleepycat.persist.model.Relationship.MANY_TO_MANY;
370
371// An entity class.
372//
373@Entity
374class Person {
375
376    @PrimaryKey
377    String ssn;
378
379    String name;
380    Address address;
381
382    @SecondaryKey(relate=MANY_TO_ONE, relatedEntity=Person.class)
383    String parentSsn;
384
385    @SecondaryKey(relate=ONE_TO_MANY)
386    Set&lt;String&gt; emailAddresses = new HashSet&lt;String&gt;();
387
388    <code>@SecondaryKey(relate=MANY_TO_MANY, relatedEntity=Employer.class,
389                                       onRelatedEntityDelete=NULLIFY)</code>
390    <code>Set&lt;Long&gt; employerIds = new HashSet&lt;Long&gt;();</code>
391
392    Person(String name, String ssn, String parentSsn) {
393        this.name = name;
394        this.ssn = ssn;
395        this.parentSsn = parentSsn;
396    }
397
398    private Person() {} // For bindings
399}
400
401// Another entity class.
402//
403@Entity
404class Employer {
405
406    @PrimaryKey(sequence="ID")
407    long id;
408
409    @SecondaryKey(relate=ONE_TO_ONE)
410    String name;
411
412    Address address;
413
414    Employer(String name) {
415        this.name = name;
416    }
417
418    private Employer() {} // For bindings
419}
420
421// A persistent class used in other classes.
422//
423@Persistent
424class Address {
425    String street;
426    String city;
427    String state;
428    int zipCode;
429    private Address() {} // For bindings
430}
431
432// The data accessor class for the entity model.
433//
434class PersonAccessor {
435
436    // Person accessors
437    //
438    PrimaryIndex&lt;String,Person&gt; personBySsn;
439    SecondaryIndex&lt;String,String,Person&gt; personByParentSsn;
440    SecondaryIndex&lt;String,String,Person&gt; personByEmailAddresses;
441    SecondaryIndex&lt;Long,String,Person&gt; personByEmployerIds;
442
443    // Employer accessors
444    //
445    PrimaryIndex&lt;Long,Employer&gt; employerById;
446    SecondaryIndex&lt;String,Long,Employer&gt; employerByName;
447
448    // Opens all primary and secondary indices.
449    //
450    public PersonAccessor(EntityStore store)
451        throws DatabaseException {
452
453        personBySsn = store.getPrimaryIndex(
454            String.class, Person.class);
455
456        personByParentSsn = store.getSecondaryIndex(
457            personBySsn, String.class, "parentSsn");
458
459        personByEmailAddresses = store.getSecondaryIndex(
460            personBySsn, String.class, "emailAddresses");
461
462        personByEmployerIds = store.getSecondaryIndex(
463            personBySsn, Long.class, "employerIds");
464
465        employerById = store.getPrimaryIndex(
466            Long.class, Employer.class);
467
468        employerByName = store.getSecondaryIndex(
469            employerById, String.class, "name"); 
470    }
471}
472
473// Open a transactional Berkeley DB engine environment.
474//
475EnvironmentConfig envConfig = new EnvironmentConfig();
476envConfig.setAllowCreate(true);
477envConfig.setTransactional(true);
478Environment env = new Environment(new File("/my/data"), envConfig);
479
480// Open a transactional entity store.
481//
482StoreConfig storeConfig = new StoreConfig();
483storeConfig.setAllowCreate(true);
484storeConfig.setTransactional(true);
485EntityStore store = new EntityStore(env, "PersonStore", storeConfig);
486
487// Initialize the data access object.
488//
489PersonAccessor dao = new PersonAccessor(store);
490
491// Add a parent and two children using the Person primary index.  Specifying a
492// non-null parentSsn adds the child Person to the sub-index of children for
493// that parent key.
494//
495dao.personBySsn.put(new Person("Bob Smith", "111-11-1111", null));
496dao.personBySsn.put(new Person("Mary Smith", "333-33-3333", "111-11-1111"));
497dao.personBySsn.put(new Person("Jack Smith", "222-22-2222", "111-11-1111"));
498
499// Print the children of a parent using a sub-index and a cursor.
500//
501EntityCursor&lt;Person&gt; children =
502    dao.personByParentSsn.subIndex("111-11-1111").entities();
503try {
504    for (Person child : children) {
505        System.out.println(child.ssn + ' ' + child.name);
506    }
507} finally {
508    children.close();
509}
510
511// Get Bob by primary key using the primary index.
512//
513Person bob = dao.personBySsn.get("111-11-1111");
514assert bob != null;
515
516// Create two employers.  Their primary keys are assigned from a sequence.
517//
518Employer gizmoInc = new Employer("Gizmo Inc");
519Employer gadgetInc = new Employer("Gadget Inc");
520dao.employerById.put(gizmoInc);
521dao.employerById.put(gadgetInc);
522
523// Bob has two jobs and two email addresses.
524//
525bob.employerIds.add(gizmoInc.id);
526bob.employerIds.add(gadgetInc.id);
527bob.emailAddresses.add("bob@bob.com");
528bob.emailAddresses.add("bob@gmail.com");
529
530// Update Bob's record.
531//
532dao.personBySsn.put(bob);
533
534// Bob can now be found by both email addresses.
535//
536bob = dao.personByEmailAddresses.get("bob@bob.com");
537assert bob != null;
538bob = dao.personByEmailAddresses.get("bob@gmail.com");
539assert bob != null;
540
541// Bob can also be found as an employee of both employers.
542//
543EntityIndex&lt;String,Person&gt; employees;
544employees = dao.personByEmployerIds.subIndex(gizmoInc.id);
545assert employees.contains("111-11-1111");
546employees = dao.personByEmployerIds.subIndex(gadgetInc.id);
547assert employees.contains("111-11-1111");
548
549// When an employer is deleted, the onRelatedEntityDelete=NULLIFY for the
550// employerIds key causes the deleted ID to be removed from Bob's employerIds.
551//
552dao.employerById.delete(gizmoInc.id);
553bob = dao.personBySsn.get("111-11-1111");
554assert !bob.employerIds.contains(gizmoInc.id);
555
556store.close();
557env.close();
558</pre>
559<p>The example illustrates several characteristics of the DPL:</p>
560<ul>
561<li>Persistent data and keys are defined in terms of instance fields.  For
562brevity the example does not show getter and setter methods, although these
563would normally exist to provide encapsulation.  The DPL accesses fields during
564object serialization and deserialization, rather than calling getter/setter
565methods, leaving business methods free to enforce arbitrary validation rules.
566For example: 
567<pre class="code">
568@Persistent
569public class ConstrainedValue {
570
571    private int min;
572    private int max;
573    private int value;
574
575    private ConstrainedValue() {} // For bindings
576
577    public ConstrainedValue(int min, int max) {
578        this.min = min;
579        this.max = max;
580        value = min;
581    }
582
583    public setValue(int value) {
584        if (value &lt; min || value &gt; max) {
585            throw new IllegalArgumentException("out of range");
586        }
587        this.value = value;
588    }
589}
590</pre>
591The above <code>setValue</code> method would not work if it were called during
592object deserialization, since the order of setting fields is arbitrary.  The
593<code>min</code> and <code>max</code> fields may not be set before the <code>value</code> is
594set.
595</li>
596<br>
597<li>The example creates a transactional store and therefore all operations are
598transaction protected.  Because no explicit transactions are used, auto-commit
599is used implicitly.
600
601<p>Explicit transactions may also be used to group multiple operations in a
602single transaction, and all access methods have optional transaction
603parameters.  For example, the following two operations are performed atomically
604in a transaction:
605<pre class="code">
606Transaction txn = env.beginTransaction(null, null);
607dao.employerById.put(txn, gizmoInc);
608dao.employerById.put(txn, gadgetInc);
609txn.commit();
610</pre>
611</li>
612<li>To provide maximum performance, the DPL operations map directly to the
613Btree operations of the Berkeley DB engine.  Unlike other persistence
614approaches, keys and indices are exposed for direct access and performance
615tuning.
616<p>Queries are implemented by calling methods of the primary and secondary
617indices.  An <A HREF="../../../com/sleepycat/persist/EntityJoin.html" title="class in com.sleepycat.persist"><CODE>EntityJoin</CODE></A> class is also
618available for performing equality joins.  For example, the following code
619queries all of Bob's children that work for Gizmo Inc:
620<pre class="code">
621EntityJoin&lt;String,Person&gt; join = new EntityJoin(dao.personBySsn);
622
623join.addCondition(dao.personByParentSsn, "111-11-1111");
624join.addCondition(dao.personByEmployerIds, gizmoInc.id);
625
626ForwardCursor&lt;Person&gt; results = join.entities();
627try {
628    for (Person person : results) {
629        System.out.println(person.ssn + ' ' + person.name);
630    }
631} finally {
632    results.close();
633}
634</li>
635<li>Object relationships are based on keys.  When a <code>Person</code> with a given
636employer ID in its <code>employerIds</code> set is stored, the <code>Person</code> object
637becomes part of the collection of employees for that employer.  This collection
638of employees is accessed using a <A HREF="../../../com/sleepycat/persist/SecondaryIndex.html#subIndex(SK)"><CODE>SecondaryIndex.subIndex</CODE></A> for the
639employer ID, as shown below:
640<pre class="code">
641EntityCursor&lt;Person&gt; employees =
642    dao.personByEmployerIds.subIndex(gizmoInc.id).entities();
643try {
644    for (Person employee : employees) {
645        System.out.println(employee.ssn + ' ' + employee.name);
646    }
647} finally {
648    employees.close();
649}
650</pre></li>
651<li>Note that when Bob's employer is deleted in the example, the <code>Person</code>
652object for Bob is refetched to see the change to its <code>employerIds</code>.  This
653is because objects are accessed by value, not by reference.  In other words, no
654object cache or "persistence context" is maintained by the DPL.  The low level
655caching of the embedded Berkeley DB engine, combined with lightweight object
656bindings, provides maximum performance.</li>
657</ul>
658
659<a name="whichAPI"><h2>Which API to use?</h2></a>
660
661<p>The Berkeley DB engine has a <A HREF="../../../com/sleepycat/db/package-summary.html"><CODE>Base API</CODE></A>, a <A HREF="../../../com/sleepycat/collections/package-summary.html"><CODE>Collections API</CODE></A> and a <A HREF="../../../com/sleepycat/persist/package-summary.html"><CODE>Direct Persistence Layer (DPL)</CODE></A>.  Follow these guidelines if you are not sure
662which API to use:</p>
663<ul>
664<li>When Java classes are used to represent domain objects in an application,
665the DPL is recommended.  The more domain classes, the more value there is in
666using annotations to define your schema.</li>
667<br>
668<li>When porting an application between Berkeley DB and Berkeley DB Java
669Edition, or when you've chosen not to use Java classes to represent domain
670objects, then the Base API is recommended.  You may also prefer to use this API
671if you have very few domain classes.</li>
672<br>
673<li>The Collections API is useful for interoperating with external components
674because it conforms to the standard Java Collections Framework.  It is
675therefore useful in combination with both the Base API and the DPL.  You may
676prefer this API because it provides the familiar Java Collections
677interface.</li>
678</ul>
679
680<a name="java14and15"><h2>Java 1.5 dependencies</h2></a>
681
682<p>The DPL uses two features of Java 1.5: generic types and annotations.  If
683you wish to avoid using these two Java 1.5 features, the DPL provides options
684for doing so.</p>
685
686<a name="genericTypes"><h3>Generic Types</h3></a>
687
688<p>Generic types are used to provide type safety, especially for the <A HREF="../../../com/sleepycat/persist/PrimaryIndex.html" title="class in com.sleepycat.persist"><CODE>PrimaryIndex</CODE></A>, <A HREF="../../../com/sleepycat/persist/SecondaryIndex.html" title="class in com.sleepycat.persist"><CODE>SecondaryIndex</CODE></A>, and <A HREF="../../../com/sleepycat/persist/EntityCursor.html" title="interface in com.sleepycat.persist"><CODE>EntityCursor</CODE></A> classes.  If you don't wish to
689use generic types, you can simply not declare your index and cursor objects
690using generic type parameters.  This is the same as using the Java 1.5
691Collections Framework without using generic types.</p>
692
693<a name="annotations"><h3>Annotations</h3></a>
694
695<p>If you don't wish to use annotations, you can provide another source of
696metadata by implementing an <A HREF="../../../com/sleepycat/persist/model/EntityModel.html" title="class in com.sleepycat.persist.model"><CODE>EntityModel</CODE></A> class.  For example, naming conventions, static members, or an XML
697configuration file might be used as a source of metadata.  However, if you
698don't use annotations then you won't be able to use bytecode enhancement, which
699is described next.</p>
700
701<a name="bytecode"><h2>Bytecode Enhancement</h2></a>
702
703<p>The persistent fields of a class may be private, package-private, protected
704or public.  The DPL can access persistent fields either by bytecode enhancement
705or by reflection.</p>
706
707<p>Bytecode enhancement may be used to fully optimize binding performance and
708to avoid the use of Java reflection.  In applications that are CPU bound,
709avoiding Java reflection can have a significant performance impact.</p>
710
711<p>Bytecode enhancement may be performed either at runtime or at build time
712(offline).  When enhancement is performed at runtime, persistent classes are
713enhanced as they are loaded.  When enhancement is performed offline, class
714files are enhanced during a post-compilation step.
715Enhanced classes are used to efficiently access all fields and default
716constructors, including non-public members.</p>
717
718<p>See <A HREF="../../../com/sleepycat/persist/model/ClassEnhancer.html" title="class in com.sleepycat.persist.model"><CODE>ClassEnhancer</CODE></A> for
719bytecode enhancement configuration details.</p>
720
721<p>If bytecode enhancement is not used as described above, the DPL will use
722reflection for accessing persistent fields and the default constructor.  The
723<A HREF="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/reflect/AccessibleObject.html?is-external=true#setAccessible(java.lang.reflect.AccessibleObject[], boolean)" title="class or interface in java.lang.reflect"><CODE>AccessibleObject.setAccessible</CODE></A> method is called by the DPL to enable access to
724non-public fields and constructors.  If you are running under a Java security
725manager you must configure your security policy to allow the following
726permission:</p>
727
728<p><code>permission java.lang.reflect.ReflectPermission "suppressAccessChecks";</code>
729
730<p>There are three cases where setting the above permission is <em>not</em>
731required:</p>
732<ol>
733<li>If you are not running under a Java Security Manager, then access to
734non-public members via reflection is not restricted.  This is the default for
735J2SE.</li>
736<br>
737<li>If all persistent fields and default constructors are <code>public</code> then
738they can be accessed via reflection without special permissions, even when
739running under a Java Security Manager.  However, declaring <code>public</code>
740instance fields is not recommended because it discourages encapsulation.</li>
741<br>
742<li>If bytecode enhancement is used as described above, then reflection will
743not be used.</li>
744</ol>
745
746<p>It is well known that executing generated code is faster than reflection.
747However, this performance difference may or may not impact a given application
748since it may be overshadowed by other factors.  Performance testing in a
749realistic usage scenario is the best way to determine the impact.  If you are
750determined to avoid the use of reflection then option 3 above is
751recommended.</p>
752<P>
753
754<P>
755<DL>
756</DL>
757<HR>
758
759
760<!-- ======= START OF BOTTOM NAVBAR ====== -->
761<A NAME="navbar_bottom"><!-- --></A>
762<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
763<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
764<TR>
765<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
766<A NAME="navbar_bottom_firstrow"><!-- --></A>
767<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
768  <TR ALIGN="center" VALIGN="top">
769  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
770  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
771  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
772  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
773  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
774  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
775  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
776  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
777  </TR>
778</TABLE>
779</TD>
780<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
781<b>Berkeley DB</b><br><font size="-1"> version 4.8.30</font></EM>
782</TD>
783</TR>
784
785<TR>
786<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
787&nbsp;<A HREF="../../../com/sleepycat/db/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
788&nbsp;<A HREF="../../../com/sleepycat/persist/evolve/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
789<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
790  <A HREF="../../../index.html?com/sleepycat/persist/package-summary.html" target="_top"><B>FRAMES</B></A>  &nbsp;
791&nbsp;<A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
792&nbsp;<SCRIPT type="text/javascript">
793  <!--
794  if(window==top) {
795    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
796  }
797  //-->
798</SCRIPT>
799<NOSCRIPT>
800  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
801</NOSCRIPT>
802
803
804</FONT></TD>
805</TR>
806</TABLE>
807<A NAME="skip-navbar_bottom"></A>
808<!-- ======== END OF BOTTOM NAVBAR ======= -->
809
810<HR>
811<font size=1>Copyright (c) 1996-2009 Oracle.  All rights reserved.</font>
812</BODY>
813</HTML>
814