2.  Field and Property Metadata

2.1. Explicit Access
2.2. Transient
2.3. Id
2.4. Generated Value
2.5. Embedded Id
2.6. Version
2.7. Basic
2.7.1. Fetch Type
2.8. Embedded
2.9. Many To One
2.9.1. Cascade Type
2.10. One To Many
2.10.1. Bidirectional Relations
2.11. One To One
2.12. Many To Many
2.13. Order By
2.14. Map Key
2.15. Persistent Field Defaults

The persistence implementation must be able to retrieve and set the persistent state of your entities, mapped superclasses, and embeddable types. JPA offers two modes of persistent state access: field access, and property access. The access type of a persistent attribute can be either set explicitly on a class or attribute level, inherited, or determined by the provider.

Under field access, the implementation injects state directly into your persistent fields, and retrieves changed state from your fields as well. To declare field access on an entire entity with XML metadata, set the access attribute of your entity XML element to FIELD. To use field access for an entire entity using annotation metadata, simply place your metadata and mapping annotations on your field declarations:

@ManyToOne
private Company publisher;

Property access, on the other hand, retrieves and loads state through JavaBean "getter" and "setter" methods. For a property p of type T, you must define the following getter method:

T getP();

For boolean properties, this is also acceptable:

boolean isP();

You must also define the following setter method:

void setP(T value);

To implicitly use property access for an entire class by default, set your entity element's access attribute to PROPERTY, or place your metadata and mapping annotations on the getter method:

@ManyToOne
private Company getPublisher() { ... }

private void setPublisher(Company publisher) { ... }

2.1.  Explicit Access

The access type of a class or individual persistent attributes can be specified explicitly using the @Access annotation or access attribute on the XML elements used to define persistent attributes. When explicitly defining access, specify the explicit access type for the class and then apply the @Access annotation or access XML attribute to individual fields or properties. If explicit FIELD or PROPERTY is specified at the class level, all eligible non-transient fields or properties will be persistent. If using class level FIELD access, non-persistent fields must be transient or annotated with @Transient. If using class level PROPERTY access, non-persistent properties must be annotated @Transient or excluded using the transient XML attribute. Refer to the JPA specification for specific rules regarding the use of explicit access with embeddables and within an inheritance hierarchy.

This entity definitions shows how multiple access types may be specified on an entity:

@Entity
@Access(AccessType.FIELD)
public class PaymentContract {

    @Id
    private String id;

    @Temporal(TemporalType.DATE)
    private String contractDate;
    
    @Transient
    private String terms;
    
    @Version
    private int version;
    
    @Lob
    @Access(AccessType.PROPERTY)
    public String getContractTerms() {
        return terms;
    }
    
    public void setContractTerms(String terms) {
        // Format string before persisting
        this.terms = formatTerms(terms);
    }
    ... 
}

The equivalent declarations in XML:

<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
    version="2.0">
    <entity class="org.xyz.PaymentContract" access="FIELD">
        <attributes>
            <id name="id"/>
             <basic name="contractTerms" access="PROPERTY"> 
                <lob/>
            </basic>
            <basic name="contractDate">
                <temporal>DATE</temporal>
            </basic>
            <version name="version"/>
            <transient name="terms"/>
       </attributes>
    </entity>
</entity-mappings>

Warning

When using property access, only the getter and setter method for a property should ever access the underlying persistent field directly. Other methods, including internal business methods in the persistent class, should go through the getter and setter methods when manipulating persistent state.

Also, take care when adding business logic to your getter and setter methods. Consider that they are invoked by the persistence implementation to load and retrieve all persistent state; other side effects might not be desirable.

The remainder of this document uses the term "persistent field" to refer to either a persistent field or a persistent property.

2.2.  Transient

The Transient annotation specifies that a field is non-persistent. Use it to exclude fields from management that would otherwise be persistent. Transient is a marker annotation only; it has no properties.

The equivalent XML element is transient. It has a single attribute:

  • name: The transient field or property name. This attribute is required.

2.3.  Id

Annotate your simple identity fields with Id. This annotation has no properties. We explore entity identity and identity fields in Section 1.3, “ Identity Fields ”.

The equivalent XML element is id. It has one required attribute:

  • name: The name of the identity field or property.

2.4.  Generated Value

