| /*- |
| * Copyright (C) 2002, 2018, Oracle and/or its affiliates. All rights reserved. |
| * |
| * This file was distributed by Oracle as part of a version of Oracle Berkeley |
| * DB Java Edition made available at: |
| * |
| * http://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html |
| * |
| * Please see the LICENSE file included in the top-level directory of the |
| * appropriate version of Oracle Berkeley DB Java Edition for a copy of the |
| * license and additional information. |
| */ |
| |
| package com.sleepycat.persist.model; |
| |
| import static java.lang.annotation.ElementType.FIELD; |
| import static java.lang.annotation.RetentionPolicy.RUNTIME; |
| |
| import java.lang.annotation.Documented; |
| import java.lang.annotation.Retention; |
| import java.lang.annotation.Target; |
| |
| import com.sleepycat.je.Environment; |
| |
| /** |
| * Indicates the sorting position of a key field in a composite key class when |
| * the {@code Comparable} interface is not implemented. The {@code KeyField} |
| * integer value specifies the sort order of this field within the set of |
| * fields in the composite key. |
| * |
| * <p>If the field type of a {@link PrimaryKey} or {@link SecondaryKey} is a |
| * composite key class containing more than one key field, then a {@code |
| * KeyField} annotation must be present on each non-transient instance field of |
| * the composite key class. The {@code KeyField} value must be a number |
| * between one and the number of non-transient instance fields declared in the |
| * composite key class.</p> |
| * |
| * <p>Note that a composite key class is a flat container for one or more |
| * simple type fields. All non-transient instance fields in the composite key |
| * class are key fields, and its superclass must be {@code Object}.</p> |
| * |
| * <p>For example:</p> |
| * <pre class="code"> |
| * {@literal @Entity} |
| * class Animal { |
| * {@literal @PrimaryKey} |
| * Classification classification; |
| * ... |
| * } |
| * |
| * {@literal @Persistent} |
| * class Classification { |
| * {@literal @KeyField(1) String kingdom;} |
| * {@literal @KeyField(2) String phylum;} |
| * {@literal @KeyField(3) String clazz;} |
| * {@literal @KeyField(4) String order;} |
| * {@literal @KeyField(5) String family;} |
| * {@literal @KeyField(6) String genus;} |
| * {@literal @KeyField(7) String species;} |
| * {@literal @KeyField(8) String subspecies;} |
| * ... |
| * }</pre> |
| * |
| * <p>This causes entities to be sorted first by {@code kingdom}, then by |
| * {@code phylum} within {@code kingdom}, and so on.</p> |
| * |
| * <p>The fields in a composite key class may not be null.</p> |
| * |
| * <p><a name="comparable"><strong>Custom Sort Order</strong></a></p> |
| * |
| * <p>To override the default sort order, a composite key class may implement |
| * the {@link Comparable} interface. This allows overriding the sort order and |
| * is therefore useful even when there is only one key field in the composite |
| * key class. For example, the following class sorts Strings using a Canadian |
| * collator:</p> |
| * |
| * <pre class="code"> |
| * import java.text.Collator; |
| * import java.util.Locale; |
| * |
| * {@literal @Entity} |
| * class Animal { |
| * ... |
| * {@literal @SecondaryKey(relate=ONE_TO_ONE)} |
| * CollatedString canadianName; |
| * ... |
| * } |
| * |
| * {@literal @Persistent} |
| * {@literal class CollatedString implements Comparable<CollatedString>} { |
| * |
| * static Collator collator = Collator.getInstance(Locale.CANADA); |
| * |
| * {@literal @KeyField(1)} |
| * String value; |
| * |
| * CollatedString(String value) { this.value = value; } |
| * |
| * private CollatedString() {} |
| * |
| * public int compareTo(CollatedString o) { |
| * return collator.compare(value, o.value); |
| * } |
| * }</pre> |
| * |
| * <p>Several important rules should be considered when implementing a custom |
| * comparison method. Failure to follow these rules may result in the primary |
| * or secondary index becoming unusable; in other words, the store will not be |
| * able to function.</p> |
| * <ol> |
| * <li>The comparison method must always return the same result, given the same |
| * inputs. The behavior of the comparison method must not change over |
| * time.</li> |
| * <li>A corollary to the first rule is that the behavior of the comparison |
| * method must not be dependent on state which may change over time. For |
| * example, if the above collation method used the default Java locale, and the |
| * default locale is changed, then the sort order will change.</li> |
| * <li>The comparison method must not assume that it is called after the store |
| * has been opened. With Berkeley DB Java Edition, the comparison method is |
| * called during database recovery, which occurs in the {@link Environment} |
| * constructor.</li> |
| * <li>The comparison method must not assume that it will only be called with |
| * keys that are currently present in the database. The comparison method will |
| * occasionally be called with deleted keys or with keys for records that were |
| * not part of a committed transaction.</li> |
| * </ol> |
| * |
| * @author Mark Hayes |
| */ |
| @Documented @Retention(RUNTIME) @Target(FIELD) |
| public @interface KeyField { |
| |
| int value(); |
| } |