com.sleepycat.persist.model.Entity Maven / Gradle / Ivy
/*-
* 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.TYPE;
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.persist.EntityStore;
import com.sleepycat.persist.PrimaryIndex;
import com.sleepycat.persist.SecondaryIndex;
import com.sleepycat.persist.evolve.IncompatibleClassException;
import com.sleepycat.persist.evolve.Mutations;
/**
* Indicates a persistent entity class. For each entity class, a {@link
* PrimaryIndex} can be used to store and access instances of that class.
* Optionally, one or more {@link SecondaryIndex} objects may be used to access
* entity instances by secondary key.
*
* Entity Subclasses and Superclasses
*
* An entity class may have any number of subclasses and superclasses;
* however, none of these may themselves be entity classes (annotated with
* {@code Entity}).
*
* Entity superclasses (which must be annotated with {@code Persistent}, not
* {@code Entity}) are used to share common definitions among entity classes.
* Fields in an entity superclass may be defined as primary or secondary keys.
* For example, the following {@code BaseClass} defines the primary key for any
* number of entity classes, using a single sequence to assign primary key
* values that will be unique across all entity classes that use it. The
* entity class {@code Pet} extends the base class, implicitly defining a
* primary index
*
*
* {@literal @Persistent}
* class BaseClass {
* {@literal @PrimaryKey(sequence="ID")}
* long id;
* }
*
* {@literal @Entity}
* class Pet extends BaseClass {
* {@literal @SecondaryKey(relate=ONE_TO_ONE)}
* String name;
* float height;
* float weight;
* }
*
* Entity subclasses (which must be annotated with {@code Persistent}, not
* {@code Entity}) are used to provide polymorphism within a single {@code
* PrimaryIndex}. Instances of the entity class and its subclasses are stored
* in the same {@code PrimaryIndex}. For example, the entity class {@code Pet}
* defines a primary index that will contain instances of it and its
* subclasses, including {@code Cat} which is defined below.
*
* Fields in an entity subclass may be defined as secondary keys, and such
* secondary keys can only be used to query instances of the subclass. For
* example, although the primary key ({@code id}) and secondary key ({@code
* name}) can be used to retrieve any {@code Pet} instance, the entity subclass
* {@code Cat} defines a secondary key ({@code finickyness}) that only applies
* to {@code Cat} instances. Querying by this key will never retrieve a {@code
* Dog} instance, if such a subclass existed, because a {@code Dog} instance
* will never contain a {@code finickyness} key.
*
*
* {@literal @Persistent}
* class Cat extends Pet {
* {@literal @SecondaryKey(relate=MANY_TO_ONE)}
* int finickyness;
* }
*
* WARNING: Entity subclasses that define secondary keys must be
* registered prior to storing an instance of the class. This can be done in
* two ways:
*
* - The {@link EntityModel#registerClass registerClass} method may be called
* to register the subclass before opening the entity store.
* - The {@link EntityStore#getSubclassIndex getSubclassIndex} method may be
* called to implicitly register the subclass after opening the entity
* store.
*
*
* Persistent Fields and Types
*
* All non-transient instance fields of an entity class, as well as its
* superclasses and subclasses, are persistent. {@code static} and {@code
* transient} fields are not persistent. The persistent fields of a class may
* be {@code private}, package-private (default access), {@code protected} or
* {@code public}.
*
* It is worthwhile to note the reasons that object persistence is defined
* in terms of fields rather than properties (getters and setters). This
* allows business methods (getters and setters) to be defined independently of
* the persistent state of an object; for example, a setter method may perform
* validation that could not be performed if it were called during object
* deserialization. Similarly, this allows public methods to evolve somewhat
* independently of the (typically non-public) persistent fields.
*
*
*
* Persistent types are divided into simple types, enum types, complex
* types, and array types. Simple types and enum types are single valued,
* while array types may contain multiple elements and complex types may
* contain one or more named fields.
*
* Simple types include:
*
* - Java primitive types: {@code boolean, char, byte, short, int, long,
* float, double}
* - The wrapper classes for Java primitive types
* - {@link java.math.BigDecimal}
* - {@link java.math.BigInteger}
* - {@link java.lang.String}
* - {@link java.util.Date}
*
*
* When null values are required (for optional key fields, for example),
* primitive wrapper classes must be used instead of primitive types.
*
* Simple types, enum types and array types do not require annotations to
* make them persistent.
*
*
*
* Complex persistent classes must be annotated with {@link Entity} or
* {@link Persistent}, or must be proxied by a persistent proxy class
* (described below). This includes entity classes, subclasses and
* superclasses, and all other complex classes referenced via fields of these
* classes.
*
* All complex persistent classes must have a default constructor. The
* default constructor may be {@code private}, package-private (default
* access), {@code protected}, or {@code public}. Other constructors are
* allowed but are not used by the persistence mechanism.
*
* It is sometimes desirable to store instances of a type that is externally
* defined and cannot be annotated or does not have a default constructor; for
* example, a class defined in the Java standard libraries or a 3rd party
* library. In this case, a {@link PersistentProxy} class may be used to
* represent the stored values for the externally defined type. The proxy
* class itself must be annotated with {@link Persistent} like other persistent
* classes, and the {@link Persistent#proxyFor} property must be specified.
*
* For convenience, built-in proxy classes are included for several common
* classes (listed below) in the Java library. If you wish, you may define
* your own {@link PersistentProxy} to override these built-in proxies.
*
* - {@link java.util.HashSet}
* - {@link java.util.TreeSet}
* - {@link java.util.HashMap}
* - {@link java.util.TreeMap}
* - {@link java.util.ArrayList}
* - {@link java.util.LinkedList}
*
*
* Complex persistent types should in general be application-defined
* classes. This gives the application control over the persistent state and
* its evolution over time.
*
* Other Type Restrictions
*
* Entity classes and subclasses may not be used in field declarations for
* persistent types. Fields of entity classes and subclasses must be simple
* types or non-entity persistent types (annotated with {@link Persistent} not
* with {@link Entity}).
*
* Entity classes, subclasses and superclasses may be {@code abstract} and
* may implement arbitrary interfaces. Interfaces do not need to be annotated
* with {@link Persistent} in order to be used in a persistent class, since
* interfaces do not contain instance fields.
*
* Persistent instances of static nested classes are allowed, but the nested
* class must be annotated with {@link Persistent} or {@link Entity}. Inner
* classes (non-static nested classes, including anonymous classes) are not
* currently allowed as persistent types.
*
* Arrays of simple and persistent complex types are allowed as fields of
* persistent types. Arrays may be multidimensional. However, an array may
* not be stored as a top level instance in a primary index. Only instances of
* entity classes and subclasses may be top level instances in a primary
* index.
*
* Embedded Objects
*
* As stated above, the embedded (or member) non-transient non-static fields
* of an entity class are themselves persistent and are stored along with their
* parent entity object. This allows embedded objects to be stored in an
* entity to an arbitrary depth.
*
* There is no arbitrary limit to the nesting depth of embedded objects
* within an entity; however, there is a practical limit. When an entity is
* marshalled, each level of nesting is implemented internally via recursive
* method calls. If the nesting depth is large enough, a {@code
* StackOverflowError} can occur. In practice, this has been observed with a
* nesting depth of 12,000, using the default Java stack size.
*
* This restriction on the nesting depth of embedded objects does not apply
* to cyclic references, since these are handled specially as described
* below.
*
* Object Graphs
*
* When an entity instance is stored, the graph of objects referenced via
* its fields is stored and retrieved as a graph. In other words, if a single
* instance is referenced by two or more fields when the entity is stored, the
* same will be true when the entity is retrieved.
*
* When a reference to a particular object is stored as a member field
* inside that object or one of its embedded objects, this is called a cyclic
* reference. Because multiple references to a single object are stored as
* such, cycles are also represented correctly and do not cause infinite
* recursion or infinite processing loops. If an entity containing a cyclic
* reference is stored, the cyclic reference will be present when the entity is
* retrieved.
*
* Note that the stored object graph is restricted in scope to a single
* entity instance. This is because each entity instance is stored separately.
* If two entities have a reference to the same object when stored, they will
* refer to two separate instances when the entities are retrieved.
*
* @see Persistent
* @see PrimaryKey
* @see SecondaryKey
* @see KeyField
*
* @author Mark Hayes
*/
@Documented @Retention(RUNTIME) @Target(TYPE)
public @interface Entity {
/**
* Identifies a new version of a class when an incompatible class change
* has been made. Prior versions of a class are referred to by version
* number to perform class evolution and conversion using {@link
* Mutations}.
*
* The first version of a class is version zero, if {@link #version} is
* not specified. When an incompatible class change is made, a version
* number must be assigned using {@link #version} that is higher than the
* previous version number for the class. If this is not done, an {@link
* IncompatibleClassException} will be thrown when the store is opened.
*
* @return the version.
*/
int version() default 0;
}