All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sleepycat.persist.model.Entity Maven / Gradle / Ivy

The newest version!
/*-
 * 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:

*
    *
  1. The {@link EntityModel#registerClass registerClass} method may be called * to register the subclass before opening the entity store.
  2. *
  3. The {@link EntityStore#getSubclassIndex getSubclassIndex} method may be * called to implicitly register the subclass after opening the entity * store.
  4. *
* *

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.

* *

Simple Types

* *

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 and Proxy Types

* *

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; }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy