JPA recognizes two types of persistent classes:
entity classes and embeddable classes.
Each persistent instance of an entity class - each
entity - represents a unique datastore
record. You can use the EntityManager to find an
entity by its persistent identity (covered later in this chapter), or use
a Query to find entities matching certain criteria.

An instance of an embeddable class, on the other hand, is only stored
as part of a separate entity. Embeddable instances have no
persistent identity, and are never returned directly from the
EntityManager or from a Query.

Despite these differences, there are few differences between entity classes
and embeddable classes. In fact, writing either type
of persistent class is little different than writing any other
class. There are no special parent classes to extend from, field types to
use, or methods to write. This is one important way in which JPA makes
persistence transparent to you, the developer.

Note

JPA supports both fields and JavaBean properties
as persistent state. For simplicity, however, we will
refer to all persistent state as persistent fields, unless we
want to note a unique aspect of persistent properties.

4.1. Restrictions on Persistent Classes

There are very few restrictions placed on persistent classes.
Still, it never hurts to familiarize yourself with exactly what
JPA does and does not support.

4.1.1. Default or No-Arg Constructor

The JPA specification requires that all persistent
classes have a no-arg constructor. This constructor
may be public or protected. Because the compiler automatically
creates a default no-arg constructor when no other constructor
is defined, only classes that define constructors must also
include a no-arg constructor.

Note

Kodo's enhancer will automatically add a
protected no-arg constructor to your class when required.
Therefore, this restriction does not apply when using
Kodo. See Section 5.2, “Enhancement”
of the Reference Guide for details.

4.1.2. Final

Entity classes may not be final. No method of an entity class can
be final.

Note

Kodo supports final classes and final methods.

4.1.3. Identity Fields

All entity classes must declare one or more fields which together
form the persistent identity of an instance. These are called
identity or primary key
fields. In our Magazine class,
isbn and
title are identity fields, because no two
magazine records in the datastore can have the same
isbn and title values.
Section 5.2.2, “Id” will show you how to denote
your identity fields in JPA metadata.
Section 4.2, “Entity Identity” below examines
persistent identity.

4.1.4. Version Field

The version field in our Magazine
class may seem out of place.
JPA uses a version field in your entity to detect
concurrent modifications to the same datastore record. When the
JPA runtime detects an attempt to concurrently modify
the same record, it throws an exception to the transaction
attempting to commit last. This prevents overwriting the previous
commit with stale data.

The version field is not required, but without one concurrent
threads or processes might succeed in making conflicting changes
to the same record at the same time. This is unacceptable to most
applications. Section 5.2.5, “Version”
shows you how to designate a version field in JPA metadata.

The version field must be an integral type (
int, Long, etc) or a
java.sql.Timestamp. You should consider
version fields immutable. Changing the field value has undefined
results.

Note

Kodo fully supports version fields, but does not require them
for concurrency detection. Kodo can maintain
surrogate version values or use state comparisons to detect
concurrent modifications. See
Section 7.7, “Additional JPA Mappings” in the Reference Guide.

4.1.5. Inheritance

JPA fully supports inheritance in persistent classes.
It allows persistent classes to inherit from non-persistent classes,
persistent classes to inherit from other persistent classes,
and non-persistent classes to inherit from persistent classes.
It is even possible to form inheritance hierarchies in which
persistence skips generations. There are, however, a few
important limitations:

Persistent classes cannot inherit from certain
natively-implemented system classes such as
java.net.Socket and
java.lang.Thread.

If a persistent class inherits from a non-persistent
class, the fields of the non-persistent superclass
cannot be persisted.

4.1.6. Persistent Fields

JPA manages the state of all persistent fields.
Before you access persistent state, the JPA runtime
makes sure that it has been loaded from the datastore. When you
set a field, the runtime records that it has changed so that
the new value will be persisted. This allows you to treat the
field in exactly the same way you treat any other field - another
aspect of JPA's transparency.

JPA does not support static or final fields.
It does, however, include built-in support for most
common field types. These types can be roughly divided into three
categories: immutable types, mutable types, and relations.

Immutable types, once created, cannot be
changed. The only way to alter a persistent field of an immutable
type is to assign a new value to the field. JPA
supports the following immutable types:

JPA also supports byte[] and
char[] as immutable types. That is, you
can persist fields of these types, but you should not manipulate
individual array indexes without resetting the array into the
persistent field.

Persistent fields of mutable types
can be altered without assigning the field a new value.
Mutable types can be modified directly through their own
methods. The JPA specification requires that
implementations support the following mutable field types:

java.util.Date

java.util.Calendar

java.sql.Date

java.sql.Timestamp

Enums

Entity types (relations between entities)

Embeddable types

java.util.Collections of entities

java.util.Sets of entities

java.util.Lists of entities

java.util.Maps in which each entry
maps the value of one of an entity's fields to that entity.

Collection and map types may be parameterized.

Most JPA implementations also have support for
persisting serializable values as binary data in the datastore.
Chapter 5, Metadata has more information on
persisting serializable types.

Note

Kodo also supports arrays,
java.lang.Number,
java.util.Locale, all JDK 1.2
Set, List, and
Map types, collections and maps of immutable and
embedded as well as entity types, and many other mutable and
immutable field types. Kodo also allows you to plug in
support for custom types.

4.1.7. Conclusions

This section detailed all of the restrictions JPA
places on persistent classes. While it may seem like we presented
a lot of information, you will seldom find yourself hindered by
these restrictions in practice. Additionally, there are often ways
of using JPA's other features to circumvent any
limitations you run into.