The previous section showed you how to declare your identity fields with the Id annotation. It is often convenient to allow the persistence implementation to assign a unique value to your identity fields automatically. JPA includes the GeneratedValue annotation for this purpose. It has the following properties:

  • GenerationType strategy: Enum value specifying how to auto-generate the field value. The GenerationType enum has the following values:

    • GeneratorType.AUTO: The default. Assign the field a generated value, leaving the details to the JPA vendor.

    • GenerationType.IDENTITY: The database will assign an identity value on insert.

    • GenerationType.SEQUENCE: Use a datastore sequence to generate a field value.

    • GenerationType.TABLE: Use a sequence table to generate a field value.

  • String generator: The name of a generator defined in mapping metadata. We show you how to define named generators in Section 5, “ Generators ”. If the GenerationType is set but this property is unset, the JPA implementation uses appropriate defaults for the selected generation type.

The equivalent XML element is generated-value, which includes the following attributes:

  • strategy: One of TABLE, SEQUENCE, IDENTITY, or AUTO, defaulting to AUTO.

  • generator: Equivalent to the generator property listed above.

Note

OpenJPA allows you to use the GeneratedValue annotation on any field, not just identity fields. Before using the IDENTITY generation strategy, however, read Section 4.4, “ Autoassign / Identity Strategy Caveats ” in the Reference Guide.

OpenJPA also offers additional generator strategies for non-numeric fields, which you can access by setting strategy to AUTO (the default), and setting the generator string to:

  • uuid-string: OpenJPA will generate a 128-bit type 1 UUID unique within the network, represented as a 16-character string. For more information on UUIDs, see the IETF UUID draft specification at: http://www.ics.uci.edu/~ejw/authoring/uuid-guid/

  • uuid-hex: Same as uuid-string, but represents the type 1 UUID as a 32-character hexadecimal string.

  • uuid-type4-string: OpenJPA will generate a 128-bit type 4 pseudo-random UUID, represented as a 16-character string. For more information on UUIDs, see the IETF UUID draft specification at: http://www.ics.uci.edu/~ejw/authoring/uuid-guid/

  • uuid-type4-hex: Same as uuid-type4-string , but represents the type 4 UUID as a 32-character hexadecimal string.

These string constants are defined in org.apache.openjpa.persistence.Generator.

If the entities are mapped to the same table name but with different schema name within one PersistenceUnit intentionally, and the strategy of GeneratedType.AUTO is used to generate the ID for each entity, a schema name for each entity must be explicitly declared either through the annotation or the mapping.xml file. Otherwise, the mapping tool only creates the tables for those entities with the schema names under each schema. In addition, there will be only one OPENJPA_SEQUENCE_TABLE created for all the entities within the PersistenceUnit if the entities are not identified with the schema name. Read Section 6, “ Generators ” and Section 11, “ Default Schema ” in the Reference Guide.

2.5.  Embedded Id

If your entity has multiple identity values, you may declare multiple @Id fields, or you may declare a single @EmbeddedId field. The type of a field annotated with EmbeddedId must be an embeddable entity class. The fields of this embeddable class are considered the identity values of the owning entity. We explore entity identity and identity fields in Section 1.3, “ Identity Fields ”.

The EmbeddedId annotation has no properties.

The equivalent XML element is embedded-id. It has one required attribute:

  • name: The name of the identity field or property.

2.6.  Version

Use the Version annotation to designate a version field. Section 1.4, “ Version Field ” explained the importance of version fields to JPA. This is a marker annotation; it has no properties.

The equivalent XML element is version, which has a single attribute:

  • name: The name of the version field or property. This attribute is required.

2.7.  Basic

Basic signifies a standard value persisted as-is to the datastore. You can use the Basic annotation on persistent fields of the following types: primitives, primitive wrappers, java.lang.String, byte[], Byte[], char[], Character[], java.math.BigDecimal, java.math.BigInteger, java.util.Date, java.util.Calendar, java.sql.Date, java.sql.Timestamp, Enums, and Serializable types.

Basic declares these properties:

  • FetchType fetch: Whether to load the field eagerly (FetchType.EAGER) or lazily ( FetchType.LAZY). Defaults to FetchType.EAGER.

  • boolean optional: Whether the datastore allows null values. Defaults to true.

The equivalent XML element is basic. It has the following attributes:

  • name: The name of the field or property. This attribute is required.

  • fetch: One of EAGER or LAZY .

  • optional: Boolean indicating whether the field value may be null.

2.7.1.  Fetch Type

