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. 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 entity with XML metadata, set the access
attribute of your entity
XML element to
FIELD
. To use field access for an 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 use property access, 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) { ... }
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. |
Each class must use either field access or property access for all state; you cannot use both access types within the same class. Additionally, a subclass must use the same access type as its superclass.
The remainder of this document uses the term "persistent field" to refer to either a persistent field or a persistent property.
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.
Annotate your simple identity fields with Id
.
This annotation has no properties. We explore entity identity and
identity fields in Section 4.1.3, “Identity Fields”.
The equivalent XML element is id
. It has one
required attribute:
name
: The name of the identity field or
property.
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 the GeneratedValue
annotation for this purpose. You can only apply the
GeneratedValue
annotation to numeric fields. 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 12.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 | |
---|---|
Kodo allows you to use the
Kodo also offers two additional
generator strategies for non-numeric fields, which you can
access by setting
These string constants are defined in
|
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 4.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.
Use the Version
annotation to designate a
version field. Section 4.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.
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
,
Enum
s, and
Serializable
types.
Basic
declares these properties:
FetchType fetch
: Whether to load the
field eagerly (FetchType.EAGER
) or
lazily (FetchType.LAZY
).
The default is FetchType.EAGER
.
boolean optional
: Whether the datastore
allows null values. The defaults is 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
orLAZY
.
optional
: Boolean indicating whether the
field value may be null.
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 7.3, “Persistence Context”, you can also use eager fetching to ensure that entites have all needed data loaded before they become detached at the end of a persistence context.
Note | |
---|---|
Kodo can lazy-load any field type. Kodo also allows you to dynamically change which fields are eagerly or lazily loaded at runtime. See Section 5.6, “Fetch Groups” in the Reference Guide for details. The Reference Guide details Kodo's eager fetching behavior in Section 5.7, “Eager Fetching”. |
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.
When an entity A
references a single entity
B
, and other A
s 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. The defaults is an empty array.
FetchType fetch
: Whether to load the
field eagerly (FetchType.EAGER
) or
lazily (FetchType.LAZY
).
The defaults is FetchType.EAGER
.
See Section 5.2.6.1, “Fetch Type” above
for details on fetch types.
boolean optional
: Whether the related
object must exist. If false
, this
field cannot be null. The defaults is 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
: Either EAGER
or LAZY
.
optional
: Boolean indicating whether the
field value may be null.
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
an 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.
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>
When an entity A
references multiple
B
entities, and no two A
s
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.
But 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 5.2.8.1, “Cascade Type”. The defaults is
an empty array.
FetchType fetch
: Whether to load the
field eagerly (FetchType.EAGER
) or
lazily (FetchType.LAZY
).
The defaults is FetchType.LAZY
.
See Section 5.2.6.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
: Either EAGER
or LAZY
.
mapped-by
: The name of the field or
property that owns the relation. See
Section 5.2, “Field and Property Metadata”.
You may also nest the cascade
element within
a one-to-many
element.
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 his or
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:
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 12, Mapping Metadata.
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, however, to only mark
one side of the relation as mappedBy
.
One side has to actually do the mapping!
Note | |
---|---|
You can configure Kodo to automatically synchronize both sides of a bidirectional relation, or to perform various actions when it detects inconsistent relations. See Section 5.4, “Managed Inverses” in the Reference Guide for details. |
When an entity A
references a single entity
B
, and no other A
s 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 5.2.9.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 5.2.8.1, “Cascade Type” above.
Defaults to an empty array.
FetchType fetch
: Whether to load the
field eagerly (FetchType.EAGER
) or
lazily (FetchType.LAZY
).
The defaults is FetchType.EAGER
.
See Section 5.2.6.1, “Fetch Type” above
for details on fetch types.
boolean optional
: Whether the related
object must exist. If false
, this
field cannot be null. The defaults is 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
: Either EAGER
or LAZY
.
mapped-by
: The field that owns the
relation. See Section 5.2, “Field and Property Metadata”.
You may also nest the cascade
element within
a one-to-one
element.
When an entity A
references multiple
B
entities, and other A
s
might reference some of the same B
s, 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 5.2.9.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 5.2.8.1, “Cascade Type”. The default is
an empty array.
FetchType fetch
: Whether to load the
field eagerly (FetchType.EAGER
) or
lazily (FetchType.LAZY
).
The defaults is FetchType.LAZY
.
See Section 5.2.6.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
: Either EAGER
or LAZY
.
mapped-by
: The field that owns the
relation. See Section 5.2, “Field and Property Metadata”.
You may also nest the cascade
element within
a many-to-many
element.
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.
Note | |
---|---|
Kodo expands the available ordering syntax. See Section 6.4.2.3, “Order-By” in the Reference Guide for details. |
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, the default is 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.
In the absence of any of the annotations above, JPA defines the following default behavior for declared fields:
Fields declared static, transient
,
or final
default to non-persistent.
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
.
Fields of an embeddable type default to persistent, as
if annotated with
@Embedded
.
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.