1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2002,2008 Oracle.  All rights reserved.
5 *
6 * $Id: PrimaryKey.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.persist.EntityStore;
19import com.sleepycat.persist.PrimaryIndex;
20
21/**
22 * Indicates the primary key field of an entity class.  The value of the
23 * primary key field is the unique identifier for the entity in a {@link
24 * PrimaryIndex}.
25 *
26 * <p>{@link PrimaryKey} may appear on at most one declared field per
27 * class.</p>
28 *
29 * <p>Primary key values may be automatically assigned as sequential integers
30 * using a {@link #sequence}.  In this case the type of the key field is
31 * restricted to a simple integer type.</p>
32 *
33 * <p>A primary key field may not be null, unless it is being assigned from a
34 * sequence.</p>
35 *
36 * <p><a name="keyTypes"><strong>Key Field Types</strong></a></p>
37 *
38 * <p>The type of a key field must either be one of the following:</p>
39 * <ul>
40 * <li>Any of the {@link <a href="Entity.html#simpleTypes">simple
41 * types</a>}.</li>
42 * <li>A composite key class containing one or more simple type fields.</li>
43 * </ul>
44 * <p>Enum types and array types are not allowed.</p>
45 *
46 * <p>When using a composite key class containing more than one key field, each
47 * field of the composite key class must be annotated with {@link KeyField} to
48 * identify the storage order and default sort order.  See {@link KeyField} for
49 * an example and more information on composite keys.</p>
50 *
51 * <p><a name="sortOrder"><strong>Key Sort Order</strong></a></p>
52 *
53 * <p>Key field types, being simple types, have a well defined and reasonable
54 * default sort order, described below.  This sort order is based on a storage
55 * encoding that allows a fast byte-by-byte comparison.</p>
56 * <ul>
57 * <li>All simple types except for {@code String} are encoded so that they are
58 * sorted as expected, that is, as if the {@link Comparable#compareTo} method
59 * of their class (or, for primitives, their wrapper class) is called.</li>
60 * <br>
61 * <li>Strings are encoded as UTF-8 byte arrays.  Zero (0x0000) character
62 * values are UTF encoded as non-zero values, and therefore embedded zeros in
63 * the string are supported.  The sequence {@literal {0xC0,0x80}} is used to
64 * encode a zero character.  This UTF encoding is the same one used by native
65 * Java UTF libraries.  However, this encoding of zero does impact the
66 * lexicographical ordering, and zeros will not be sorted first (the natural
67 * order) or last.  For all character values other than zero, the default UTF
68 * byte ordering is the same as the Unicode lexicographical character
69 * ordering.</li>
70 * </ul>
71 *
72 * <p>To override the default sort order, you can use a composite key class
73 * that implements {@link Comparable}.  This allows overriding the sort order
74 * and is therefore useful even when there is only one key field in the
75 * composite key class.  See {@link <a href="KeyField.html#comparable">Custom
76 * Sort Order</a>} for more information on sorting of composite keys.</p>
77 *
78 * <p><a name="inherit"><strong>Inherited Primary Key</strong></a></p>
79 *
80 * <p>If it does not appear on a declared field in the entity class, {@code
81 * PrimaryKey} must appear on a field of an entity superclass.  In the
82 * following example, the primary key on the base class is used:</p>
83 *
84 * <pre class="code">
85 * {@literal @Persistent}
86 * class BaseClass {
87 *     {@literal @PrimaryKey}
88 *     long id;
89 *     ...
90 * }
91 * {@literal @Entity}
92 * class Employee extends BaseClass {
93 *     // inherits id primary key
94 *     ...
95 * }</pre>
96 *
97 * <p>If more than one class with {@code PrimaryKey} is present in a class
98 * hierarchy, the key in the most derived class is used.  In this case, primary
99 * key fields in superclasses are "shadowed" and are not persistent.  In the
100 * following example, the primary key in the base class is not used and is not
101 * persistent:</p>
102 * <pre class="code">
103 * {@literal @Persistent}
104 * class BaseClass {
105 *     {@literal @PrimaryKey}
106 *     long id;
107 *     ...
108 * }
109 * {@literal @Entity}
110 * class Employee extends BaseClass {
111 *     // overrides id primary key
112 *     {@literal @PrimaryKey}
113 *     String uuid;
114 *     ...
115 * }</pre>
116 *
117 * <p>Note that a {@code PrimaryKey} is not allowed on entity subclasses.  The
118 * following is illegal and will cause an {@code IllegalArgumentException} when
119 * trying to store an {@code Employee} instance:</p>
120 * <pre class="code">
121 * {@literal @Entity}
122 * class Person {
123 *     {@literal @PrimaryKey}
124 *     long id;
125 *     ...
126 * }
127 * {@literal @Entity}
128 * class Employee extends Person {
129 *     {@literal @PrimaryKey}
130 *     String uuid;
131 *     ...
132 * }</pre>
133 *
134 * @author Mark Hayes
135 */
136@Documented @Retention(RUNTIME) @Target(FIELD)
137public @interface PrimaryKey {
138
139    /**
140     * The name of a sequence from which to assign primary key values
141     * automatically.  If a non-empty string is specified, sequential integers
142     * will be assigned from the named sequence.
143     *
144     * <p>A single sequence may be used for more than one entity class by
145     * specifying the same sequence name for each {@code PrimaryKey}.  For
146     * each named sequence, a {@link com.sleepycat.db.Sequence} will be used to
147     * assign key values.  For more information on configuring sequences, see
148     * {@link EntityStore#setSequenceConfig EntityStore.setSequenceConfig}.</p>
149     *
150     * <p>To use a sequence, the type of the key field must be a primitive
151     * integer type ({@code byte}, {@code short}, {@code int} or {@code long})
152     * or the primitive wrapper class for one of these types.  A composite key
153     * class may also be used to override sort order, but it may contain only a
154     * single key field that has one of the types previously mentioned.</p>
155     *
156     * <p>When an entity with a primary key sequence is stored using one of the
157     * <code>put</code> methods in the {@link PrimaryIndex}, a new key will be
158     * assigned if the primary key field in the entity instance is null (for a
159     * reference type) or zero (for a primitive integer type).  Specifying zero
160     * for a primitive integer key field is allowed because the initial value
161     * of the sequence is one (not zero) by default.  If the sequence
162     * configuration is changed such that zero is part of the sequence, then
163     * the field type must be a primitive wrapper class and the field value
164     * must be null to cause a new key to be assigned.</p>
165     *
166     * <p>When one of the <code>put</code> methods in the {@link PrimaryIndex}
167     * is called and a new key is assigned, the assigned value is returned to
168     * the caller via the key field of the entity object that is passed as a
169     * parameter.</p>
170     */
171    String sequence() default "";
172}
173