Many metadata annotations in JPA have a fetch property. This property can take on one of two values: FetchType.EAGER or FetchType.LAZY. FetchType.EAGER means that the field is loaded by the JPA implementation before it returns the persistent object to you. Whenever you retrieve an entity from a query or from the EntityManager, you are guaranteed that all of its eager fields are populated with datastore data.

FetchType.LAZY is a hint to the JPA runtime that you want to defer loading of the field until you access it. This is called lazy loading. Lazy loading is completely transparent; when you attempt to read the field for the first time, the JPA runtime will load the value from the datastore and populate the field automatically. Lazy loading is only a hint and not a directive because some JPA implementations cannot lazy-load certain field types.

With a mix of eager and lazily-loaded fields, you can ensure that commonly-used fields load efficiently, and that other state loads transparently when accessed. As you will see in Section 3, “ Persistence Context ”, you can also use eager fetching to ensure that entities have all needed data loaded before they become detached at the end of a persistence context.

Note

OpenJPA can lazy-load any field type. OpenJPA also allows you to dynamically change which fields are eagerly or lazily loaded at runtime. See Section 7, “ Fetch Groups ” in the Reference Guide for details.

The Reference Guide details OpenJPA's eager fetching behavior in Section 8, “ Eager Fetching ”.

2.8.  Embedded

Use the Embedded marker annotation on embeddable field types. Embedded fields are mapped as part of the datastore record of the declaring entity. In our sample model, Author and Company each embed their Address, rather than forming a relation to an Address as a separate entity.

The equivalent XML element is embedded, which expects a single attribute:

  • name: The name of the field or property. This attribute is required.

2.9.  Many To One

When an entity A references a single entity B, and other As might also reference the same B, we say there is a many to one relation from A to B. In our sample model, for example, each magazine has a reference to its publisher. Multiple magazines might have the same publisher. We say, then, that the Magazine.publisher field is a many to one relation from magazines to publishers.

JPA indicates many to one relations between entities with the ManyToOne annotation. This annotation has the following properties:

  • Class targetEntity: The class of the related entity type.

  • CascadeType[] cascade: Array of enum values defining cascade behavior for this field. We explore cascades below. Defaults to an empty array.

  • FetchType fetch: Whether to load the field eagerly (FetchType.EAGER) or lazily (FetchType.LAZY). Defaults to FetchType.EAGER. See Section 2.7.1, “ Fetch Type ” above for details on fetch types.

  • boolean optional: Whether the related object must exist. If false, this field cannot be null. Defaults to true.

The equivalent XML element is many-to-one. It accepts the following attributes:

  • name: The name of the field or property. This attribute is required.

  • target-entity: The class of the related type.

  • fetch: One of EAGER or LAZY.

  • optional: Boolean indicating whether the field value may be null.

2.9.1.  Cascade Type

We introduce the JPA EntityManager in Chapter 8, EntityManager . The EntityManager has APIs to persist new entities, remove (delete) existing entities, refresh entity state from the datastore, and merge detached entity state back into the persistence context. We explore all of these APIs in detail later in the overview.

When the EntityManager is performing the above operations, you can instruct it to automatically cascade the operation to the entities held in a persistent field with the cascade property of your metadata annotation. This process is recursive. The cascade property accepts an array of CascadeType enum values.

  • CascadeType.PERSIST: When persisting an entity, also persist the entities held in this field. We suggest liberal application of this cascade rule, because if the EntityManager finds a field that references a new entity during flush, and the field does not use CascadeType.PERSIST, it is an error.

  • CascadeType.REMOVE: When deleting an entity, also delete the entities held in this field.

  • CascadeType.REFRESH: When refreshing an entity, also refresh the entities held in this field.

  • CascadeType.MERGE: When merging entity state, also merge the entities held in this field.

Note

OpenJPA offers enhancements to JPA's CascadeType.REMOVE functionality, including additional annotations to control how and when dependent fields will be removed. See Section 4.2.1, “ Dependent ” for more details.

CascadeType defines one additional value, CascadeType.ALL, that acts as a shortcut for all of the values above. The following annotations are equivalent:

@ManyToOne(cascade={CascadeType.PERSIST,CascadeType.REMOVE,
    CascadeType.REFRESH,CascadeType.MERGE})
private Company publisher;
@ManyToOne(cascade=CascadeType.ALL)
private Company publisher;

In XML, these enumeration constants are available as child elements of the cascade element. The cascade element is itself a child of many-to-one. The following examples are equivalent:

