1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2002-2009 Oracle. All rights reserved. 5 * 6 * $Id$ 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.DatabaseException; 19import com.sleepycat.persist.PrimaryIndex; 20import com.sleepycat.persist.SecondaryIndex; // for javadoc 21import com.sleepycat.persist.StoreConfig; 22 23/** 24 * Indicates a secondary key field of an entity class. The value of the 25 * secondary key field is a unique or non-unique identifier for the entity and 26 * is accessed via a {@link SecondaryIndex}. 27 * 28 * <p>{@code SecondaryKey} may appear on any number of fields in an entity 29 * class, subclasses and superclasses. For a secondary key field in the entity 30 * class or one of its superclasses, all entity instances will be indexed by 31 * that field (if it is non-null). For a secondary key field in an entity 32 * subclass, only instances of that subclass will be indexed by that field (if 33 * it is non-null).</p> 34 * 35 * <p>If a secondary key field is null, the entity will not be indexed by that 36 * key. In other words, the entity cannot be queried by that secondary key nor 37 * can the entity be found by iterating through the secondary index.</p> 38 * 39 * <p>For a given entity class and its superclasses and subclasses, no two 40 * secondary keys may have the same name. By default, the field name 41 * identifies the secondary key and the secondary index for a given entity 42 * class. {@link #name} may be specified to override this default.</p> 43 * 44 * <p>Using {@link #relate}, instances of the entity class are related to 45 * secondary keys in a many-to-one, one-to-many, many-to-many, or one-to-one 46 * relationship. This required property specifies the <em>cardinality</em> of 47 * each side of the relationship.</p> 48 * 49 * <p>A secondary key may optionally be used to form a relationship with 50 * instances of another entity class using {@link #relatedEntity} and {@link 51 * #onRelatedEntityDelete}. This establishes <em>foreign key constraints</em> 52 * for the secondary key.</p> 53 * 54 * <p>The secondary key field type must be an array or collection type when a 55 * <em>x-to-many</em> relationship is used or a singular type when an 56 * <em>x-to-one</em> relationship is used; see {@link #relate}.</p> 57 * 58 * <p>The field type (or element type, when an array or collection type is 59 * used) of a secondary key field must follow the same rules as for a {@link 60 * <a href="PrimaryKey.html#keyTypes">primary key type</a>}. The {@link <a 61 * href="PrimaryKey.html#sortOrder">key sort order</a>} is also the same.</p> 62 * 63 * <p>For a secondary key field with a collection type, a type parameter must 64 * be used to specify the element type. For example {@code Collection<String>} 65 * is allowed but {@code Collection} is not.</p> 66 * 67 * @author Mark Hayes 68 */ 69@Documented @Retention(RUNTIME) @Target(FIELD) 70public @interface SecondaryKey { 71 72 /** 73 * Defines the relationship between instances of the entity class and the 74 * secondary keys. 75 * 76 * <p>The table below summarizes how to create all four variations of 77 * relationships.</p> 78 * <div> 79 * <table border="yes"> 80 * <tr><th>Relationship</th> 81 * <th>Field type</th> 82 * <th>Key type</th> 83 * <th>Example</th> 84 * </tr> 85 * <tr><td>{@link Relationship#ONE_TO_ONE}</td> 86 * <td>Singular</td> 87 * <td>Unique</td> 88 * <td>A person record with a unique social security number 89 * key.</td> 90 * </tr> 91 * <tr><td>{@link Relationship#MANY_TO_ONE}</td> 92 * <td>Singular</td> 93 * <td>Duplicates</td> 94 * <td>A person record with a non-unique employer key.</td> 95 * </tr> 96 * <tr><td>{@link Relationship#ONE_TO_MANY}</td> 97 * <td>Array/Collection</td> 98 * <td>Unique</td> 99 * <td>A person record with multiple unique email address keys.</td> 100 * </tr> 101 * <tr><td>{@link Relationship#MANY_TO_MANY}</td> 102 * <td>Array/Collection</td> 103 * <td>Duplicates</td> 104 * <td>A person record with multiple non-unique organization 105 * keys.</td> 106 * </tr> 107 * </table> 108 * </div> 109 * 110 * <p>For a <em>many-to-x</em> relationship, the secondary index will 111 * have non-unique keys; in other words, duplicates will be allowed. 112 * Conversely, for <em>one-to-x</em> relationship, the secondary index 113 * will have unique keys.</p> 114 * 115 * <p>For a <em>x-to-one</em> relationship, the secondary key field is 116 * singular; in other words, it may not be an array or collection type. 117 * Conversely, for a <em>x-to-many</em> relationship, the secondary key 118 * field must be an array or collection type. A collection type is any 119 * implementation of {@link java.util.Collection}.</p> 120 */ 121 Relationship relate(); 122 123 /** 124 * Specifies the entity to which this entity is related, for establishing 125 * foreign key constraints. Values of this secondary key will be 126 * constrained to the set of primary key values for the given entity class. 127 * 128 * <p>The given class must be an entity class. This class is called the 129 * <em>related entity</em> or <em>foreign entity</em>.</p> 130 * 131 * <p>When a related entity class is specified, a check (foreign key 132 * constraint) is made every time a new secondary key value is stored for 133 * this entity, and every time a related entity is deleted.</p> 134 * 135 * <p>Whenever a new secondary key value is stored for this entity, it is 136 * checked to ensure it exists as a primary key value of the related 137 * entity. If it does not, a {@link DatabaseException} will be thrown 138 * by the {@link PrimaryIndex} {@code put} method.</p> 139 * 140 * <p>Whenever a related entity is deleted and its primary key value exists 141 * as a secondary key value for this entity, the action is taken that is 142 * specified using the {@link #onRelatedEntityDelete} property.</p> 143 * 144 * <p>Together, these two checks guarantee that a secondary key value for 145 * this entity will always exist as a primary key value for the related 146 * entity. Note, however, that a transactional store must be configured 147 * to guarantee this to be true in the face of a crash; see {@link 148 * StoreConfig#setTransactional}.</p> 149 */ 150 Class relatedEntity() default void.class; 151 152 /** 153 * Specifies the action to take when a related entity is deleted having a 154 * primary key value that exists as a secondary key value for this entity. 155 * 156 * <p><em>Note:</em> This property only applies when {@link #relatedEntity} 157 * is specified to define the related entity.</p> 158 * 159 * <p>The default action, {@link DeleteAction#ABORT ABORT}, means that a 160 * {@link DatabaseException} is thrown in order to abort the current 161 * transaction.</p> 162 * 163 * <p>If {@link DeleteAction#CASCADE CASCADE} is specified, then this 164 * entity will be deleted also. This in turn could trigger further 165 * deletions, causing a cascading effect.</p> 166 * 167 * <p>If {@link DeleteAction#NULLIFY NULLIFY} is specified, then the 168 * secondary key in this entity is set to null and this entity is updated. 169 * If the key field type is singular, the field value is set to null; 170 * therefore, to specify {@code NULLIFY} for a singular key field type, a 171 * primitive wrapper type must be used instead of a primitive type. If the 172 * key field type is an array or collection type, the key is deleted from 173 * the array (the array is resized) or from the collection (using {@link 174 * java.util.Collection#remove Collection.remove}).</p> 175 */ 176 DeleteAction onRelatedEntityDelete() default DeleteAction.ABORT; 177 178 /** 179 * Specifies the name of the key in order to use a name that is different 180 * than the field name. 181 * 182 * <p>This is convenient when prefixes or suffices are used on field names. 183 * For example:</p> 184 * <pre class="code"> 185 * class Person { 186 * {@literal @SecondaryKey(relate=MANY_TO_ONE, relatedEntity=Person.class, name="parentSsn")} 187 * String m_parentSsn; 188 * }</pre> 189 * 190 * <p>It can also be used to uniquely name a key when multiple secondary 191 * keys for a single entity class have the same field name. For example, 192 * an entity class and its subclass may both have a field named 'date', 193 * and both fields are used as secondary keys. The {@code name} property 194 * can be specified for one or both fields to give each key a unique 195 * name.</p> 196 */ 197 String name() default ""; 198} 199