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> </TD> 41 <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT> </TD> 42 <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT> </TD> 43 <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A> </TD> 44 <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD> 45 <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD> 46 <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD> 47 <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </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 <A HREF="../../../com/sleepycat/db/package-summary.html"><B>PREV PACKAGE</B></A> 59 <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> 62 <A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A> 63 <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 <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<V></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<K,V></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<V></A></B></TD> 114<TD>Cursor operations limited to traversing forward.</TD> 115</TR> 116</TABLE> 117 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<PK,E></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<PK,E></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<SK,PK,E></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 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 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<Long,Employer> 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<String,Employer> 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<Long> employerIds = new HashSet<Long>(); 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<String,Person> 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<String> emailAddresses = new HashSet<String>(); 387 388 <code>@SecondaryKey(relate=MANY_TO_MANY, relatedEntity=Employer.class, 389 onRelatedEntityDelete=NULLIFY)</code> 390 <code>Set<Long> employerIds = new HashSet<Long>();</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<String,Person> personBySsn; 439 SecondaryIndex<String,String,Person> personByParentSsn; 440 SecondaryIndex<String,String,Person> personByEmailAddresses; 441 SecondaryIndex<Long,String,Person> personByEmployerIds; 442 443 // Employer accessors 444 // 445 PrimaryIndex<Long,Employer> employerById; 446 SecondaryIndex<String,Long,Employer> 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<Person> 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<String,Person> 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 < min || value > 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<String,Person> join = new EntityJoin(dao.personBySsn); 622 623join.addCondition(dao.personByParentSsn, "111-11-1111"); 624join.addCondition(dao.personByEmployerIds, gizmoInc.id); 625 626ForwardCursor<Person> 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<Person> 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> </TD> 770 <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT> </TD> 771 <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT> </TD> 772 <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A> </TD> 773 <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD> 774 <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD> 775 <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD> 776 <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </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 <A HREF="../../../com/sleepycat/db/package-summary.html"><B>PREV PACKAGE</B></A> 788 <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> 791 <A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A> 792 <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