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