<many-to-one name="publisher">
    <cascade>
        <cascade-persist/>
        <cascade-merge/>
        <cascade-remove/>
        <cascade-refresh/>
    </cascade>
</many-to-one>
<many-to-one name="publisher">
    <cascade>
        <cascade-all/>
    </cascade>
</many-to-one>

2.10.  One To Many

When an entity A references multiple B entities, and no two As reference the same B, we say there is a one to many relation from A to B.

One to many relations are the exact inverse of the many to one relations we detailed in the preceding section. In that section, we said that the Magazine.publisher field is a many to one relation from magazines to publishers. Now, we see that the Company.mags field is the inverse - a one to many relation from publishers to magazines. Each company may publish multiple magazines, but each magazine can have only one publisher.

JPA indicates one to many relations between entities with the OneToMany annotation. This annotation has the following properties:

  • Class targetEntity: The class of the related entity type. This information is usually taken from the parameterized collection or map element type. You must supply it explicitly, however, if your field isn't a parameterized type.

  • String mappedBy: Names the many to one field in the related entity that maps this bidirectional relation. We explain bidirectional relations below. Leaving this property unset signals that this is a standard unidirectional relation.

  • CascadeType[] cascade: Array of enum values defining cascade behavior for the collection elements. We explore cascades above in Section 2.9.1, “ Cascade Type ”. Defaults to an empty array.

  • FetchType fetch: Whether to load the field eagerly (FetchType.EAGER) or lazily (FetchType.LAZY). Defaults to FetchType.LAZY. See Section 2.7.1, “ Fetch Type ” above for details on fetch types.

The equivalent XML element is one-to-many, which includes the following attributes:

  • name: The name of the field or property. This attribute is required.

  • target-entity: The class of the related type.

  • fetch: One of EAGER or LAZY.

  • mapped-by: The name of the field or property that owns the relation. See Section 2, “ Field and Property Metadata ”.

You may also nest the cascade element within a one-to-many element.

2.10.1.  Bidirectional Relations

When two fields are logical inverses of each other, they form a bidirectional relation. Our model contains two bidirectional relations: Magazine.publisher and Company.mags form one bidirectional relation, and Article.authors and Author.articles form the other. In both cases, there is a clear link between the two fields that form the relationship. A magazine refers to its publisher while the publisher refers to all its published magazines. An article refers to its authors while each author refers to her written articles.

When the two fields of a bidirectional relation share the same datastore mapping, JPA formalizes the connection with the mappedBy property. Marking Company.mags as mappedBy Magazine.publisher means two things:

  1. Company.mags uses the datastore mapping for Magazine.publisher, but inverses it. In fact, it is illegal to specify any additional mapping information when you use the mappedBy property. All mapping information is read from the referenced field. We explore mapping in depth in Chapter 13, Mapping Metadata .

  2. Magazine.publisher is the "owner" of the relation. The field that specifies the mapping data is always the owner. This means that changes to the Magazine.publisher field are reflected in the datastore, while changes to the Company.mags field alone are not. Changes to Company.mags may still affect the JPA implementation's cache, however. Thus, it is very important that you keep your object model consistent by properly maintaining both sides of your bidirectional relations at all times.

You should always take advantage of the mappedBy property rather than mapping each field of a bidirectional relation independently. Failing to do so may result in the JPA implementation trying to update the database with conflicting data. Be careful to only mark one side of the relation as mappedBy, however. One side has to actually do the mapping!

Note

You can configure OpenJPA to automatically synchronize both sides of a bidirectional relation, or to perform various actions when it detects inconsistent relations. See Section 5, “ Managed Inverses ” in the Reference Guide for details.

2.11.  One To One

When an entity A references a single entity B, and no other As can reference the same B, we say there is a one to one relation between A and B. In our sample model, Magazine has a one to one relation to Article through the Magazine.coverArticle field. No two magazines can have the same cover article.

JPA indicates one to one relations between entities with the OneToOne annotation. This annotation has the following properties:

  • Class targetEntity: The class of the related entity type. This information is usually taken from the field type.

  • String mappedBy: Names the field in the related entity that maps this bidirectional relation. We explain bidirectional relations in Section 2.10.1, “ Bidirectional Relations ” above. Leaving this property unset signals that this is a standard unidirectional relation.

  • CascadeType[] cascade: Array of enum values defining cascade behavior for this field. We explore cascades in Section 2.9.1, “ Cascade Type ” above. Defaults to an empty array.

  • FetchType fetch: Whether to load the field eagerly (FetchType.EAGER) or lazily (FetchType.LAZY). Defaults to FetchType.EAGER. See Section 2.7.1, “ Fetch Type ” above for details on fetch types.

  • boolean optional: Whether the related object must exist. If false, this field cannot be null. Defaults to true.

