1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2002,2008 Oracle. All rights reserved. 5 * 6 * $Id: KeyField.java,v 1.1 2008/02/07 17:12:28 mark Exp $ 7 */ 8 9package com.sleepycat.persist.model; 10 11import static java.lang.annotation.ElementType.FIELD; 12import static java.lang.annotation.RetentionPolicy.RUNTIME; 13 14import java.lang.annotation.Documented; 15import java.lang.annotation.Retention; 16import java.lang.annotation.Target; 17 18import com.sleepycat.db.Environment; 19 20/** 21 * Indicates the sorting position of a key field in a composite key class when 22 * the {@code Comparable} interface is not implemented. The {@code KeyField} 23 * integer value specifies the sort order of this field within the set of 24 * fields in the composite key. 25 * 26 * <p>If the field type of a {@link PrimaryKey} or {@link SecondaryKey} is a 27 * composite key class containing more than one key field, then a {@code 28 * KeyField} annotation must be present on each non-transient instance field of 29 * the composite key class. The {@code KeyField} value must be a number 30 * between one and the number of non-transient instance fields declared in the 31 * composite key class.</p> 32 * 33 * <p>Note that a composite key class is a flat container for one or more 34 * simple type fields. All non-transient instance fields in the composite key 35 * class are key fields, and the composite key class may not have superclasses 36 * containing non-transient instance fields.</p> 37 * 38 * <p>For example:</p> 39 * <pre class="code"> 40 * {@literal @Entity} 41 * class Animal { 42 * {@literal @PrimaryKey} 43 * Classification classification; 44 * ... 45 * } 46 * 47 * {@literal @Persistent} 48 * class Classification { 49 * {@literal @KeyField(1) String kingdom;} 50 * {@literal @KeyField(2) String phylum;} 51 * {@literal @KeyField(3) String clazz;} 52 * {@literal @KeyField(4) String order;} 53 * {@literal @KeyField(5) String family;} 54 * {@literal @KeyField(6) String genus;} 55 * {@literal @KeyField(7) String species;} 56 * {@literal @KeyField(8) String subspecies;} 57 * ... 58 * }</pre> 59 * 60 * <p>This causes entities to be sorted first by {@code kingdom}, then by 61 * {@code phylum} within {@code kingdom}, and so on.</p> 62 * 63 * <p>The fields in a composite key class may not be null.</p> 64 * 65 * <p><a name="comparable"><strong>Custom Sort Order</strong></a></p> 66 * 67 * <p>To override the default sort order, a composite key class may implement 68 * the {@link Comparable} interface. This allows overriding the sort order and 69 * is therefore useful even when there is only one key field in the composite 70 * key class. For example, the following class sorts Strings using a Canadian 71 * collator:</p> 72 * 73 * <pre class="code"> 74 * import java.text.Collator; 75 * import java.util.Locale; 76 * 77 * {@literal @Entity} 78 * class Animal { 79 * ... 80 * {@literal @SecondaryKey(relate=ONE_TO_ONE)} 81 * CollatedString canadianName; 82 * ... 83 * } 84 * 85 * {@literal @Persistent} 86 * {@literal class CollatedString implements Comparable<CollatedString>} { 87 * 88 * static Collator collator = Collator.getInstance(Locale.CANADA); 89 * 90 * {@literal @KeyField(1)} 91 * String value; 92 * 93 * CollatedString(String value) { this.value = value; } 94 * 95 * private CollatedString() {} 96 * 97 * public int compareTo(CollatedString o) { 98 * return collator.compare(value, o.value); 99 * } 100 * }</pre> 101 * 102 * <p>Several important rules should be considered when implementing a custom 103 * comparison method. Failure to follow these rules may result in the primary 104 * or secondary index becoming unusable; in other words, the store will not be 105 * able to function.</p> 106 * <ol> 107 * <li>The comparison method must always return the same result, given the same 108 * inputs. The behavior of the comparison method must not change over 109 * time.</li> 110 * <br> 111 * <li>A corollary to the first rule is that the behavior of the comparison 112 * method must not be dependent on state which may change over time. For 113 * example, if the above collation method used the default Java locale, and the 114 * default locale is changed, then the sort order will change.</li> 115 * <br> 116 * <li>The comparison method must not assume that it is called after the store 117 * has been opened. With Berkeley DB Java Edition, the comparison method is 118 * called during database recovery, which occurs in the {@link Environment} 119 * constructor.</li> 120 * <br> 121 * <li>The comparison method must not assume that it will only be called with 122 * keys that are currently present in the database. The comparison method will 123 * occasionally be called with deleted keys or with keys for records that were 124 * not part of a committed transaction.</li> 125 * </ol> 126 * 127 * @author Mark Hayes 128 */ 129@Documented @Retention(RUNTIME) @Target(FIELD) 130public @interface KeyField { 131 132 int value(); 133} 134