/*- * See the file LICENSE for redistribution information. * * Copyright (c) 2002,2008 Oracle. All rights reserved. * * $Id: KeyField.java,v 1.1 2008/02/07 17:12:28 mark Exp $ */ 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.db.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. * *

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.

* *

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 the composite key class may not have superclasses * containing non-transient instance fields.

* *

For example:

*
 *  {@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;}
 *      ...
 *  }
* *

This causes entities to be sorted first by {@code kingdom}, then by * {@code phylum} within {@code kingdom}, and so on.

* *

The fields in a composite key class may not be null.

* *

Custom Sort Order

* *

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:

* *
 *  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} {
 *
 *      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);
 *      }
 *  }
* *

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.

*
    *
  1. The comparison method must always return the same result, given the same * inputs. The behavior of the comparison method must not change over * time.
  2. *
    *
  3. 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.
  4. *
    *
  5. 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.
  6. *
    *
  7. 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.
  8. *
* * @author Mark Hayes */ @Documented @Retention(RUNTIME) @Target(FIELD) public @interface KeyField { int value(); }