The equivalent XML element is one-to-one which understands the following attributes:

  • name: The name of the field or property. This attribute is required.

  • target-entity: The class of the related type.

  • fetch: One of EAGER or LAZY.

  • mapped-by: The field that owns the relation. See Section 2, “ Field and Property Metadata ”.

You may also nest the cascade element within a one-to-one element.

2.12.  Many To Many

When an entity A references multiple B entities, and other As might reference some of the same Bs, we say there is a many to many relation between A and B. In our sample model, for example, each article has a reference to all the authors that contributed to the article. Other articles might have some of the same authors. We say, then, that Article and Author have a many to many relation through the Article.authors field.

JPA indicates many to many relations between entities with the ManyToMany annotation. This annotation has the following properties:

  • Class targetEntity: The class of the related entity type. This information is usually taken from the parameterized collection or map element type. You must supply it explicitly, however, if your field isn't a parameterized type.

  • String mappedBy: Names the many to many field in the related entity that maps this bidirectional relation. We explain bidirectional relations in Section 2.10.1, “ Bidirectional Relations ” above. Leaving this property unset signals that this is a standard unidirectional relation.

  • CascadeType[] cascade: Array of enum values defining cascade behavior for the collection elements. We explore cascades above in Section 2.9.1, “ Cascade Type ”. Defaults to an empty array.

  • FetchType fetch: Whether to load the field eagerly (FetchType.EAGER) or lazily (FetchType.LAZY). Defaults to FetchType.LAZY. See Section 2.7.1, “ Fetch Type ” above for details on fetch types.

The equivalent XML element is many-to-many. It accepts the following attributes:

  • name: The name of the field or property. This attribute is required.

  • target-entity: The class of the related type.

  • fetch: One of EAGER or LAZY.

  • mapped-by: The field that owns the relation. See Section 2, “ Field and Property Metadata ”.

You may also nest the cascade element within a many-to-many element.

2.13.  Order By

Datastores such as relational databases do not preserve the order of records. Your persistent List fields might be ordered one way the first time you retrieve an object from the datastore, and a completely different way the next. To ensure consistent ordering of collection fields, you must use the OrderBy annotation. The OrderBy annotation's value is a string defining the order of the collection elements. An empty value means to sort on the identity value(s) of the elements in ascending order. Any other value must be of the form:

<field name>[ ASC|DESC][, ...]

Each <field name> is the name of a persistent field in the collection's element type. You can optionally follow each field by the keyword ASC for ascending order, or DESC for descending order. If the direction is omitted, it defaults to ascending.

The equivalent XML element is order-by which can be listed as a sub-element of the one-to-many or many-to-many elements. The text within this element is parsed as the order by string.

2.14.  Map Key

JPA supports persistent Map fields through either a OneToMany or ManyToMany association. The related entities form the map values. JPA derives the map keys by extracting a field from each entity value. The MapKey annotation designates the field that is used as the key. It has the following properties:

  • String name: The name of a field in the related entity class to use as the map key. If no name is given, defaults to the identity field of the related entity class.

The equivalent XML element is map-key which can be listed as a sub-element of the one-to-many or many-to-many elements. The map-key element has the following attributes:

  • name: The name of the field in the related entity class to use as the map key.

2.15.  Persistent Field Defaults

In the absence of any of the annotations above, JPA defines the following default behavior for declared fields:

  1. Fields declared static, transient, or final default to non-persistent.

  2. Fields of any primitive type, primitive wrapper type, java.lang.String, byte[], Byte[], char[], Character[], java.math.BigDecimal, java.math.BigInteger, java.util.Date, java.util.Calendar, java.sql.Date, java.sql.Timestamp, or any Serializable type default to persistent, as if annotated with @Basic.

  3. Fields of an embeddable type default to persistent, as if annotated with @Embedded.

  4. All other fields default to non-persistent.

Note that according to these defaults, all relations between entities must be annotated explicitly. Without an annotation, a relation field will default to serialized storage if the related entity type is serializable, or will default to being non-persistent if not.