Java Persistence 2 0 Edr Spec
Java Persistence 2 0 Edr Spec
Specification Lead:
Linda DeMichiel, Sun Microsystems
af t
Dr
ly
E ar
Version 2.0, Early Draft
April 14, 2008
Java Persistence 2.0, Early Draft Sun Microsystems, Inc.
NOTICE
The Specification is protected by copyright and the information described therein may be protected by
one or more U.S. patents, foreign patents, or pending applications. Except as provided under the follow-
ing license, no part of the Specification may be reproduced in any form by any means without the prior
written authorization of Sun Microsystems, Inc. ("Sun") and its licensors, if any. Any use of the Speci-
fication and the information described therein will be governed by the terms and conditions of this Agree-
ment.
Subject to the terms and conditions of this license, including your compliance with Paragraphs 1 and 2
below, Sun hereby grants you a fully-paid, non-exclusive, non-transferable, limited license (without the
right to sublicense) under Sun's intellectual property rights to:
1. Review the Specification for the purposes of evaluation. This includes: (i) developing implementa-
tions of the Specification for your internal, non-commercial use; (ii) discussing the Specification with
any third party; and (iii) excerpting brief portions of the Specification in oral or written communications
which discuss the Specification provided that such excerpts do not in the aggregate constitute a signifi-
cant portion of the Technology.
2. Distribute implementations of the Specification to third parties for their testing and evaluation use, pro-
vided that any such implementation:
(i) does not modify, subset, superset or otherwise extend the Licensor Name Space, or include any public
or protected packages, classes, Java interfaces, fields or methods within the Licensor Name Space other
than those required/authorized by the Specification or Specifications being implemented;
(ii) is clearly and prominently marked with the word "UNTESTED" or "EARLY ACCESS" or "INCOM-
PATIBLE" or "UNSTABLE" or "BETA" in any list of available builds and in proximity to every link
initiating its download, where the list or link is under Licensee's control; and
(iii) includes the following notice:
"This is an implementation of an early-draft specification developed under the Java Community Process
(JCP) and is made available for testing and evaluation purposes only. The code is not compatible with
any specification of the JCP."
The grant set forth above concerning your distribution of implementations of the specification is contin-
gent upon your agreement to terminate development and distribution of your "early draft" implementa-
tion as soon as feasible following final completion of the specification. If you fail to do so, the foregoing
grant shall be considered null and void.
No provision of this Agreement shall be understood to restrict your ability to make and distribute to third
parties applications written to the Specification.
Other than this limited license, you acquire no right, title or interest in or to the Specification or any other
Sun intellectual property, and the Specification may only be used in accordance with the license terms
set forth herein. This license will expire on the earlier of: (a) two (2) years from the date of Release listed
2 4/14/08
Java Persistence 2.0, Early Draft Sun Microsystems, Inc.
above; (b) the date on which the final version of the Specification is publicly released; or (c) the date on
which the Java Specification Request (JSR) to which the Specification corresponds is withdrawn. In ad-
dition, this license will terminate immediately without notice from Sun if you fail to comply with any
provision of this license. Upon termination, you must cease use of or destroy the Specification.
"Licensor Name Space" means the public class or interface declarations whose names begin with "java",
"javax", "com.sun" or their equivalents in any subsequent naming convention adopted by Sun through
the Java Community Process, or any recognized successors or replacements thereof.
TRADEMARKS
No right, title, or interest in or to any trademarks, service marks, or trade names of Sun or Sun's licensors
is granted hereunder. Sun, Sun Microsystems, the Sun logo, Java are trademarks or registered trademarks
of Sun Microsystems, Inc. in the U.S. and other countries.
DISCLAIMER OF WARRANTIES
THE SPECIFICATION IS PROVIDED "AS IS" AND IS EXPERIMENTAL AND MAY CONTAIN
DEFECTS OR DEFICIENCIES WHICH CANNOT OR WILL NOT BE CORRECTED BY SUN. SUN
MAKES NO REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS OR IMPLIED, IN-
CLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, OR NON-INFRINGEMENT THAT THE CONTENTS OF THE SPECIFI-
CATION ARE SUITABLE FOR ANY PURPOSE OR THAT ANY PRACTICE OR IMPLEMENTA-
TION OF SUCH CONTENTS WILL NOT INFRINGE ANY THIRD PARTY PATENTS,
COPYRIGHTS, TRADE SECRETS OR OTHER RIGHTS. This document does not represent any com-
mitment to release or implement any portion of the Specification in any product.
LIMITATION OF LIABILITY
TO THE EXTENT NOT PROHIBITED BY LAW, IN NO EVENT WILL SUN OR ITS LICENSORS
BE LIABLE FOR ANY DAMAGES, INCLUDING WITHOUT LIMITATION, LOST REVENUE,
PROFITS OR DATA, OR FOR SPECIAL, INDIRECT, CONSEQUENTIAL, INCIDENTAL OR PU-
NITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILI-
TY, ARISING OUT OF OR RELATED TO ANY FURNISHING, PRACTICING, MODIFYING OR
ANY USE OF THE SPECIFICATION, EVEN IF SUN AND/OR ITS LICENSORS HAVE BEEN AD-
VISED OF THE POSSIBILITY OF SUCH DAMAGES.
You will hold Sun (and its licensors) harmless from any claims based on your use of the Specification
for any purposes other than the limited right of evaluation as described above, and from any claims that
later versions or releases of any Specification furnished to you are incompatible with the Specification
provided to you under this license.
3 4/14/08
Java Persistence 2.0, Early Draft Sun Microsystems, Inc.
through 227.7202-4 (for Department of Defense (DoD) acquisitions) and with 48 C.F.R. 2.101 and
12.212 (for non-DoD acquisitions).
REPORT
You may wish to report any ambiguities, inconsistencies or inaccuracies you may find in connection with
your evaluation of the Specification ("Feedback"). To the extent that you provide Sun with any Feed-
back, you hereby: (i) agree that such Feedback is provided on a non-proprietary and non-confidential ba-
sis, and (ii) grant Sun a perpetual, non-exclusive, worldwide, fully paid-up, irrevocable license, with the
right to sublicense through multiple levels of sublicensees, to incorporate, disclose, and use without lim-
itation the Feedback for any purpose related to the Specification and future versions, implementations,
and test suites thereof.
GENERAL TERMS
Any action related to this Agreement will be governed by California law and controlling U.S. federal law.
The U.N. Convention for the International Sale of Goods and the choice of law rules of any jurisdiction
will not apply.
The Specification is subject to U.S. export control laws and may be subject to export or import regula-
tions in other countries. Licensee agrees to comply strictly with all such laws and regulations and ac-
knowledges that it has the responsibility to obtain such licenses to export, re-export or import as may be
required after delivery to Licensee.
This Agreement is the parties' entire agreement relating to its subject matter. It supersedes all prior or
contemporaneous oral or written communications, proposals, conditions, representations and warranties
and prevails over any conflicting or additional terms of any quote, order, acknowledgment, or other com-
munication between the parties relating to its subject matter during the term of this Agreement. No mod-
ification to this Agreement will be binding, unless in writing and signed by an authorized representative
of each party.
4 4/14/08
Sun Microsystems, Inc.
Table of Contents
Chapter 1 Introduction.................................................................................................................... 15
1.1 Expert Group ................................................................................................... 15
1.2 Document Conventions ................................................................................... 15
5 4/14/08
Sun Microsystems, Inc.
4/14/08 6
Sun Microsystems, Inc.
7 4/14/08
Sun Microsystems, Inc.
4/14/08 8
Sun Microsystems, Inc.
tion154
5.8 Requirements on the Container ....................................................................... 155
5.8.1 Application-managed Persistence Contexts...................................... 155
5.8.2 Container Managed Persistence Contexts......................................... 155
5.9 Runtime Contracts between the Container and Persistence Provider ............. 155
5.9.1 Container Responsibilities ................................................................ 155
5.9.2 Provider Responsibilities .................................................................. 157
5.10 Cache Interface................................................................................................ 158
Chapter 7 Container and Provider Contracts for Deployment and Bootstrapping......................... 173
7.1 Java EE Deployment ....................................................................................... 173
7.1.1 Responsibilities of the Container ...................................................... 173
7.1.2 Responsibilities of the Persistence Provider ..................................... 174
7.1.3 javax.persistence.spi.PersistenceProvider......................................... 174
7.1.3.1 Persistence Unit Properties ................................................. 175
7.1.4 javax.persistence.spi.PersistenceUnitInfo Interface.......................... 177
7.2 Bootstrapping in Java SE Environments ......................................................... 180
7.2.1 javax.persistence.Persistence Class................................................... 182
9 4/14/08
Sun Microsystems, Inc.
4/14/08 10
Sun Microsystems, Inc.
11 4/14/08
Sun Microsystems, Inc.
4/14/08 12
Sun Microsystems, Inc.
List of Tables
Table 1 Definition of the AND Operator ...........................................................................................................129
Table 2 Definition of the OR Operator ..............................................................................................................130
Table 3 Definition of the NOT Operator............................................................................................................130
Table 4 AssociationOverride Annotation Elements ...........................................................................................193
Table 5 AttributeOverride Annotation Elements ...............................................................................................196
Table 6 Basic Annotation Elements ...................................................................................................................199
Table 7 CollectionTable Annotation Elements ..................................................................................................200
Table 8 Column Annotation Elements ...............................................................................................................202
Table 9 DiscriminatorColumn Annotation Elements.........................................................................................204
Table 10 DiscriminatorValueAnnotation Elements..............................................................................................205
Table 11 ElementCollection Annotation Elements ..............................................................................................206
Table 12 Enumerated Annotation Elements.........................................................................................................209
Table 13 GeneratedValue Annotation Elements ..................................................................................................210
Table 14 Inheritance Annotation Elements ..........................................................................................................212
Table 15 JoinColumn Annotation Elements ........................................................................................................213
Table 16 JoinTable Annotation Elements ............................................................................................................216
Table 17 ManyToMany Annotation Elements .....................................................................................................218
Table 18 ManyToOne Annotation Elements........................................................................................................221
Table 19 MapKeyColumn Annotation Elements .................................................................................................225
Table 20 MapKeyJoinColumn Annotation Elements ..........................................................................................227
Table 21 OneToMany Annotation Elements........................................................................................................232
Table 22 OneToOne Annotation Elements ..........................................................................................................234
Table 23 OrderColumn Annotation Elements......................................................................................................238
Table 24 PrimaryKeyJoinColumn Annotation Elements.....................................................................................241
Table 25 SecondaryTable Annotation Elements ..................................................................................................243
Table 26 SequenceGenerator Annotation Elements.............................................................................................245
Table 27 Table Annotation Elements ...................................................................................................................246
Table 28 TableGenerator Annotation Elements ...................................................................................................247
Table 29 Temporal Annotation Elements.............................................................................................................249
Table 30 UniqueConstraint Annotation Elements................................................................................................250
13 4/14/08
Sun Microsystems, Inc.
4/14/08 14
Sun Microsystems, Inc.
Java Persistence 2.0, Early Draft
C ha p t e r 1 Introduction
This document is the specification of the Java API for the management of persistence and object/rela-
tional mapping with Java EE and Java SE. The technical objective of this work is to provide an
object/relational mapping facility for the Java application developer using a Java domain model to man-
age a relational database.
This is the first Early Draft of the Java Persistence 2.0 specification. This draft addresses
improvements in the areas of domain modeling, O/R mapping, and EntityManager and
Query[1] runtime APIs.
This work is being conducted as part of JSR 317 under the Java Community Process Program. This
specification is the result of the collaborative work of the members of the JSR 317 Expert Group:
Adobe Systems Inc.: Jeff Vroom; akquinet tech@Spree: Michael Bouschen; BEA Systems: Patrick Lin-
skey; DataDirect: Eric Samson; Ericsson AB: Erik Brakkee; IBM: Kevin Sutter; Inria: Florent Benoit;
Oracle: Michael Keith, Gordon Yorke; Pramati Technologies: Deepak Anupalli; Red Hat Middleware
LLC: Gavin King, Emmanuel Bernard; SAP AG: Rainer Schweigkoffer, Adrian Goerler; SpringSource
Inc.: Matthew Adams; Sun Microsystems: Linda DeMichiel (Specification Lead), Kenneth Saks;
Sybase: Evan Ireland; Tmax Soft Inc.: Wonseok Kim; Adam Bien; Antonio Goncalves; Chris Maki.
The regular Times font is used for information that is prescriptive by this specification.
The italic Times font is used for paragraphs that contain descriptive information, such as notes describ-
ing typical use, or notes clarifying the text with prescriptive specification.
The Helvetica font is used to specify the BNF of the Java Persistence query language.
[1] We plan to address extensions to the Java Persistence query language and an API for criteria queries in the next draft of this spec-
ification.
15 4/14/08
Sun Microsystems, Inc.
This document is written in terms of the use of Java language metadata annotations. An XML descriptor
(as specified in Chapter 10) may be used as an alternative to annotations or to augment or override
annotations. The elements of this descriptor mirror the annotations and have the same semantics. When
semantic requirements are written in terms of annotations, it should be understood that the same seman-
tics apply when the XML descriptor is used as an alternative.
C ha p t e r 2 Entities
The primary programming artifact is the entity class. An entity class may make use of auxiliary classes
that serve as helper classes or that are used to represent the state of the entity.
The entity class must be annotated with the Entity annotation or denoted in the XML descriptor as an
entity.
The entity class must have a no-arg constructor. The entity class may have other constructors as well.
The no-arg constructor must be public or protected.
The entity class must be a top-level class. An enum or interface must not be designated as an entity.
The entity class must not be final. No methods or persistent instance variables of the entity class may be
final.
Entities Java Persistence 2.0, Early Draft Persistent Fields and Properties
If an entity instance is to be passed by value as a detached object (e.g., through a remote interface), the
entity class must implement the Serializable interface.
Both abstract and concrete classes can be entities. Entities may extend non-entity classes as well as
entity classes, and non-entity classes may extend entity classes.
The persistent state of an entity is represented by instance variables, which may correspond to Java-
Beans properties. An instance variable must be directly accessed only from within the methods of the
entity by the entity instance itself. Instance variables must not be accessed by clients of the entity. The
state of the entity is available to clients only through the entity’s methods—i.e., accessor methods (get-
ter/setter methods) or other business methods.
The persistent state of an entity is accessed by the persistence provider runtime[2] either via JavaBeans
style property accessors (“property access”) or via instance variables (“field access”). Whether persis-
tent properties or persistent fields or a combination of the two is used for the provider’s access to a
given class or entity hierarchy is determined as described in Section 2.3, “Access Type”.
Terminology Note: The persistent fields and properties of an entity class are generically
referred to in this document as the “attributes” of the class.
The instance variables of a class must be private, protected, or package visibility independent of
whether field access or property access is used. When property-based access is used, the property acces-
sor methods must be public or protected.
It is required that the entity class follow the method signature conventions for JavaBeans read/write
properties (as defined by the JavaBeans Introspector class) for persistent properties when prop-
erty-based access is used.
In this case, for every persistent property property of type T of the entity, there is a getter method, get-
Property, and setter method setProperty. For boolean properties, isProperty may be used as an alterna-
tive name for the getter method.[3]
• T getProperty()
• void setProperty(T t)
[2] The term "persistence provider runtime" refers to the runtime environment of the persistence implementation. In Java EE envi-
ronments, this may be the Java EE container or a third-party persistence provider implementation integrated with it.
[3] Specifically, if getX is the name of the getter method and setX is the name ofthe setter method, where X is a string, the name of the
persistent property is defined by the result of java.beans.Introspector.decapitalize(X).
Persistent Fields and Properties Java Persistence 2.0, Early Draft Entities
Collection-valued persistent fields and properties must be defined in terms of one of the following col-
lection-valued interfaces regardless of whether the entity class otherwise adheres to the JavaBeans
method conventions noted above and whether field or property-based access is used:
java.util.Collection, java.util.Set, java.util.List[4], java.util.Map.[5]
Terminology Note: The terms “collection” and “collection-valued” are used in this specifica-
tion to denote any of the above types unless further qualified. In cases where a
java.util.Collection type (or one of its subtypes) is to be distinguished, the type is
identified as such. The term “map collection” is used to apply to a collection of type
java.util.Map.
For collection-valued persistent properties, type T must be one of these collection interface types in the
method signatures above. Generic variants of these collection types may also be used (for example,
Set<Order>).
In addition to returning and setting the persistent state of the instance, property accessor methods may
contain other business logic as well, for example, to perform validation. The persistence provider runt-
ime executes this logic when property-based access is used.
Caution should be exercised in adding business logic to the accessor methods when prop-
erty-based access is used. The order in which the persistence provider runtime calls these
methods when loading or storing persistent state is not defined. Logic contained in such meth-
ods therefore cannot rely upon a specific invocation order.
If property-based access is used and lazy fetching is specified, portable applications should not directly
access the entity state underlying the property methods of managed instances until after it has been
fetched by the persistence provider.[6]
Runtime exceptions thrown by property accessor methods cause the current transaction to be marked for
rollback. Exceptions thrown by such methods when used by the persistence runtime to load or store per-
sistent state cause the persistence runtime to mark the current transaction for rollback and to throw a
PersistenceException that wraps the application exception.
Entity subclasses may override the property accessor methods. However, portable applications must not
override the object/relational mapping metadata that applies to the persistent fields or properties of
entity superclasses.
[4] Portable applications should not expect the order of a list to be maintained across persistence contexts unless the OrderColumn
construct is used or unless the OrderBy construct is used and the modifications to the list observe the specified ordering.
[5] The implementation type may be used by the application to initialize fields or properties before the entity is made persistent. Once
the entity becomes managed (or detached), subsequent access must be through the interface type.
[6] Lazy fetching is a hint to the persistence provider and can be specified by means of the Basic, OneToOne, OneToMany,
ManyToOne, ManyToMany, and ElementCollection annotations and their XML equivalents. See Chapter 9.
Entities Java Persistence 2.0, Early Draft Persistent Fields and Properties
The persistent fields or properties of an entity may be of the following types: Java primitive types;
java.lang.String; other Java serializable types (including wrappers of the primitive types,
java.math.BigInteger, java.math.BigDecimal, java.util.Date,
java.util.Calendar[7], java.sql.Date, java.sql.Time, java.sql.Timestamp,
user-defined serializable types, byte[], Byte[], char[], and Character[]); enums; entity
types; collections of entity types; embeddable classes (see Section 2.5); collections of basic and
embeddable types (see Section 2.6).
Object/relational mapping metadata may be specified to customize the object-relational mapping, and
the loading and storing of the entity state and relationships. See Chapter 9.
2.2.1 Example
@Entity
public class Customer implements Serializable {
// No-arg constructor
public Customer() {}
[7] Note that an instance of Calendar must be fully initialized for the type that it is mapped to.
@OneToMany
public Collection<Order> getOrders() {
return orders;
}
@ManyToMany
public Set<PhoneNumber> getPhones() {
return phones;
}
When annotations are used to define a default access type, the placement of the mapping annotations on
either the persistent fields or persistent properties of the entity class specifies the access type as being
either field- or property-based access respectively.
• When field-based access is used, the object/relational mapping annotations for the entity class
annotate the instance variables, and the persistence provider runtime accesses instance vari-
ables directly. All non-transient instance variables that are not annotated with the Tran-
sient annotation are persistent.
• When property-based access is used, the object/relational mapping annotations for the entity
class annotate the getter property accessors[9], and the persistence provider runtime accesses
[8] The use of XML as an alternative and the interaction between Java language annotations and XML elements in defining default
and explicit access types is described in Chapter 10.
[9] These annotations must not be applied to the setter methods.
persistent state via the property accessor methods. All properties not annotated with the
Transient annotation are persistent.
• Mapping annotations must not be applied to fields or properties that are transient or
Transient.
All such classes in the entity hierarchy whose access type is defaulted in this way must be consistent in
their placement of annotations on either fields or properties, such that a single, consistent default access
type applies within the hierarchy. Any embeddable classes used by such classes will have the same
access type as the default access type of the hierarchy unless the Access annotation is specified as
defined below. The behavior of applications that mix the placement of annotations on fields and proper-
ties within an entity hierarchy without explicitly specifying the Access annotation is undefined.
[10] It is permitted (but redundant) to place Access(FIELD) on a persistent field whose class has field access type or Access(PROP-
ERTY) on a persistent property whose class has property access type. It is not permitted to specify a field as Access(PROPERTY)
or a property as Access(FIELD).
Primary Keys and Entity Identity Java Persistence 2.0, Early Draft Entities
Note that when access types are combined within a class, the Transient annotation should
be used to avoid duplicate persistent mappings.
The access type of an embeddable class is determined by the access type of the entity class, mapped
superclass, or embeddable class in which it is embedded (including as a member of an element collec-
tion) independent of whether the access type of the containing class has been explicitly specified or
defaulted. A different access type for an embeddable class may be specified for that embeddable class
by means of the Access annotation as described above.
The primary key must be defined on the entity class that is the root of the entity hierarchy or on a
mapped superclass that is a (direct or indirect) superclass of all entity classes in the entity hierarchy. The
primary key must be defined exactly once in an entity hierarchy.
A primary key corresponds to one or more fields or properties (“attributes”) of the entity class.
• A simple (i.e., non-composite) primary key must correspond to a single persistent field or
property of the entity class. The Id annotation is used to denote a simple primary key. See Sec-
tion 9.1.17.
• A composite primary key must correspond to either a single persistent field or property or to a
set of such fields or properties as described below. A primary key class must be defined to rep-
resent a composite primary key. Composite primary keys typically arise when mapping from
legacy databases when the database key is comprised of several columns. The EmbeddedId
and IdClass annotations are used to denote composite primary keys. See Sections 9.1.14 and
9.1.18.
A simple primary key or a field or property of a composite primary key should be one of the following
types: any Java primitive type; any primitive wrapper type; java.lang.String;
java.util.Date; java.sql.Date; java.math.BigDecimal; java.math.BigInte-
ger.[11] If the primary key is a composite primary key derived from the primary key of another entity,
the primary key may contain an attribute whose type is that of the primary key of the referenced entity,
as described in Section 2.4.1. Entities whose primary keys use types other than these will not be porta-
ble. If generated primary keys are used, only integral types will be portable. If java.util.Date is
used as a primary key field or property, the temporal type should be specified as DATE.
• The primary key class must be public and must have a public no-arg constructor.
[11] In general, however, approximate numeric types (e.g., floating point types) should never be used in primary keys.
Entities Java Persistence 2.0, Early Draft Primary Keys and Entity Identity
• The access type (field- or property-based access) of a primary key class is determined by the
access type of the entity for which it is the primary key unless the primary key is a embedded
id and a different access type is specified. See Section 2.3, “Access Type”.
• If property-based access is used, the properties of the primary key class must be public or pro-
tected.
• The primary key class must define equals and hashCode methods. The semantics of value
equality for these methods must be consistent with the database equality for the database types
to which the key is mapped.
• A composite primary key must either be represented and mapped as an embeddable class (see
Section 9.1.14, “EmbeddedId Annotation”) or must be represented as an id class and mapped
to multiple fields or properties of the entity class (see Section 9.1.18, “IdClass Annotation”).
• If the composite primary key class is represented as an id class, the names of primary key
fields or properties in the primary key class and those of the entity class to which the id class is
mapped must correspond and their types must be the same.
• A primary key that corresponds to a derived identity must conform to the rules of Section
2.4.1.
The value of its primary key uniquely identifies an entity instance within a persistence context and to
EntityManager operations as described in Chapter 3, “Entity Operations”. The application must not
change the value of the primary key[12]. The behavior is undefined if this occurs.[13]
Derived identities may be captured by means of simple primary keys or by means of composite primary
keys as described in subsection 2.4.1.1below.
[12] This includes not changing the value of a mutable type that is primary key or an attribute of a composite primary key.
[13] The implementation may, but is not required to, throw an exception. Portable applications must not rely on any such specific
behavior.
Primary Keys and Entity Identity Java Persistence 2.0, Early Draft Entities
If the dependent entity class has primary key attributes in addition to those of the parent's primary key
or if the parent has a composite primary key, an embedded id or id class must be used to specify the pri-
mary key of the dependent entity[14]. It is not necessary that parent entity and dependent entity both use
embedded ids or both use id classes to represent composite primary keys when the parent has a compos-
ite key.
• The Id attribute in the entity class and the corresponding attribute in the id class must have the
same name.
• If an Id attribute in the entity class is of basic type, the corresponding attribute in the id class
must have the same type.
If the dependent entity uses an embedded id to represent its primary key, the primary key attribute cor-
responding to the relationship in the dependent entity must be of the same type as the primary key of the
referenced entity and must be designated by the MappedById annotation applied to the relationship
attribute. The value element of the MappedById annotation must be used to specify the name of the
primary key attribute to which the relationship corresponds. If the primary key referenced by the rela-
tionship attribute is of the same Java type as the dependent's primary key, then the value element is
not specified.[15]
If the dependent entity class has a single primary key attribute (i.e, the relationship attribute) and the
primary key of the parent entity is a simple primary key, the primary key of the dependent entity is a
simple primary key of the same type as that of the parent entity (and neither EmbeddedId nor
IdClass is specified). In this case, either (1) the relationship attribute is annotated Id, or (2) a sepa-
rate Id attribute is specified and the relationship attribute is annotated MappedById.
[14] If the dependent has a many-to-one relationship to a parent, the dependent's primary key will be a composite primary key, since it
will contain one or more attributes in addition to an attribute corresponding to the parent's primary key.
[15] Note: the dependent's primary key may be represented as a embedded id and the parent's primary key as an id class, or vice versa.
Entities Java Persistence 2.0, Early Draft Primary Keys and Entity Identity
Example 1:
@Entity
public class Employee {
@Id long empId;
String name;
...
}
@Entity
@IdClass(DependentId.class)
public class Dependent {
@Id String name;
@Id @ManyToOne Employee emp;
...
}
Sample query:
SELECT d
FROM Dependent d
WHERE d.name = 'Joe' AND d.emp.name = 'Sam'
@Embeddable
public class DependentId {
String name;
long empPK; // corresponds to PK type of Employee
}
@Entity
public class Dependent {
@EmbeddedId DependentId id;
...
@MappedById("empPK") // maps to empPK attribute of embedded id
@ManyToOne Employee emp;
}
Sample query:
SELECT d
FROM Dependent d
WHERE d.id.name = 'Joe' AND d.emp.name = 'Sam'
Primary Keys and Entity Identity Java Persistence 2.0, Early Draft Entities
Example 2:
@Entity
@IdClass(EmployeeId.class)
public class Employee {
@Id String firstName
@Id String lastName
...
}
@Entity
@IdClass(DependentId.class)
public class Dependent {
@Id String name;
@Id @ManyToOne Employee emp;
}
Sample query:
SELECT d
FROM Dependent d
WHERE d.name = 'Joe' AND d.emp.firstName = 'Sam'
The dependent entity uses EmbeddedId. The type of the empPK attribute is the same as that of the pri-
mary key of Employee.
@Embeddable
public class DependentId {
String name;
EmployeeId empPK;
}
@Entity
public class Dependent {
@EmbeddedId DependentId id;
...
@MappedById("empPK")
@ManyToOne Employee emp;
}
Entities Java Persistence 2.0, Early Draft Primary Keys and Entity Identity
Sample query:
SELECT d
FROM Dependent d
WHERE d.id.name = 'Joe' AND d.emp.firstName = 'Sam'
Note that the following alternative query will yield the same result:
SELECT d
FROM Dependent d
WHERE d.id.name = 'Joe' AND d.id.empPK.firstName = 'Sam'
Example 3:
@Embeddable
public class EmployeeId {
String firstName;
String lastName;
...
}
@Entity
public class Employee {
@EmbeddedId EmployeeId empId;
...
}
@Entity
@IdClass(DependentId.class)
public class Dependent {
@Id String name;
@Id @ManyToOne Employee emp;
}
Sample query:
SELECT d
FROM Dependent d
WHERE d.name = 'Joe' and d.emp.empId.firstName = 'Sam'
Primary Keys and Entity Identity Java Persistence 2.0, Early Draft Entities
@Embeddable
public class DependentId {
String name;
EmployeeId empPK; // corresponds to PK type of Employee
}
@Entity
public class Dependent {
@EmbeddedId DependentId id;
...
@MappedById("empPK")
@ManyToOne Employee emp;
}
Sample query:
SELECT d
FROM Dependent d
WHERE d.id.name = 'Joe' and d.emp.empId.firstName = 'Sam'
Note that the following alternative query will yield the same result:
SELECT d
FROM Dependent d
WHERE d.id.name = 'Joe' AND d.id.empPK.firstName = 'Sam'
Example 4:
@Entity
public class Person {
@Id String ssn;
...
}
The dependent entity has a single relationship attribute corresponding to the parent’s primary key. The
primary key of MedicalHistory is of type String.
@Entity
public class MedicalHistory {
@Id @OneToOne Person patient;
...
}
Sample query:
select m
from MedicalHistory m
where m.patient.ssn = '123-45-6789'
Entities Java Persistence 2.0, Early Draft Primary Keys and Entity Identity
The primary key consists of a single attribute corresponding to the simple primary key of the parent
entity. The dependent entity has a primary key attribute in addition to the relationship attribute corre-
sponding to the primary key. This attribute is mapped to the primary key by the MappedById annota-
tion applied to the relationship. [16]
@Entity
public class MedicalHistory {
@Id String id;
...
@MappedById
@OneToOne Person patient;
...
}
Sample query:
SELECT m
FROM MedicalHistory m
WHERE m.patient.ssn = '123-45-6789'
Example 5:
The parent entity uses IdClass. The dependent's primary key class is of same type as that of the par-
ent entity.
@Entity
@IdClass(PersonId.class)
public class Person {
@Id String firstName;
@Id String lastName;
...
}
@Entity
@IdClass(PersonId.class)
public class MedicalHistory {
@Id @OneToOne Person patient;
...
}
[16] Note that the use of PrimaryKeyJoinColumn instead of MappedById would result in the same mapping in this example. Use of
MappedById is preferred for the mapping of derived identities.
Primary Keys and Entity Identity Java Persistence 2.0, Early Draft Entities
Sample query:
SELECT m
FROM MedicalHistory m
WHERE m.patient.firstName = 'Charles'
The dependent entity uses the EmbeddedId and MappedById annotations. The PersonId class
either needs to be annotated Embeddable or denoted as an embeddable class in the XML descriptor.
@Entity
public class MedicalHistory {
@EmbeddedId PersonId id;
...
@MappedById
@OneToOne Person patient;
...
}
Sample query:
SELECT m
FROM MedicalHistory m
WHERE m.patient.firstName = 'Charles'
Note that the following alternative query will yield the same result:
SELECT m
FROM MedicalHistory m
WHERE m.id.firstName = 'Charles'
Example 6:
The parent entity uses EmbeddedId. The dependent's primary key is of the same type as that of the
parent.
@Embeddable
public class PersonId {
String firstName;
String lastName;
}
@Entity
public class Person {
@EmbeddedId PersonId id;
...
}
@Entity
@IdClass(PersonId.class)
public class MedicalHistory {
@Id @OneToOne Person patient;
...
}
@Entity
public class MedicalHistory {
@EmbeddedId PersonId id;
...
@MappedById
@OneToOne Person patient;
...
}
An entity may use other fine-grained classes to represent entity state. Instances of these classes, unlike
entity instances, do not have persistent identity of their own. Instead, they exist only as part of the state
of the entity to which they belong. An entity may have collections of embeddables as well as single-val-
ued embeddable attributes. Embeddables may also be used as map keys and map values. Embedded
objects belong strictly to their owning entity, and are not sharable across persistent entities. Attempting
to share an embedded object across entities has undefined semantics.
Embeddable classes must adhere to the requirements specified in Section 2.1 for entities with the excep-
tion that embeddable classes are not annotated as Entity. Embeddable classes must be annotated as
Embeddable or denoted in the XML descriptor as such. The access type for an embedded object is
determined by the access type of the entity in which it is embedded unless otherwise specified. See Sec-
tion 2.3, “Access Type”.
Open Issue: Should this be “determined by the access type of the entity or embeddable in
which it is embedded”?
An embeddable class may be used to represent the state of another embeddable class. An embeddable
class (including an embeddable class within another embeddable class) may contain a collection of a
basic type or other embeddable class.[17]
[17] Direct or indirect circular containment dependencies among embeddable classes are not permitted.
Collections of Embeddable Classes and Basic TypesJava Persistence 2.0, Early Draft Entities
An embeddable class may contain a relationship to an entity or collection of entities. Since instances of
embeddable classes themselves have no persistent identity, the relationship from the referenced entity is
to the entity which contains the embeddable instance(s) and not to the embeddable itself.[18] An
embeddable class that is used as an embedded id or as a map key must not contain such a relationship.
Additional requirements and restrictions on embeddable classes are described in Sections 2.6 and
9.1.12.
A persistent field or property of an entity may correspond to a collection of a basic type or embeddable
class (“element collection”). Such a collection, when specified as such by the ElementCollection
annotation, is mapped by means of a collection table, as defined in Section 9.1.7. If the ElementCol-
lection annotation (or XML equivalent) is not specified for the collection-valued field or property,
the rules of Section 2.8 apply.
An embeddable class (including an embeddable class within another embeddable class) contained
within an element collection must not contain an element collection, nor may it contain a relationship to
an entity other than a many-to-one or one-to-one relationship. The embeddable class must be on the
owning side of the relationship and the relationship must be mapped by a foreign key mapping. (See
Section 2.9.)
The map key and the map value independently can each be a basic type, an embeddable class, or an
entity.
The ElementCollection, OneToMany, and ManyToMany annotations are used to specify the
map as an element collection or entity relationship as appropriate.
Bidirectional relationships represented as java.util.Map collections support the use of the Map
datatype on one side of the relationship only.
[18] An entity cannot have a unidirectional relationship to the embeddable class of another entity (or itself).
Entities Java Persistence 2.0, Early Draft Mapping Defaults for Non-Relationship Fields or
If the map key type is an embeddable class, the mappings for the map key columns are defaulted
according to the default column mappings for the embeddable class. (See Section 9.1.8, “Column
Annotation”). The AttributeOverride and AttributeOverrides annotations can be used to
override these mappings, as described in section 9.1.4. If an embeddable class is used as a map key, the
embeddable class should implement the hashCode and equals methods.
If the map key type is an entity, the MapKeyJoinColumn and MapKeyJoinColumns annotations
are used to specify the column mappings for the map key. If the primary key of the referenced entity is
a simple primary key and the MapKeyJoinColumn annotation is not specified, the default values of
the MapKeyJoinColumn annotation apply as described in section 9.1.29.
The MapKey annotation is used to specify the special case where the map key is itself the primary key
or a persistent field or property of the entity that is the value of the map. Otherwise, if Java generic types
are not used in the declaration of a relationship attribute of type java.util.Map, the MapKey-
Class annotation must be used to specify the type of the key of the map.
The default column mappings for the map value are derived according to the default mapping rules for
the CollectionTable annotation defined in Section 9.1.7.
The Column annotation is used to override these defaults for a map value of basic type. The
AttributeOverride(s) and AssociationOverride(s) annotations are used to override the
mappings for a map value that is an embeddable class.
When the value type of the map is an entity, a join table is used to map the map for a many-to-many
relationship or, by default, for a one-to-many unidirectional relationship. If the relationship is a bidirec-
tional one-to-many/many-to-one relationship, by default the map is mapped in the table of the entity
that is the value of the map. If Java generic types are not used, the targetEntity element of the
OneToMany or ManyToMany annotation must be used to specify the value type for the map.
If a persistent field or property other than a relationship property is not annotated with one of the map-
ping annotations defined in Chapter 9 (or equivalent mapping information is not specified in the XML
descriptor), the following default mapping rules are applied in order:
• If the type is a class that is annotated with the Embeddable annotation, it is mapped in the
same way as if the field or property were annotated with the Embedded annotation. See Sec-
tions 9.1.12 and 9.1.13.
• If the type of the field or property is one of the following, it is mapped in the same way as it
would if it were annotated as Basic: Java primitive types, wrappers of the primitive types,
java.lang.String, java.math.BigInteger, java.math.BigDecimal,
java.util.Date, java.util.Calendar, java.sql.Date, java.sql.Time,
java.sql.Timestamp, byte[], Byte[], char[], Character[], enums, any other
type that implements Serializable. See Sections 9.1.6, 9.1.15, 9.1.23, and 9.1.44.
If there is an association between two entities, one of the following relationship modeling annotations
must be applied to the corresponding persistent property or instance variable of the referencing entity:
OneToOne, OneToMany, ManyToOne, ManyToMany. For associations that do not specify the tar-
get type (e.g., where Java generic types are not used for collections), it is necessary to specify the entity
that is the target of the relationship.
These annotations mirror common practice in relational database schema modeling. The use of the
relationship modeling annotations allows the object/relationship mapping of associations to the rela-
tional database schema to be fully defaulted, to provide an ease-of-development facility. This is
described in Section 2.10, “Relationship Mapping Defaults”.
• The inverse side of a bidirectional relationship must refer to its owning side by use of the
mappedBy element of the OneToOne, OneToMany, or ManyToMany annotation. The
mappedBy element designates the property or field in the entity that is the owner of the rela-
tionship.
• The many side of one-to-many / many-to-one bidirectional relationships must be the owning
side, hence the mappedBy element cannot be specified on the ManyToOne annotation.
• For one-to-one bidirectional relationships, the owning side corresponds to the side that con-
tains the corresponding foreign key.
• For many-to-many bidirectional relationships either side may be the owning side.
The relationship modeling annotation constrains the use of the cascade=REMOVE specification. The
cascade=REMOVE specification should only be applied to associations that are specified as One-
ToOne or OneToMany. Applications that apply cascade=REMOVE to other associations are not por-
table.
Associations that are specified as OneToOne or OneToMany support use of the orphanRemoval
option. The following behaviors apply when orphanRemoval is in effect:
• If an entity that is the target of the relationship is removed from the relationship (by setting the
relationship to null or removing the entity from the relationship collection), the remove opera-
tion will be applied to the entity being orphaned. If the entity being orphaned is a detached,
new, or removed entity, the semantics of orphanRemoval do not apply.
• If the remove operation is applied to the source entity, the remove operation will be cascaded
to the relationship target in accordance with the rules of section 3.2.3, (and hence it is not nec-
essary to specify cascade=REMOVE for the relationship)[19].
• The remove operation is applied at the time of the flush operation. The orphanRemoval
functionality is intended for entities that are privately "owned" by their parent entity. Portable
applications must otherwise not depend upon a specific order of removal, and must not reas-
sign an entity that has been orphaned to another relationship or otherwise attempt to persist it
Section 2.10, “Relationship Mapping Defaults”, defines relationship mapping defaults for entity rela-
tionships. Additional mapping annotations (e.g., column and table mapping annotations) may be speci-
fied to override or further refine the default mappings and mapping strategies described in Section 2.10.
This specification also requires support for the following alternative mapping strategies: the
mapping of unidirectional one-to-many relationships by means of foreign key mappings; the
mapping of unidirectional and bidirectional one-to-one relationships and bidirectional
many-to-one/one-to-many relationships by means of join table mappings. The JoinColumn
and JoinTable annotations or corresponding XML elements must be used to specify such
non-default mappings. See sections 9.1.20 and 9.1.22.
Schema-level mapping annotations must be specified on the owning side of the relationship. Any over-
riding of mapping defaults must be consistent with the relationship modeling annotation that is speci-
fied. For example, if a many-to-one relationship mapping is specified, it is not permitted to specify a
unique key constraint on the foreign key for the relationship.
The persistence provider handles the object-relational mapping of the relationships, including their
loading and storing to the database as specified in the metadata of the entity class, and the referential
integrity of the relationships as specified in the database (e.g., by foreign key constraints).
Note that it is the application that bears responsibility for maintaining the consistency of runt-
ime relationships—for example, for insuring that the “one” and the “many” sides of a bidirec-
tional relationship are consistent with one another when the application updates the
relationship at runtime.
[19] If the parent is detached or new or was previously removed before the orphan was associated with it, the remove operation is not
applied to the entity being orphaned.
If there are no associated entities for a multi-valued relationship of an entity fetched from the database,
the persistence provider is responsible for returning an empty collection as the value of the relationship.
This section defines the mapping defaults that apply to the use of the OneToOne, OneToMany,
ManyToOne, and ManyToMany relationship modeling annotations. The same mapping defaults apply
when the XML descriptor is used to denote the relationship cardinalities.
Example:
@Entity
public class Employee {
private Cubicle assignedCubicle;
@OneToOne
public Cubicle getAssignedCubicle() {
return assignedCubicle;
}
public void setAssignedCubicle(Cubicle cubicle) {
this.assignedCubicle = cubicle;
}
...
}
@Entity
public class Cubicle {
private Employee residentEmployee;
@OneToOne(mappedBy="assignedCubicle")
public Employee getResidentEmployee() {
return residentEmployee;
}
public void setResidentEmployee(Employee employee) {
this.residentEmployee = employee;
}
...
}
In this example:
Example:
@Entity
public class Employee {
private Department department;
@ManyToOne
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
...
}
@Entity
public class Department {
private Collection<Employee> employees = new HashSet();
@OneToMany(mappedBy="department")
public Collection<Employee> getEmployees() {
return employees;
}
In this example:
A unidirectional relationship has only an owning side, which in this case must be Entity A.
The unidirectional single-valued relationship modeling case can be specified as either a unidirectional
OneToOne or as a unidirectional ManyToOne relationship.
Example:
@Entity
public class Employee {
private TravelProfile profile;
@OneToOne
public TravelProfile getProfile() {
return profile;
}
public void setProfile(TravelProfile profile) {
this.profile = profile;
}
...
}
@Entity
public class TravelProfile {
...
}
In this example:
Example:
@Entity
public class Employee {
private Address address;
@ManyToOne
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
...
}
@Entity
public class Address {
...
}
In this example:
Example:
@Entity
public class Project {
private Collection<Employee> employees;
@ManyToMany
public Collection<Employee> getEmployees() {
return employees;
}
@Entity
public class Employee {
private Collection<Project> projects;
@ManyToMany(mappedBy="employees")
public Collection<Project> getProjects() {
return projects;
}
In this example:
A unidirectional relationship has only an owning side, which in this case must be Entity A.
The unidirectional multi-valued relationship modeling case can be specified as either a unidirectional
OneToMany or as a unidirectional ManyToMany relationship.
Example:
@Entity
public class Employee {
private Collection<AnnualReview> annualReviews;
@OneToMany
public Collection<AnnualReview> getAnnualReviews() {
return annualReviews;
}
@Entity
public class AnnualReview {
...
}
In this example:
and has the same type as the primary key of EMPLOYEE. This foreign key column is named
EMPLOYEE_<PK of EMPLOYEE>, where <PK of EMPLOYEE> denotes the name of the
primary key column of table EMPLOYEE. The other foreign key column refers to table ANNU-
ALREVIEW and has the same type as the primary key of ANNUALREVIEW. This foreign key
column is named ANNUALREVIEWS_<PK of ANNUALREVIEW>, where <PK of ANNU-
ALREVIEW> denotes the name of the primary key column of table ANNUALREVIEW. There
is a unique key constraint on the foreign key that refers to table ANNUALREVIEW.
Example:
@Entity
public class Employee {
private Collection<Patent> patents;
@ManyToMany
public Collection<Patent> getPatents() {
return patents;
}
@Entity
public class Patent {
...
}
In this example:
2.11 Inheritance
An entity may inherit from another entity class. Entities support inheritance, polymorphic associations,
and polymorphic queries.
Both abstract and concrete classes can be entities. Both abstract and concrete classes can be annotated
with the Entity annotation, mapped as entities, and queried for as entities.
Entities can extend non-entity classes and non-entity classes can extend entity classes.
An abstract entity class is annotated with the Entity annotation or denoted in the XML descriptor as
an entity.
The following example shows the use of an abstract entity class in the entity inheritance hierarchy.
@Entity
@Table(name="EMP")
@Inheritance(strategy=JOINED)
public abstract class Employee {
@Id protected Integer empId;
@Version protected Integer version;
@ManyToOne protected Address address;
...
}
@Entity
@Table(name="FT_EMP")
@DiscriminatorValue("FT")
@PrimaryKeyJoinColumn(name="FT_EMPID")
public class FullTimeEmployee extends Employee {
// Defaults to FT_EMP.SALARY
protected Integer salary;
...
}
@Entity
@Table(name="PT_EMP")
@DiscriminatorValue("PT")
// PK field is PT_EMP.EMPID due to PrimaryKeyJoinColumn default
public class PartTimeEmployee extends Employee {
protected Float hourlyWage;
...
}
A mapped superclass, unlike an entity, is not queryable and cannot be passed as an argument to Enti-
tyManager or Query operations. A mapped superclass cannot be the target of a persistent relation-
ship.
Both abstract and concrete classes may be specified as mapped superclasses. The MappedSuper-
class annotation (or mapped-superclass XML descriptor element) is used to designate a
mapped superclass.
A class designated as a mapped superclass has no separate table defined for it. Its mapping information
is applied to the entities that inherit from it.
A class designated as a mapped superclass can be mapped in the same way as an entity except that the
mappings will apply only to its subclasses since no table exists for the mapped superclass itself. When
applied to the subclasses, the inherited mappings will apply in the context of the subclass tables. Map-
ping information can be overridden in such subclasses by using the AttributeOverride and
AssociationOverride annotations or corresponding XML elements.
All other entity mapping defaults apply equally to a class designated as a mapped superclass.
The following example illustrates the definition of a concrete class as a mapped superclass.
@MappedSuperclass
public class Employee {
// Defaults to FTEMPLOYEE.SALARY
protected Integer salary;
public FTEmployee() {}
@Entity @Table(name="PT_EMP")
@AssociationOverride(name="address",
joincolumns=@JoinColumn(name="ADDR_ID"))
public class PartTimeEmployee extends Employee {
// Inherited empId field mapped to PT_EMP.EMPID
// Inherited version field mapped to PT_EMP.VERSION
// address field mapping overridden to PT_EMP.ADDR_ID fk
@Column(name="WAGE")
protected Float hourlyWage;
public PartTimeEmployee() {}
The non-entity superclass serves for inheritance of behavior only. The state of a non-entity superclass is
not persistent. Any state inherited from non-entity superclasses is non-persistent in an inheriting entity
class. This non-persistent state is not managed by the EntityManager[21]. Any annotations on such
superclasses are ignored.
The following example illustrates the use of a non-entity class as a superclass of an entity.
@Entity
public class ShoppingCart extends Cart {
Collection<Item> items = new Vector<Item>();
public ShoppingCart() { super(); }
...
@OneToMany
public Collection<Item> getItems() { return items; }
public void addItem(Item item) {
items.add(item);
incrementOperationCount();
}
}
There are three basic strategies that are used when mapping a class or class hierarchy to a relational
database:
• a strategy in which fields that are specific to a subclass are mapped to a separate table than the
fields that are common to the parent class, and a join is performed to instantiate the subclass.
An implementation is required to support the single table per class hierarchy inheritance mapping strat-
egy and the joined subclass strategy.
Support for the table per concrete class inheritance mapping strategy is optional in this
release.
[Note to reviewers] We would welcome feedback as to the whether support for this mapping strategy should be
required.
Support for the combination of inheritance strategies within a single entity inheritance hierar-
chy is not required by this specification.
This mapping strategy provides good support for polymorphic relationships between entities and for
queries that range over the class hierarchy.
It has the drawback, however, that it requires that the columns that correspond to state specific to the
subclasses be nullable.
• It typically requires that SQL UNION queries (or a separate SQL query per subclass) be issued
for queries that are intended to range over the class hierarchy.
It has the drawback that it requires that one or more join operations be performed to instantiate instances
of a subclass. In deep class hierarchies, this may lead to unacceptable performance. Queries that range
over the class hierarchy likewise require joins.
C ha p t e r 3 Entity Operations
This chapter describes the use of the EntityManager API to manage the entity instance lifecycle and
the use of the Query API to retrieve and query entities and their persistent state.
3.1 EntityManager
The set of entities that can be managed by a given EntityManager instance is defined by a persistence
unit. A persistence unit defines the set of all classes that are related or grouped by the application, and
which must be colocated in their mapping to a single database.
Section 3.1 defines the EntityManager interface. The entity instance lifecycle is described in Sec-
tion 3.2. The relationships between entity managers and persistence contexts are described in section
3.3 and in further detail in Chapter 5. Section 3.5 describes entity listeners and lifecycle callback meth-
ods for entities. The Query interface is described in section 3.6. The definition of persistence units is
described in chapter 6.
package javax.persistence;
/**
* Interface used to interact with the persistence context.
*/
/**
* Make an instance managed and persistent.
* @param entity
* @throws EntityExistsException if the entity already exists.
* (The EntityExistsException may be thrown when the persist
* operation is invoked, or the EntityExistsException or
* another PersistenceException may be thrown at flush or
* commit time.)
* @throws IllegalArgumentException if the instance is not an
* entity
* @throws TransactionRequiredException if invoked on a
* container-managed entity manager of type
* PersistenceContextType.TRANSACTION and there is
* no transaction.
*/
public void persist(Object entity);
/**
* Merge the state of the given entity into the
* current persistence context.
* @param entity
* @return the managed instance that the state was merged to
* @throws IllegalArgumentException if instance is not an
* entity or is a removed entity
* @throws TransactionRequiredException if invoked on a
* container-managed entity manager of type
* PersistenceContextType.TRANSACTION and there is
* no transaction.
*/
public <T> T merge(T entity);
/**
* Remove the entity instance.
* @param entity
* @throws IllegalArgumentException if the instance is not an
* entity or is a detached entity
* @throws TransactionRequiredException if invoked on a
* container-managed entity manager of type
* PersistenceContextType.TRANSACTION and there is
* no transaction.
*/
public void remove(Object entity);
/**
* Find by primary key.
* @param entityClass
* @param primaryKey
* @return the found entity instance or null
* if the entity does not exist
/**
* Find by primary key and lock.
* Search for an entity of the specified class and primary key
* and lock it with respect to the specified lock type.
* If the entity instance is contained in the persistence context
* it is returned from there[23]. If the entity is found
* within the persistence context and the lock mode type
* is pessimistic and the entity has a version attribute, the
* persistence provider must perform optimistic version checks
* when obtaining the database lock. If these checks fail,
* the OptimisticLockException will be thrown.
* If the lock mode type is pessimistic and the entity instance
* is found but cannot be locked:
* - the PessimisticLockException will be thrown if the database
* locking failure causes transaction-level rollback.
* - the LockTimeoutException will be thrown if the database
* locking failure causes only statement-level rollback
* @param entityClass
* @param primaryKey
* @param lockMode
* @return the found entity instance or null if the entity does
* not exist
* @throws IllegalArgumentException if the first argument does
* not denote an entity type or the second argument is
* not a valid type for that entity's primary key or
* is null
* @throws TransactionRequiredException if there is no
* transaction and a lock mode other than NONE is set
* @throws OptimisticLockException if the optimistic version
* check fails
* @throws PessimisticLockException if pessimistic locking
* fails and the transaction is rolled back
* @throws LockTimeoutException if pessimistic locking fails and
* only the statement is rolled back
* @throws PersistenceException if an unsupported lock call
* is made
*/
public <T> T find(Class<T> entityClass, Object primaryKey,
LockModeType lockMode)
/**
* Find by primary key and lock.
* Search for an entity of the specified class and primary key
* and lock it with respect to the specified lock type.
* If the entity instance is contained in the persistence context
* it is returned from there. If the entity is found
* within the persistence context and the lock mode type
* is pessimistic and the entity has a version attribute, the
[23] If the entity is already in the persistence context, the effect of this method is the same as if the lock method had been called on the
entity.
/**
* Get an instance, whose state may be lazily fetched.
* If the requested instance does not exist in the database,
* the EntityNotFoundException is thrown when the instance
* state is first accessed. (The persistence provider runtime is
* permitted to throw the EntityNotFoundException when
* getReference is called.)
* The application should not expect that the instance state will
* be available upon detachment, unless it was accessed by the
* application while the entity manager was open.
* @param entityClass
* @param primaryKey
* @return the found entity instance
* @throws IllegalArgumentException if the first argument does
* not denote an entity type or the second argument is
* not a valid type for that entity’s primary key or
* is null
* @throws EntityNotFoundException if the entity state
* cannot be accessed
*/
public <T> T getReference(Class<T> entityClass,
Object primaryKey);
/**
* Synchronize the persistence context to the
* underlying database.
* @throws TransactionRequiredException if there is
* no transaction
* @throws PersistenceException if the flush fails
*/
public void flush();
/**
* Set the flush mode that applies to all objects contained
* in the persistence context.
* @param flushMode
*/
public void setFlushMode(FlushModeType flushMode);
/**
* Get the flush mode that applies to all objects contained
* in the persistence context.
* @return flushMode
*/
public FlushModeType getFlushMode();
/**
* Lock an entity instance that is contained in the persistence
* context with the specified lock mode type.
* If a pessimistic lock mode type is specified and the entity
* contains a version attribute, the persistence provider must
* also perform optimistic version checks when obtaining the
* database lock. If these checks fail, the
* OptimisticLockException will be thrown.
* If the lock mode type is pessimistic and the entity instance
* is found but cannot be locked:
* - the PessimisticLockException will be thrown if the database
* locking failure causes transaction-level rollback.
* - the LockTimeoutException will be thrown if the database
* locking failure causes only statement-level rollback
* @param entity
* @param lockMode
* @throws IllegalArgumentException if the instance is not an
* entity or is a detached entity
* @throws TransactionRequiredException if there is no
* transaction
* @throws EntityNotFoundException if the entity does not exist
* in the database when pessimistic locking is
* performed
* @throws OptimisticLockException if the optimistic version
* check fails
* @throws PessimisticLockException if pessimistic locking fails
* and the transaction is rolled back
* @throws LockTimeoutException if pessimistic locking fails and
* only the statement is rolled back
* @throws PersistenceException if an unsupported lock call
* is made
*/
/**
* Refresh the state of the instance from the database,
* overwriting changes made to the entity, if any, and
* lock it with respect to given lock mode type.
* If the lock mode type is pessimistic and the entity instance
* is found but cannot be locked:
* - the PessimisticLockException will be thrown if the database
* locking failure causes transaction-level rollback.
* - the LockTimeoutException will be thrown if the
* database locking failure causes only statement-level
* rollback.
* @param entity
* @param lockMode
* @throws IllegalArgumentException if the instance is not
* an entity or the entity is not managed
* @throws TransactionRequiredException if there is no
* transaction
* @throws EntityNotFoundException if the entity no longer exists
* in the database
* @throws PessimisticLockException if pessimistic locking fails
* and the transaction is rolled back
* @throws LockTimeoutException if pessimistic locking fails and
* only the statement is rolled back
* @throws PersistenceException if an unsupported lock call
* is made
*/
public void refresh(Object entity, LockModeType lockMode)
/**
* Refresh the state of the instance from the database,
* overwriting changes made to the entity, if any, and
* lock it with respect to given lock mode type.
* If the lock mode type is pessimistic and the entity instance
* is found but cannot be locked:
* - the PessimisticLockException will be thrown if the database
* locking failure causes transaction-level rollback.
* - the LockTimeoutException will be thrown if the database
* locking failure causes only statement-level rollback
* If a vendor-specific property or hint is not recognized,
* it is silently ignored.
* Portable applications should not rely on the standard timeout
* hint. Depending on the database in use and the locking
* mechanisms used by the provider, the hint may or may not
* be observed.
* @param entity
* @param lockMode
* @param properties standard and vendor-specific properties
* and hints
* @throws IllegalArgumentException if the instance is not
* an entity or the entity is not managed
* @throws TransactionRequiredException if there is no
* transaction
* @throws EntityNotFoundException if the entity no longer exists
* in the database
* @throws PessimisticLockException if pessimistic locking fails
* and the transaction is rolled back
* @throws LockTimeoutException if pessimistic locking fails and
* only the statement is rolled back
* @throws PersistenceException if an unsupported lock call
* is made
*/
public void refresh(Object entity, LockModeType lockMode,
Map properties)
/**
* Clear the persistence context, causing all managed
* entities to become detached. Changes made to entities that
* have not been flushed to the database will not be
* persisted.
*/
public void clear();
/**
* Remove the given entity from the persistence context, causing
* a managed entity to become detached. Unflushed changes made
* to the entity if any (including removal of the entity),
* will not be synchronized to the database.
* @param entity
* @throws IllegalArgumentException if the instance is not an
* entity
*/
public void clear(Object entity);
Open Issue: Alternative names for this method and the corresponding cascade option.
/**
* Check if the instance is a managed entity instance belonging
* to the current persistence context.
* @param entity
* @return
* @throws IllegalArgumentException if not an entity
*/
public boolean contains(Object entity);
/**
* Get the current lock mode for the entity instance.
* @param entity
* @return lock mode
* @throws TransactionRequiredException if there is no
* transaction
* @throws IllegalArgumentException if the instance is not a
* managed entity and a transaction is active
*/
public LockModeType getLockMode(Object entity);
/**
* Get the properties and associated values that are in effect
* for the entity manager. Changing the contents of the map does
* not change the configuration in effect.
*/
public Map getProperties();
/**
* Get the names of the properties that are supported for use
* with the entity manager.
* These correspond to properties and hints that may be passed
* to the methods of the EntityManager interface that take a
* properties argument or used with the PersistenceContext
* annotation. These properties include all standard entity
* manager hints and properties as well as vendor-specific ones
* supported by the provider. These properties may or may not
* currently be in effect.
* @return property names
*/
public Set<String> getSupportedProperties();
/**
* Create an instance of Query for executing a
* Java Persistence query language statement.
* @param qlString a Java Persistence query string
* @return the new query instance
* @throws IllegalArgumentException if query string is not valid
*/
public Query createQuery(String qlString);
/**
* Create an instance of Query for executing a
* named query (in the Java Persistence query language
* or in native SQL).
* @param name the name of a query defined in metadata
* @return the new query instance
* @throws IllegalArgumentException if a query has not been
* defined with the given name
*/
public Query createNamedQuery(String name);
/**
* Create an instance of Query for executing
* a native SQL statement, e.g., for update or delete.
* @param sqlString a native SQL query string
* @return the new query instance
*/
public Query createNativeQuery(String sqlString);
/**
* Create an instance of Query for executing
* a native SQL query.
* @param sqlString a native SQL query string
* @param resultClass the class of the resulting instance(s)
* @return the new query instance
*/
public Query createNativeQuery(String sqlString,
Class resultClass);
/**
* Create an instance of Query for executing
* a native SQL query.
* @param sqlString a native SQL query string
* @param resultSetMapping the name of the result set mapping
* @return the new query instance
*/
public Query createNativeQuery(String sqlString,
String resultSetMapping);
/**
* Indicate to the EntityManager that a JTA transaction is
* active. This method should be called on a JTA application
* managed EntityManager that was created outside the scope
* of the active transaction to associate it with the current
* JTA transaction.
* @throws TransactionRequiredException if there is
* no transaction.
*/
public void joinTransaction();
/**
* Return the underlying provider object for the EntityManager,
* if available. The result of this method is implementation
* specific.
* /
public Object getDelegate();
/**
* Close an application-managed EntityManager.
* After the close method has been invoked, all methods
* on the EntityManager instance and any Query objects obtained
* from it will throw the IllegalStateException except
* for getTransaction and isOpen (which will return false).
* If this method is called when the EntityManager is
* associated with an active transaction, the persistence
* context remains managed until the transaction completes.
* @throws IllegalStateException if the EntityManager
* is container-managed.
*/
public void close();
/**
* Determine whether the EntityManager is open.
* @return true until the EntityManager has been closed.
*/
public boolean isOpen();
/**
* Return the resource-level transaction object.
* The EntityTransaction instance may be used serially to
* begin and commit multiple transactions.
* @return EntityTransaction instance
* @throws IllegalStateException if invoked on a JTA
* EntityManager.
*/
public EntityTransaction getTransaction();
/**
* Return the entity manager factory for the entity manager.
* @return EntityManagerFactory instance
* @throws IllegalStateException if the entity manager has
* been closed.
*/
public EntityManagerFactory getEntityManagerFactory();
}
The persist, merge, remove, and refresh methods must be invoked within a transaction con-
text when an entity manager with a transaction-scoped persistence context is used. If there is no transac-
tion context, the javax.persistence.TransactionRequiredException is thrown.
The find method (if invoked without a lock or with LockModeType.NONE) and the getRefer-
ence method are not required to be invoked within a transaction context. If an entity manager with
transaction-scoped persistence context is in use, the resulting entities will be detached; if an entity man-
ager with an extended persistence context is used, they will be managed. See section 3.3 for entity man-
ager use outside a transaction.
Methods that otherwise specify lock modes must be invoked within a transaction context. If there is no
transaction context, the javax.persistence.TransactionRequiredException is thrown.
The Query and EntityTransaction objects obtained from an entity manager are valid while that
entity manager is open.
If the argument to the createQuery method is not a valid Java Persistence query string, the Ille-
galArgumentException may be thrown or the query execution will fail. If a native query is not a
valid query for the database in use or if the result set specification is incompatible with the result of the
query, the query execution will fail and a PersistenceException will be thrown when the query
is executed. The PersistenceException should wrap the underlying database exception when
possible.
Runtime exceptions thrown by the methods of the EntityManager interface other than the Lock-
TimeoutException will cause the current transaction to be marked for rollback.
The methods close, isOpen, joinTransaction, and getTransaction are used to manage
application-managed entity managers and their lifecycle. See Section 5.2.2, “Obtaining an Applica-
tion-managed Entity Manager”.
Entity Instance’s Life Cycle Java Persistence 2.0, Early Draft Entity Operations
This section describes the EntityManager operations for managing an entity instance’s lifecycle. An
entity instance may be characterized as being new, managed, detached, or removed.
• A new entity instance has no persistent identity, and is not yet associated with a persistence
context.
• A managed entity instance is an instance with a persistent identity that is currently associated
with a persistence context.
• A detached entity instance is an instance with a persistent identity that is not (or no longer)
associated with a persistence context.
• A removed entity instance is an instance with a persistent identity, associated with a persis-
tence context, that will be removed from the database upon transaction commit.
The following subsections describe the effect of lifecycle operations upon entities. Use of the cascade
annotation element may be used to propagate the effect of an operation to associated entities. The cas-
cade functionality is most typically used in parent-child relationships.
A new entity instance becomes both managed and persistent by invoking the persist method on it or
by cascading the persist operation.
Entity Operations Java Persistence 2.0, Early Draft Entity Instance’s Life Cycle
• If X is a new entity, it becomes managed. The entity X will be entered into the database at or
before transaction commit or as a result of the flush operation.
• If X is a preexisting managed entity, it is ignored by the persist operation. However, the persist
operation is cascaded to entities referenced by X, if the relationships from X to these other
entities are annotated with the cascade=PERSIST or cascade=ALL annotation element
value or specified with the equivalent XML descriptor element.
• For all entities Y referenced by a relationship from X, if the relationship to Y has been anno-
tated with the cascade element value cascade=PERSIST or cascade=ALL, the persist
operation is applied to Y.
3.2.3 Removal
A managed entity instance becomes removed by invoking the remove method on it or by cascading the
remove operation.
• If X is a new entity, it is ignored by the remove operation. However, the remove operation is
cascaded to entities referenced by X, if the relationship from X to these other entities is anno-
tated with the cascade=REMOVE or cascade=ALL annotation element value.
• If X is a managed entity, the remove operation causes it to become removed. The remove oper-
ation is cascaded to entities referenced by X, if the relationships from X to these other entities
is annotated with the cascade=REMOVE or cascade=ALL annotation element value.
• A removed entity X will be removed from the database at or before transaction commit or as a
result of the flush operation.
After an entity has been removed, its state (except for generated state) will be that of the entity at the
point at which the remove operation was called.
Entity Instance’s Life Cycle Java Persistence 2.0, Early Draft Entity Operations
The state of persistent entities is synchronized to the database at transaction commit. This synchroniza-
tion involving writing to the database any updates to persistent entities and their relationships as speci-
fied above.
An update to the state of an entity includes both the assignment of a new value to a persistent property
or field of the entity as well as the modification of a mutable value of a persistent property or field.
Synchronization to the database does not involve a refresh of any managed entities unless the refresh
operation is explicitly invoked on those entities.
Bidirectional relationships between managed entities will be persisted based on references held by the
owning side of the relationship. It is the developer’s responsibility to keep the in-memory references
held on the owning side and those held on the inverse side consistent with each other when they change.
In the case of unidirectional one-to-one and one-to-many relationships, it is the developer’s responsibil-
ity to insure that the semantics of the relationships are adhered to.[24]
It is particularly important to ensure that changes to the inverse side of a relationship result in
appropriate updates on the owning side, so as to ensure the changes are not lost when they are
synchronized to the database.
The persistence provider runtime is permitted to perform synchronization to the database at other times
as well when a transaction is active. The flush method can be used by the application to force syn-
chronization. It applies to entities associated with the persistence context. The EntityManager and
Query setFlushMode methods can be used to control synchronization semantics. The effect of
FlushModeType.AUTO is defined in section 3.6.2. If FlushModeType.COMMIT is specified,
flushing will occur at transaction commit; the persistence provider is permitted, but not required, to per-
form to flush at other times. If there is no transaction active, the persistence provider must not flush to
the database.
[24] This might be an issue if unique constraints (such as those described for the default mappings in sections 2.10.3.1 and 2.10.5.1)
were not applied in the definition of the object/relational mapping.
Entity Operations Java Persistence 2.0, Early Draft Entity Instance’s Life Cycle
nized with the database; otherwise, if Y owns the relationships, the behavior
is undefined.
• If X is a removed entity, it is removed from the database. No cascade options are relevant.
• If X is a managed entity, the state of X is refreshed from the database, overwriting changes
made to the entity, if any. The refresh operation is cascaded to entities referenced by X, if the
relationship from X to these other entities is annotated with the cascade=REFRESH or
cascade=ALL annotation element value.
Applications must use the flush method prior to the clear method to ensure portable semantics if
changes have been made to the entity (including removal of the entity). Because the persistence pro-
vider is allowed to write to the database at times other than the explicit invocation of the flush
method, portable applications must not assume that changes have not been written to the database if the
flush method has not been called prior to eviction.
• If X is a managed entity, the clear operation causes it to become detached. The clear operation
is cascaded to entities referenced by X, if the relationships from X to these other entities is
annotated with the cascade=CLEAR or cascade=ALL annotation element value. Entities
which previously referenced X will continue to reference X.
• If X is a removed entity, the clear operation is cascaded to entities referenced by X, if the rela-
tionships from X to these other entities is annotated with the cascade=CLEAR or cas-
cade=ALL annotation element value. Entities which previously referenced X will continue to
reference X. Portable applications should not pass removed entities that have been cleared
from the persistence context to further EntityManager operations.
Open Issue: Alternative names for this method and the corresponding cascade option.
Entity Instance’s Life Cycle Java Persistence 2.0, Early Draft Entity Operations
A detached entity may result from transaction commit if a transaction-scoped container-managed entity
manager is used (see section 3.3); from transaction rollback (see section 3.3.2); from clearing the persis-
tence context; from closing an entity manager; and from serializing an entity or otherwise passing an
entity by value—e.g., to a separate application tier, through a remote interface, etc.
Detached entity instances continue to live outside of the persistence context in which they were per-
sisted or retrieved, and their state is no longer guaranteed to be synchronized with the database state.
The application may access the available state of available detached entity instances after the persis-
tence context ends. The available state includes:
If the persistent field or property is an association, the available state of an associated instance may only
be safely accessed if the associated instance is available. The available instances include:
• Any entity instances retrieved using a query or explicitly requested in a FETCH JOIN clause.
• Any entity instance for which an instance variable holding non-primary-key persistent state
was accessed by the application.
• Any entity instance that may be reached from another available instance by navigating associ-
ations marked fetch=EAGER.
The merge operation allows for the propagation of state from detached entities onto persistent entities
managed by the EntityManager.
• If X is a detached entity, the state of X is copied onto a pre-existing managed entity instance X'
of the same identity or a new managed copy X' of X is created.
• If X is a new entity instance, a new managed entity instance X' is created and the state of X is
copied into the new managed entity instance X'.
• If X is a managed entity, it is ignored by the merge operation, however, the merge operation is
cascaded to entities referenced by relationships from X if these relationships have been anno-
tated with the cascade element value cascade=MERGE or cascade=ALL annotation.
Entity Operations Java Persistence 2.0, Early Draft Entity Instance’s Life Cycle
• For all entities Y referenced by relationships from X having the cascade element value
cascade=MERGE or cascade=ALL, Y is merged recursively as Y'. For all such Y refer-
enced by X, X' is set to reference Y'. (Note that if X is managed then X is the same object as
X'.)
The persistence provider must not merge fields marked LAZY that have not been fetched: it must ignore
such fields when merging.
Any Version columns used by the entity must be checked by the persistence runtime implementation
during the merge operation and/or at flush or commit time. In the absence of Version columns there is
no additional version checking done by the persistence provider runtime during the merge operation.
A vendor is required to support the serialization and subsequent deserialization and merging of detached
entity instances (which may contain lazy properties or fields and/or relationships that have not been
fetched) back into a separate JVM instance of that vendor's runtime, where both runtime instances have
access to the entity classes and any required vendor persistence implementation classes.
When interoperability across vendors is required, the application must not use lazy loading.
The contains() method can be used to determine whether an entity instance is managed in the cur-
rent persistence context.
• If the entity has been retrieved from the database or has been returned by getReference,
and has not been removed or detached.
• If the entity instance is new, and the persist method has been called on the entity or the per-
sist operation has been cascaded to it.
Persistence Context Lifetime Java Persistence 2.0, Early Draft Entity Operations
• If the remove method has been called on the entity, or the remove operation has been cas-
caded to it.
• If the instance is new, and the persist method has not been called on the entity or the persist
operation has not been cascaded to it.
Note that the effect of the cascading of persist, merge, remove, or clear is immediately visible to the
contains method, whereas the actual insertion, modification, or deletion of the database representa-
tion for the entity may be deferred until the end of the transaction.
The lifetime of a container-managed persistence context may either be scoped to a transaction (transac-
tion-scoped persistence context), or have a lifetime scope that extends beyond that of a single transac-
tion (extended persistence context). The enum PersistenceContextType is used to define the
persistence context lifetime scope for container-managed entity managers. The persistence context life-
time scope is defined when the EntityManager instance is created (whether explicitly, or in conjunction
with injection or JNDI lookup). See Section 5.6.
When an extended persistence context is used, the extended persistence context exists from the time the
EntityManager instance is created until it is closed. This persistence context might span multiple trans-
actions and non-transactional invocations of the EntityManager. A container-managed extended persis-
tence context is enlisted in the current transaction when the EntityManager is invoked in the scope of
that transaction or when the stateful session bean to which the extended persistence context is bound is
invoked in the scope of that transaction.
An EntityManager with an extended persistence context maintains its references to the entity objects
after a transaction has committed. Those objects remain managed by the EntityManager, and they may
be updated as managed objects between transactions.[25] Navigation from a managed object in an
extended persistence context results in one or more other managed objects regardless of whether a trans-
action is active.
When an EntityManager with an extended persistence context is used, the persist, remove, merge, and
refresh operations may be called regardless of whether a transaction is active. The effects of these oper-
ations will be committed to the database when the extended persistence context is enlisted in a transac-
tion and the transaction commits.
[25] Note that when a new transaction is begun, the managed objects in an extended persistence context are not reloaded from the data-
base.
Entity Operations Java Persistence 2.0, Early Draft Locking and Concurrency
The scope of the persistence context of an application-managed entity manager is extended. It is the
responsibility of the application to manage the lifecycle of the persistence context.
Container-managed persistence contexts are described further in section 5.6. Persistence contexts man-
aged by the application are described futher in section 5.7.
This specification assumes the use of optimistic concurrency control. It assumes that the databases to
which persistence units are mapped will be accessed by implementations using read-committed isola-
tion (or a vendor equivalent in which long-term read locks are not held), and that writes to the database
typically occur only when the flush method has been invoked—whether explicitly by the application,
or by the persistence provider runtime in accordance with the flush mode setting. If a transaction is
active, a compliant implementation of this specification is permitted to write to the database immedi-
ately (i.e., whenever a managed entity is updated, created, and/or removed), however, the configuration
of an implementation to require such non-deferred database writes is outside the scope of this specifica-
tion. [28]
In addition, both pessimistic and optimistic locking are supported for selected entities by means of spec-
ified lock modes. The configuration of the setting of optimistic lock modes is described in section
3.4.4.1, and the configuration of the setting of pessimistic lock modes is described in section 3.4.4.2.
[26] These are instances that were persistent in the database at the start of the transaction.
[27] It is unspecified as to whether instances that were not persistent in the database behave as new instances or detached instances
after rollback. This may be implementation-dependent.
[28] Applications that prefer the use of pessimistic concurrency control may require that database isolation levels higher than
read-committed be in effect. The configuration of the setting database isolation levels, however, is outside the scope of this speci-
fication.
Locking and Concurrency Java Persistence 2.0, Early Draft Entity Operations
Portable applications that wish to enable optimistic locking for entities must specify Version
attributes for those entities—i.e., persistent properties or fields annotated with the Version annotation
or specified in the XML descriptor as version attributes. Applications are strongly encouraged to enable
optimistic locking for all entities that may be concurrently accessed or merged from a disconnected
state. Failure to use optimistic locking may lead to inconsistent entity state, lost updates and other state
irregularities. If optimistic locking is not defined as part of the entity state, the application must bear the
burden of maintaining data consistency.
An entity may access the state of its version field or property or export a method for use by the applica-
tion to access the version, but must not modify the version value[29]. Only the persistence provider is
permitted to set or update the value of the version attribute in the object.
The version attribute is updated by the persistence provider runtime when the object is written to the
database. All non-relationship fields and properties and all relationships owned by the entity are
included in version checks.
The persistence provider's implementation of the merge operation must examine the version attribute
when an entity is being merged and throw an OptimisticLockException if it is discovered that
the object being merged is a stale copy of the entity—i.e. that the entity has been updated since the
entity became detached. Depending on the implementation strategy used, it is possible that this excep-
tion may not be thrown until flush is called or commit time, whichever happens first.
The persistence provider runtime is only required to use the version attribute when performing optimis-
tic lock checking. Persistence provider implementations may provide additional mechanisms beside
version attributes to enable optimistic lock checking. However, support for such mechanisms is not
required of an implementation of this specification.[30]
[29] Bulk update statements, however, are permitted to set the value of version attributes. See section 4.10.
[30] Such additional mechanisms may be standardized by a future release of this specification.
Entity Operations Java Persistence 2.0, Early Draft Locking and Concurrency
If only some entities contain version attributes, the persistence provider runtime is required to check
those entities for which version attributes have been specified. The consistency of the object graph is
not guaranteed, but the absence of version attributes on some of the entities will not stop operations
from completing.
Pessimistic locking guarantees that once a transaction has obtained a pessimistic lock on an entity
instance:
• no other transaction (whether a transaction of an application using the Java Persistence API or
any other transaction using the underlying resource) may successfully modify or delete that
instance until the transaction holding the lock has ended.
This specification does not define the mechanisms a persistence provider uses to obtain database locks,
and a portable application may not rely on how pessimistic locking is achieved on the database.[31] In
particular, a persistence provider or the underlying database management system may lock more rows
than the ones selected by the application.
Whenever a pessimistically locked entity containing a version attribute is updated on the database, the
persistence provider must also update (increment) the entity's version column to enable correct interac-
tion with applications using optimistic locking. See sections 3.4.2 and 3.4.4.
Pessimistic locking may be applied to entities that do not contain version attributes. However, in this
case correct interaction with applications using optimistic locking cannot be ensured.
Lock modes are intended to provide a facility that enables the effect of “repeatable read” semantics for
the items read, whether “optimistically” (as described in section 3.4.4.1) or “pessimistically” (as
described in section 3.4.4.2).
[31] A persistence provider may, for example, use an underlying database platform's SELECT FOR UPDATE statements to implement
pessimistic locking if that construct provides appropriate semantics.
Locking and Concurrency Java Persistence 2.0, Early Draft Entity Operations
Open Issue: Names of the lock modes are still under discussion and subject to change.
Lock modes OPTIMISTIC and OPTIMISTIC_FORCE_INCREMENT are used for optimistic locking.
• P1 (Dirty read): Transaction T1 modifies a row. Another transaction T2 then reads that row and
obtains the modified value, before T1 has committed or rolled back. Transaction T2 eventually
commits successfully; it does not matter whether T1 commits or rolls back and whether it does
so before or after T2 commits.
[32] The lock mode type NONE may be specified as a value of lock mode arguments and also provides a default value for annota-
tions.
Entity Operations Java Persistence 2.0, Early Draft Locking and Concurrency
If a versioned object is otherwise updated or removed, then the implementation must ensure that the
requirements of LockModeType.OPTIMISTIC_FORCE_INCREMENT are met, even if no explicit
call to EntityManager.lock was made.
For portability, an application should not depend on vendor-specific hints or configuration to ensure
repeatable read for objects that are not updated or removed via any mechanism other than the use of ver-
sion attributes and the EntityManager lock method. However, it should be noted that if an implemen-
tation has acquired up-front pessimistic locks on some database rows, then it is free to ignore
lock(entity, LockModeType.OPTIMISTIC) calls on the entity objects representing those
rows.
Locking and Concurrency Java Persistence 2.0, Early Draft Entity Operations
• P1 (Dirty read): Transaction T1 modifies a row. Another transaction T2 then reads that row and
obtains the modified value, before T1 has committed or rolled back.
Any such lock must be obtained immediately and retained until transaction T1 completes (commits or
rolls back).
Avoidance of phenomena P1 and P2 is generally achieved by the entity manager acquiring a long-term
lock on the underlying database row. Any implementation that supports pessimistic repeatable reads as
described above is permissible.
When the lock cannot be obtained, and the database locking failure results in transaction-level rollback,
the provider must throw the PessimisticLockException and ensure that the JTA transaction or
EntityTransaction has been marked for rollback.
When the lock cannot be obtained, and the database locking failure results in only statement-level roll-
back, the provider must throw the LockTimeoutException (and not mark the transaction for roll-
back).
Entity Operations Java Persistence 2.0, Early Draft Locking and Concurrency
This hint may be used with the methods of the EntityManager interface that allow lock modes to be
specified, the Query.setLockMode method and the NamedQuery annotation. It may also be
passed as a property to the Persistence.createEntityManagerFactory method and used
in the properties element of the persistence.xml file. See sections 3.1.1, 3.6.3, 6.2.1.7, 7.2.1,
and 8.3.1. When used in the createEntityManagerFactory method, the persistence.xml
file, and the NamedQuery annotation, the timeout hint serves as a default value which can be selec-
tively overridden by use in the methods of the EntityManager and Query interfaces as specified above.
Portable applications should not rely on this hint. Depending on the database in use and the locking
mechanisms used by the persistence provider, the hint may or may not be observed.
Vendors are permitted to support the use of additional, vendor-specific locking hints. Vendor-specific
hints must not use the javax.persistence namespace. Vendor-specific hints must be ignored if
they are not understood.
3.4.5 OptimisticLockException
Provider implementations may defer writing to the database until the end of the transaction, when con-
sistent with the flush mode setting in effect. In this case, the optimistic lock check may not occur until
commit time, and the OptimisticLockException may be thrown in the "before completion"
phase of the commit. If the OptimisticLockException must be caught or handled by the appli-
cation, the flush method should be used by the application to force the database writes to occur. This
will allow the application to catch and handle optimistic lock exceptions.
The OptimisticLockException provides an API to return the object that caused the exception to
be thrown. The object reference is not guaranteed to be present every time the exception is thrown but
should be provided whenever the persistence provider can supply it. Applications cannot rely upon this
object being available.
Entity Listeners and Callback Methods Java Persistence 2.0, Early Draft Entity Operations
Refreshing objects or reloading objects in a new transaction context and then retrying the transaction is
a potential response to an OptimisticLockException.
A method may be designated as a lifecycle callback method to receive notification of entity lifecycle
events.
A lifecycle callback method may be defined on an entity class, a mapped superclass, or an entity listener
class associated with an entity or mapped superclass. An entity listener class is a class whose methods
are invoked in response to lifecycle events on an entity. Any number of entity listener classes may be
defined for an entity class or mapped superclass.
Default entity listeners—entity listeners that apply to all entities in the persistence unit—can be speci-
fied by means of the XML descriptor.
Lifecycle callback methods and entity listener classes are defined by means of metadata annotations or
the XML descriptor. When annotations are used, one or more entity listener classes are denoted using
the EntityListeners annotation on the entity class or mapped superclass. If multiple entity listen-
ers are defined, the order in which they are invoked is determined by the order in which they are speci-
fied in the EntityListeners annotation. The XML descriptor may be used as an alternative to
specify the invocation order of entity listeners or to override the order specified in metadata annotations.
Any subset or combination of annotations may be specified on an entity class, mapped superclass, or
listener class. A single class may not have more than one lifecycle callback method for the same lifecy-
cle event. The same method may be used for multiple callback events.
Multiple entity classes and mapped superclasses in an inheritance hierarchy may define listener classes
and/or lifecycle callback methods directly on the class. Section 3.5.4 describes the rules that apply to
method invocation order in this case.
• Lifecycle callbacks can invoke JNDI, JDBC, JMS, and enterprise beans.
• In general, the lifecycle method of a portable application should not invoke EntityMan-
ager or Query operations, access other entity instances, or modify relationships within the
same persistence context.[33]
Entity Operations Java Persistence 2.0, Early Draft Entity Listeners and Callback Methods
When invoked from within a Java EE environment, the callback listeners for an entity share the enter-
prise naming context of the invoking component, and the entity callback methods are invoked in the
transaction and security contexts of the calling component at the time at which the callback method is
invoked. [34]
Lifecycle callback methods are annotated with annotations designating the callback events for which
they are invoked or are mapped to the callback event using the XML descriptor.
The annotations used for callback methods on the entity class or mapped superclass and for callback
methods on the entity listener class are the same. The signatures of individual methods, however, differ.
Callback methods defined on an entity class or mapped superclass have the following signature:
void <METHOD>()
Callback methods defined on an entity listener class have the following signature:
void <METHOD>(Object)
The Object argument is the entity instance for which the callback method is invoked. It may be
declared as the actual entity type.
The callback methods can have public, private, protected, or package level access, but must not be
static or final.
The following annotations are defined to designate lifecycle event callback methods of the correspond-
ing types.
• PrePersist
• PostPersist
• PreRemove
• PostRemove
• PreUpdate
• PostUpdate
[33] The semantics of such operations may be standardized in a future release of this specification.
[34] For example, if a transaction commit occurs as a result of the normal termination of a session bean business method with transac-
tion attribute RequiresNew, the PostPersist and PostRemove callbacks are executed in the naming context, the transac-
tion context, and the security context of that component.
Entity Listeners and Callback Methods Java Persistence 2.0, Early Draft Entity Operations
• PostLoad
The PostPersist and PostRemove callback methods are invoked for an entity after the entity has
been made persistent or removed. These callbacks will also be invoked on all entities to which these
operations are cascaded. The PostPersist and PostRemove methods will be invoked after the
database insert and delete operations respectively. These database operations may occur directly after
the persist, merge, or remove operations have been invoked or they may occur directly after a flush
operation has occurred (which may be at the end of the transaction). Generated primary key values are
available in the PostPersist method.
The PreUpdate and PostUpdate callbacks occur before and after the database update operations to
entity data respectively. These database operations may occur at the time the entity state is updated or
they may occur at the time state is flushed to the database (which may be at the end of the transaction).
The PostLoad method for an entity is invoked after the entity has been loaded into the current persis-
tence context from the database or after the refresh operation has been applied to it. The PostLoad
method is invoked before a query result is returned or accessed or before an association is traversed.
It is implementation-dependent as to whether callback methods are invoked before or after the cascad-
ing of the lifecycle events to related entities. Applications should not depend on this ordering.
Entity Operations Java Persistence 2.0, Early Draft Entity Listeners and Callback Methods
3.5.3 Example
@Entity
@EntityListeners(com.acme.AlertMonitor.class)
public class Account {
Long accountId;
Integer balance;
boolean preferred;
@Id
public Long getAccountId() { ... }
...
public Integer getBalance() { ... }
...
@Transient // because status depends upon non-persistent context
public boolean isPreferred() { ... }
...
@PrePersist
protected void validateCreate() {
if (getBalance() < MIN_REQUIRED_BALANCE)
throw new AccountException("Insufficient balance to open an
account");
}
@PostLoad
protected void adjustPreferredStatus() {
preferred =
(getBalance() >= AccountManager.getPreferredStatu-
sLevel());
}
}
@PostPersist
public void newAccountAlert(Account acct) {
Alerts.sendMarketingInfo(acct.getAccountId(), acct.getBal-
ance());
}
}
If multiple callback methods are defined for an entity lifecycle event, the ordering of the invocation of
these methods is as follows.
Default listeners, if any, are invoked first, in the order specified in the XML descriptor. Default listeners
apply to all entities in the persistence unit, unless explicitly excluded by means of the ExcludeDe-
faultListeners annotation or exclude-default-listeners XML element.
Entity Listeners and Callback Methods Java Persistence 2.0, Early Draft Entity Operations
The lifecycle callback methods defined on the entity listener classes for an entity class or mapped super-
class are invoked in the same order as the specification of the entity listener classes in the Enti-
tyListeners annotation.
If a lifecycle callback method for the same lifecycle event is also specified on the entity class and/or one
or more of its entity or mapped superclasses, the callback methods on the entity class and/or super-
classes are invoked after the other lifecycle callback methods, most general superclass first. A class is
permitted to override an inherited callback method of the same callback type, and in this case, the over-
ridden method is not invoked.[36]
Callback methods are invoked by the persistence provider runtime in the order specified. If the callback
method execution terminates normally, the persistence provider runtime then invokes the next callback
method, if any.
The XML descriptor may be used to override the lifecycle callback method invocation order specified
in annotations.
[35] Excluded listeners may be reintroduced on an entity class by listing them explicitly in the EntityListeners annotation or
XML entity-listeners element.
[36] If a method overrides an inherited callback method but specifies a different lifecycle event or is not a lifecycle callback method,
the overridden method will not be invoked.
Entity Operations Java Persistence 2.0, Early Draft Entity Listeners and Callback Methods
3.5.5 Example
There are several entity classes and listeners for animals:
@Entity
public class Animal {
....
@PostPersist
protected void postPersistAnimal() {
....
}
}
@Entity
@EntityListeners(PetListener.class)
public class Pet extends Animal {
....
}
@Entity
@EntityListeners({CatListener.class, CatListener2.class})
public class Cat extends Pet {
....
}
If a PostPersist event occurs on an instance of Cat, the following methods are called in order:
postPersistPetListenerMethod
postPersistCatListenerMethod
postPersistCatListener2Method
postPersistAnimal
Entity Listeners and Callback Methods Java Persistence 2.0, Early Draft Entity Operations
@EntityListeners(SiameseCatListener.class)
@Entity
public class SiameseCat extends Cat {
...
@PostPersist
protected void postPersistSiameseCat() {
...
}
}
If a PostPersist event occurs on an instance of SiameseCat, the following methods are called in
order:
postPersistPetListenerMethod
postPersistCatListenerMethod
postPersistCatListener2Method
postPersistSiameseCatListenerMethod
postPersistAnimal
postPersistSiameseCat
@EntityListeners(SiameseCatListener.class)
@Entity
public class SiameseCat extends Cat {
...
@PostPersist
protected void postPersistAnimal() {
...
}
}
In this case, the following methods would be called in order, where postPersistAnimal is the
PostPersist method defined in the SiameseCat class:
postPersistPetListenerMethod
postPersistCatListenerMethod
postPersistCatListener2Method
postPersistSiameseCatListenerMethod
postPersistAnimal
3.5.6 Exceptions
Lifecycle callback methods may throw runtime exceptions. A runtime exception thrown by a callback
method that executes within a transaction causes that transaction to be marked for rollback. No further
lifecycle callback methods will be invoked after a runtime exception is thrown.
3.5.7 Specification of Callback Listener Classes and Lifecycle Methods in the XML
Descriptor
The XML descriptor can be used as an alternative to metadata annotations to specify entity listener
classes and their binding to entities or to override the invocation order of lifecycle callback methods as
specified in annotations.
The entity-listener XML descriptor element is used to specify the lifecycle listener methods of
an entity listener class. The lifecycle listener methods are specified by using the pre-persist,
post-persist, pre-remove, post-remove, pre-update, post-update, and/or
post-load elements.
An entity listener class can define multiple callback methods. However, at most one method of an entity
listener class can be designated as a pre-persist method, post-persist method, pre-remove method,
post-remove method, pre-update method, post-update method, and/or post-load method, regardless of
whether the XML descriptor is used to define entity listeners or whether some combination of annota-
tions and XML descriptor elements is used.
The binding of entity listeners to entity classes is additive. The entity listener classes bound to the
superclasses of an entity or mapped superclass are applied to it as well.
The exclude-superclass-listeners element specifies that the listener methods for super-
classes are not to be invoked for an entity class (or mapped superclass) and its subclasses.
The exclude-default-listeners element specifies that default entity listeners are not to be
invoked for an entity class (or mapped superclass) and its subclasses.
Explicitly listing an excluded default or superclass listener for a given entity class or mapped superclass
causes it to be applied to that entity or mapped superclass and its subclasses.
In the case of multiple callback methods for a single lifecycle event, the invocation order rules
described in section 3.5.4 apply.
The Query API is used for both static queries (i.e., named queries) and dynamic queries. The Query
API also supports named parameter binding and pagination control.
/**
* Interface used to control query execution.
*/
/**
* Execute a SELECT query and return the query results
* as a List.
* @return a list of the results
* @throws IllegalStateException if called for a Java
* Persistence query language UPDATE or DELETE statement
* @throws QueryTimeoutException if the query execution exceeds
timeout value set
* @throws TransactionRequiredException if a lock mode has
* been set and there is no transaction
* @throws PessimisticLockException if pessimistic locking
* fails and the transaction is rolled back
* @throws LockTimeoutException if pessimistic locking
* fails and only the statement is rolled back
*/
public List getResultList();
/**
* Execute a SELECT query that returns a single result.
* @return the result
* @throws NoResultException if there is no result
* @throws NonUniqueResultException if more than one result
* @throws IllegalStateException if called for a Java
* Persistence query language UPDATE or DELETE statement
* @throws QueryTimeoutException if the query execution exceeds
timeout value set
* @throws TransactionRequiredException if a lock mode has
* been set and there is no transaction
* @throws PessimisticLockException if pessimistic locking
* fails and the transaction is rolled back
* @throws LockTimeoutException if pessimistic locking
* fails and only the statement is rolled back
*/
public Object getSingleResult();
/**
* Execute an update or delete statement.
* @return the number of entities updated or deleted
* @throws IllegalStateException if called for a Java
* Persistence query language SELECT statement
* @throws TransactionRequiredException if there is
* no transaction
* @throws QueryTimeoutException if the statement execution
exceeds timeout value set
*/
public int executeUpdate();
/**
* Set the maximum number of results to retrieve.
* @param maxResult
* @return the same query instance
* @throws IllegalArgumentException if argument is negative
*/
public Query setMaxResults(int maxResult);
/**
* The maximum number of results the query object was set to
* retrieve. Returns Integer.MAX_VALUE if setMaxResults was not
* applied to the query object.
* @return maximum number of results
*/
public int getMaxResults();
/**
* Set the position of the first result to retrieve.
* @param start position of the first result, numbered from 0
* @return the same query instance
* @throws IllegalArgumentException if argument is negative
*/
public Query setFirstResult(int startPosition);
/**
* The position of the first result the query object was set to
* retrieve. Returns 0 if setFirstResult was not applied to the
* query object.
* @return position of first result
*/
public int getFirstResult();
/**
* Set a query hint.
* If a vendor-specific hint is not recognized, it is silently
* ignored.
* Portable applications should not rely on the standard timeout
* hint. Depending on the database in use and the locking
* mechanisms used by the provider, the hint may or may not
* be observed.
* @param hintName
* @param value
* @return the same query instance
* @throws IllegalArgumentException if the second argument is not
* valid for the implementation
*/
public Query setHint(String hintName, Object value);
/**
* Get the hints and associated values that are in effect for
* the query instance.
* @return query hints
*/
public Map getHints();
/**
* Get the names of the hints that are supported for query
* objects. These hints correspond to hints that may be passed
* to the methods of the Query interface that take hints as
* arguments or used with the NamedQuery and NamedNativeQuery
* annotations. These include all standard query hints as well as
* vendor-specific hints supported by the provider. These hints
* may or may not currently be in effect.
* @return hints
*/
public Set<String> getSupportedHints();
/**
* Bind an argument to a named parameter.
* @param name the parameter name
* @param value
* @return the same query instance
* @throws IllegalArgumentException if parameter name does not
* correspond to parameter in query string
* or argument is of incorrect type
*/
public Query setParameter(String name, Object value);
/**
* Bind an instance of java.util.Date to a named parameter.
* @param name
* @param value
* @param temporalType
* @return the same query instance
* @throws IllegalArgumentException if parameter name does not
* correspond to parameter in query string
*/
public Query setParameter(String name, Date value,
TemporalType temporalType);
/**
* Bind an instance of java.util.Calendar to a named parameter.
* @param name
* @param value
* @param temporalType
* @return the same query instance
* @throws IllegalArgumentException if parameter name does not
* correspond to parameter in query string
*/
public Query setParameter(String name, Calendar value,
TemporalType temporalType);
/**
* Bind an argument to a positional parameter.
* @param position
* @param value
* @return the same query instance
* @throws IllegalArgumentException if position does not
* correspond to positional parameter of query
* or argument is of incorrect type
*/
public Query setParameter(int position, Object value);
/**
* Bind an instance of java.util.Date to a positional parameter.
* @param position
* @param value
* @param temporalType
* @return the same query instance
* @throws IllegalArgumentException if position does not
* correspond to positional parameter of query
*/
public Query setParameter(int position, Date value,
TemporalType temporalType);
/**
* Bind an instance of java.util.Calendar to a positional
* parameter.
* @param position
* @param value
* @param temporalType
* @return the same query instance
* @throws IllegalArgumentException if position does not
* correspond to positional parameter of query
*/
public Query setParameter(int position, Calendar value,
TemporalType temporalType);
/**
* Get the parameters names and associated values of the
* parameters that are bound for the query instance.
* Returns empty map if no parameters have been bound
* or if the query does not use named parameters.
* @return named parameters
*/
public Map getNamedParameters();
/**
* Get the values of the positional parameters
* that are bound for the query instance.
* Positional positions are listed in order of position.
* Returns empty list if no parameters have been bound
* or if the query does not use positional parameters.
* @return positional parameters
*/
public List getPositionalParameters();
/**
* Set the flush mode type to be used for the query execution.
* The flush mode type applies to the query regardless of the
* flush mode type in use for the entity manager.
* @param flushMode
*/
public Query setFlushMode(FlushModeType flushMode);
/**
* The flush mode in effect for the query execution. If a flush
* mode has not been set for the query object, returns the flush
* mode in effect for the entity manager.
* @return flush mode
*/
public FlushModeType getFlushMode();
/**
* Set the lock mode type to be used for the query execution.
* @param lockMode
* @throws IllegalStateException if not a Java Persistence
* query language SELECT query
*/
public Query setLockMode(LockModeType lockMode);
/**
* Get the current lock mode for the query.
* @return lock mode
* @throws IllegalStateException if not a Java Persistence
* query language SELECT query
*/
public LockModeType getLockMode();
}
The elements of the result of a Java Persistence query whose SELECT clause consists of more than one
select expression are of type Object[]. If the SELECT clause consists of only one select expression,
the elements of the query result are of type Object. When native SQL queries are used, the SQL result
set mapping (see section 3.6.8), determines how many items (entities, scalar values, etc.) are returned. If
multiple items are returned, the elements of the query result are of type Object[]. If only a single
item is returned as a result of the SQL result set mapping or if a result class is specified, the elements of
the query result are of type Object.
The effect of applying setMaxResults or setFirstResult to a query involving fetch joins over
collections is undefined.
Query methods other than the executeUpdate method are not required to be invoked within a trans-
action context, unless a lock mode has been specified for the query. In particular, the getRe-
sultList and getSingleResult methods are not required to be invoked within a transaction
context unless a lock mode has been specified for the query.[37] If an entity manager with transac-
tion-scoped persistence context is in use, the resulting entities will be detached; if an entity manager
with an extended persistence context is used, they will be managed. See Chapter 5 for further discussion
of entity manager use outside a transaction and persistence context types.
[37] A lock mode is specified for a query by means of the setLockMode method or by specifying the lock mode in the Named-
Query annotation.
3.6.1.1 Example
public List findWithName(String name) {
return em.createQuery(
"SELECT c FROM Customer c WHERE c.name LIKE :custName")
.setParameter("custName", name)
.setMaxResults(10)
.getResultList();
}
When queries are executed within a transaction, if FlushModeType.AUTO is set on the Query
object, or if the flush mode setting for the persistence context is AUTO (the default) and a flush mode
setting has not been specified for the Query object, the persistence provider is responsible for ensuring
that all updates to the state of all entities in the persistence context which could potentially affect the
result of the query are visible to the processing of the query. The persistence provider implementation
may achieve this by flushing those entities to the database or by some other means. If FlushMode-
Type.COMMIT is set, the effect of updates made to entities in the persistence context upon queries is
unspecified.
If there is no transaction active, the persistence provider must not flush to the database.
If a lock mode other than NONE is specified for a query, the query must be executed within a transaction
or the TransactionRequiredException will be thrown.
[38] Note that locking will not occur for data passed to aggregate functions.
This hint may be used with the methods of the Query.setHint method and the NamedQuery and
NamedNativeQuery annotations. It may also be passed as a property to the Persistence.cre-
ateEntityManagerFactory method and used in the properties element of the persis-
tence.xml file. See sections 3.6.1, 6.2.1.7, 7.2.1, 8.3. When used in the
createEntityManagerFactory method, the persistence.xml file, and annotations, the
timeout hint serves as a default value which can be selectively overridden by use in the Query.set-
Hint method.
Portable applications should not rely on this hint. Depending on the persistence provider and database in
use, the hint may or may not be observed.
Vendors are permitted to support the use of additional, vendor-specific locking hints. Vendor-specific
hints must not use the javax.persistence namespace. Vendor-specific hints must be ignored if
they are not understood.
Named parameters follow the rules for identifiers defined in Section 4.4.1. The use of named parame-
ters applies to the Java Persistence query language, and is not defined for native queries. Only positional
parameter binding may be portably used for native queries.
The parameter names passed to the setParameter methods of the Query API do not include the
":" prefix.
@NamedQuery(
name="findAllCustomersWithName",
query="SELECT c FROM Customer c WHERE c.name LIKE :custName"
)
@PersistenceContext
public EntityManager em;
...
customers = em.createNamedQuery("findAllCustomersWithName")
.setParameter("custName", "Smith")
.getResultList();
By default, all queries are polymorphic. That is, the FROM clause of a query designates not only
instances of the specific entity class(es) to which it explicitly refers, but subclasses as well. The
instances returned by a query include instances of the subclasses that satisfy the query conditions.[39]
returns the average salary of all employees, including subtypes of Employee, such as Manager and
Exempt.
The SQL query facility is intended to provide support for those cases where it is necessary to
use the native SQL of the target database in use (and/or where the Java Persistence query lan-
guage cannot be used). Native SQL queries are not expected to be portable across databases.
When multiple entities are returned by a SQL query, the entities must be specified and mapped to the
column results of the SQL statement in a SqlResultSetMapping metadata definition. This result
set mapping metadata can then be used by the persistence provider runtime to map the JDBC results
into the expected objects. See Section 8.3.3 for the definition of the SqlResultSetMapping meta-
data annotation and related annotations.
If the results of the query are limited to entities of a single entity class, a simpler form may be used and
SqlResultSetMapping metadata is not required.
This is illustrated in the following example in which a native SQL query is created dynamically using
the createNativeQuery method and the entity class that specifies the type of the result is passed in
as an argument.
Query q = em.createNativeQuery(
"SELECT o.id, o.quantity, o.item " +
"FROM Order o, Item i " +
"WHERE (o.item = i.id) AND (i.name = ‘widget’)",
com.acme.Order.class);
When executed, this query will return a Collection of all Order entities for items named "widget". The
same results could also be obtained using SqlResultSetMapping:
Query q = em.createNativeQuery(
"SELECT o.id, o.quantity, o.item " +
"FROM Order o, Item i " +
"WHERE (o.item = i.id) AND (i.name = ‘widget’)",
"WidgetOrderResults");
In this case, the metadata for the query result type might be specified as follows:
@SqlResultSetMapping(name="WidgetOrderResults",
entities=@EntityResult(entityClass=com.acme.Order.class))
The following query and SqlResultSetMapping metadata illustrates the return of multiple entity
types and assumes default metadata and column name defaults.
Query q = em.createNativeQuery(
"SELECT o.id, o.quantity, o.item, i.id, i.name, i.description "+
"FROM Order o, Item i " +
"WHERE (o.quantity > 25) AND (o.item = i.id)",
"OrderItemResults");
@SqlResultSetMapping(name="OrderItemResults",
entities={
@EntityResult(entityClass=com.acme.Order.class),
@EntityResult(entityClass=com.acme.Item.class)
})
When an entity is being returned, the SQL statement should select all of the columns that are mapped to
the entity object. This should include foreign key columns to related entities. The results obtained
when insufficient data is available are undefined. A SQL result set mapping must not be used to map
results to the non-persistent state of an entity.
The column names that are used in the SQL result set mapping annotations refer to the names of the col-
umns in the SQL SELECT clause. Note that column aliases must be used in the SQL SELECT clause
where the SQL result would otherwise contain multiple columns of the same name.
An example of combining multiple entity types and that includes aliases in the SQL statement requires
that the column names be explicitly mapped to the entity fields. The FieldResult annotation is used
for this purpose.
Query q = em.createNativeQuery(
"SELECT o.id AS order_id, " +
"o.quantity AS order_quantity, " +
"o.item AS order_item, " +
"i.id, i.name, i.description " +
"FROM Order o, Item i " +
"WHERE (order_quantity > 25) AND (order_item = i.id)",
"OrderItemResults");
@SqlResultSetMapping(name="OrderItemResults",
entities={
@EntityResult(entityClass=com.acme.Order.class, fields={
@FieldResult(name="id", column="order_id"),
@FieldResult(name="quantity", column="order_quantity"),
@FieldResult(name="item", column="order_item")}),
@EntityResult(entityClass=com.acme.Item.class)
})
Scalar result types can be included in the query result by specifying the ColumnResult annotation in
the metadata.
Query q = em.createNativeQuery(
"SELECT o.id AS order_id, " +
"o.quantity AS order_quantity, " +
"o.item AS order_item, " +
"i.name AS item_name, " +
"FROM Order o, Item i " +
"WHERE (order_quantity > 25) AND (order_item = i.id)",
"OrderResults");
@SqlResultSetMapping(name="OrderResults",
entities={
@EntityResult(entityClass=com.acme.Order.class, fields={
@FieldResult(name="id", column="order_id"),
@FieldResult(name="quantity", column="order_quantity"),
@FieldResult(name="item", column="order_item")})},
columns={
@ColumnResult(name="item_name")}
)
When the returned entity type is the owner of a single-valued relationship and the foreign key is a com-
posite foreign key (composed of multiple columns), a FieldResult element should be used for each
of the foreign key columns. The FieldResult element must use a dot (".") notation form to indicate
which column maps to each property or field of the target entity primary key. The dot-notation form
described below is not required to be supported for any usage other than for composite foreign keys or
embedded primary keys.
If the target entity has a primary key of type IdClass, this specification takes the form of the name of
the field or property for the relationship, followed by a dot ("."), followed by the name of the field or
property of the primary key in the target entity. The latter will be annotated with Id, as specified in sec-
tion 9.1.18.
Example:
Query q = em.createNativeQuery(
"SELECT o.id AS order_id, " +
"o.quantity AS order_quantity, " +
"o.item_id AS order_item_id, " +
"o.item_name AS order_item_name, " +
"i.id, i.name, i.description " +
"FROM Order o, Item i " +
"WHERE (order_quantity > 25) AND (order_item_id = i.id) AND
(order_item_name = i.name)",
"OrderItemResults");
@SqlResultSetMapping(name="OrderItemResults",
entities={
@EntityResult(entityClass=com.acme.Order.class, fields={
@FieldResult(name="id", column="order_id"),
@FieldResult(name="quantity", column="order_quantity"),
@FieldResult(name="item.id", column="order_item_id")}),
@FieldResult(name="item.name",
column="order_item_name")}),
@EntityResult(entityClass=com.acme.Item.class)
})
If the target entity has a primary key of type EmbeddedId, this specification is composed of the name
of the field or property for the relationship, followed by a dot ("."), followed by the name or the field or
property of the primary key (i.e., the name of the field or property annotated as EmbeddedId), fol-
lowed by the name of the corresponding field or property of the embedded primary key class.
Example:
Query q = em.createNativeQuery(
"SELECT o.id AS order_id, " +
"o.quantity AS order_quantity, " +
"o.item_id AS order_item_id, " +
"o.item_name AS order_item_name, " +
"i.id, i.name, i.description " +
"FROM Order o, Item i " +
"WHERE (order_quantity > 25) AND (order_item_id = i.id) AND
(order_item_name = i.name)",
"OrderItemResults");
@SqlResultSetMapping(name="OrderItemResults",
entities={
@EntityResult(entityClass=com.acme.Order.class, fields={
@FieldResult(name="id", column="order_id"),
@FieldResult(name="quantity", column="order_quantity"),
@FieldResult(name="item.itemPk.id",
column="order_item_id")}),
@FieldResult(name="item.itemPk.name",
column="order_item_name")}),
@EntityResult(entityClass=com.acme.Item.class)
})
The FieldResult elements for the composite foreign key are combined to form the primary key
EmbeddedId class for the target entity. This may then be used to subsequently retrieve the entity if
the relationship is to be eagerly loaded.
The use of named parameters is not defined for native queries. Only positional parameter binding for
SQL queries may be used by portable applications.
PersistenceException
TransactionRequiredException
OptimisticLockException
PessimisticLockException
LockTimeoutException
because the database uses statement-level rollback when a pessimistic lock cannot be granted
(and there is no deadlock). The LockTimeoutException does not cause the current trans-
action to be marked for rollback.
RollbackException
EntityExistsException
The EntityExistsException may thrown by the persistence provider when the per-
sist operation is invoked and the entity already exists. The EntityExistsException
may be thrown when the persist operation is invoked, or the EntityExistsException or
another PersistenceException may be thrown at commit time.
EntityNotFoundException
NoResultException
NonUniqueResultException
QueryTimeoutException
C ha p t e r 4 Query Language
[Note to readers] Extensions to the Java Persistence query language and an API for criteria queries will be
addressed in the next draft of this specification.
The Java Persistence query language is used to define queries over entities and their persistent state. It
enables the application developer to specify the semantics of queries in a portable way, independent of
the particular database in use in an enterprise environment.
The Java Persistence query language is an extension of the Enterprise JavaBeans query language, EJB
QL, defined in [7]. It adds further operations, including bulk update and delete, JOIN operations,
GROUP BY, HAVING, projection, and subqueries; and supports the use of dynamic queries and the use
of named parameters. The full range of the language may be used in both static and dynamic queries.
4.1 Overview
The Java Persistence query language is a query specification language for dynamic queries and for static
queries expressed through metadata. It is used to define queries over the persistent entities defined by
this specification and their persistent state and relationships.
The Java Persistence query language can be compiled to a target language, such as SQL, of a database
or other persistent store. This allows the execution of queries to be shifted to the native language facili-
ties provided by the database, instead of requiring queries to be executed on the runtime representation
of the entity state. As a result, query methods can be optimizable as well as portable.
The query language uses the abstract persistence schemas of entities, including their relationships, for
its data model, and it defines operators and expressions based on this data model. It uses a SQL-like
syntax to select objects or values based on entity abstract schema types and relationships among them. It
is possible to parse and validate queries before entities are deployed.
The term abstract persistence schema refers to the persistent schema abstraction (persistent
entities, their state, and their relationships) over which Java Persistence queries operate.
Queries over this persistent schema abstraction are translated into queries that are executed
over the database schema to which entities are mapped. See Section 4.3.
Queries may be defined in metadata annotations or the XML descriptor. The abstract schema types of a
set of entities can be used in a query if the entities are defined in the same persistence unit as the query.
Path expressions allow for navigation over relationships defined in the persistence unit.
A persistence unit defines the set of all classes that are related or grouped by the application
and which must be colocated in their mapping to a single database.
A Java Persistence query language statement may be either a select statement, an update statement, or a
delete statement.
This chapter refers to all such statements as “queries”. Where it is important to distinguish
among statement types, the specific statement type is referenced.
Any Java Persistence query language statement may be constructed dynamically or may be statically
defined in a metadata annotation or XML descriptor element.
• a SELECT clause, which determines the type of the objects or values to be selected.
Abstract Schema Types and Query Domains Java Persistence 2.0, Early Draft Query Language
• a FROM clause, which provides declarations that designate the domain to which the expres-
sions specified in the other clauses of the query apply.
• an optional WHERE clause, which may be used to restrict the results that are returned by the
query.
• an optional ORDER BY clause, which may be used to order the results that are returned by the
query.
A select statement must always have a SELECT and a FROM clause. The square brackets [] indicate
that the other clauses are optional.
The update and delete clauses determine the type of the entities to be updated or deleted. The WHERE
clause may be used to restrict the scope of the update or delete operation.
The Java Persistence query language is a typed language, and every expression has a type. The type of
an expression is derived from the structure of the expression, the abstract schema types of the identifica-
tion variable declarations, the types to which the persistent fields and relationships evaluate, and the
types of literals.
The abstract schema type of an entity is derived from the entity class and the metadata information pro-
vided by Java language annotations or in the XML descriptor.
Query Language Java Persistence 2.0, Early Draft Abstract Schema Types and Query Domains
• For every persistent field or get accessor method (for a persistent property) of the entity class,
there is a field (“state-field”) whose abstract schema type corresponds to that of the field or
the result type of the accessor method.
• For every persistent relationship field or get accessor method (for a persistent relationship
property) of the entity class, there is a field (“association-field”) whose type is the abstract
schema type of the related entity (or, if the relationship is a one-to-many or many-to-many, a
collection of such).
Abstract schema types are specific to the query language data model. The persistence provider is not
required to implement or otherwise materialize an abstract schema type.
The domain of a query consists of the abstract schema types of all entities that are defined in the same
persistence unit.
The domain of a query may be restricted by the navigability of the relationships of the entity on which it
is based. The association-fields of an entity’s abstract schema type determine navigability. Using the
association-fields and their values, a query can select related entities and use their abstract schema types
in the query.
4.3.1 Naming
Entities are designated in query strings by their entity names. The entity name is defined by the name
element of the Entity annotation (or the entity-name XML descriptor element), and defaults to
the unqualified name of the entity class. Entity names are scoped within the persistence unit and must be
unique within the persistence unit.
4.3.2 Example
This example assumes that the application developer provides several entity classes, representing
orders, products, line items, shipping addresses, and billing addresses. The abstract schema types for
these entities are Order, Product, LineItem, ShippingAddress, and BillingAddress
respectively. These entities are logically in the same persistence unit, as shown in Figure 1.
Figure 1 Several Entities with Abstract Persistence Schemas Defined in the Same Persistence Unit.
The entities ShippingAddress and BillingAddress each have one-to-many relationships with
Order. There is also a one-to-many relationship between Order and Lineitem. The entity
LineItem is related to Product in a many-to-one relationship.
Abstract Schema Types and Query Domains Java Persistence 2.0, Early Draft Query Language
Order
m m 1
m
LineItem m
1
Product
1
1
Shipping Billing
Address Address
Queries to select orders can be defined by navigating over the association-fields and state-fields defined
by Order and LineItem. A query to find all orders with pending line items might be written as fol-
lows:
SELECT DISTINCT o
FROM Order AS o JOIN o.lineItems AS l
WHERE l.shipped = FALSE
This query navigates over the association-field lineItems of the abstract schema type Order to find
line items, and uses the state-field shipped of LineItem to select those orders that have at least one
line item that has not yet shipped. (Note that this query does not select orders that have no line items.)
Although predefined reserved identifiers, such as DISTINCT, FROM, AS, JOIN, WHERE, and FALSE
appear in upper case in this example, predefined reserved identifiers are case insensitive.
The SELECT clause of this example designates the return type of this query to be of type Order.
Because the same persistence unit defines the abstract persistence schemas of the related entities, the
developer can also specify a query over orders that utilizes the abstract schema type for products, and
hence the state-fields and association-fields of both the abstract schema types Order and Product.
For example, if the abstract schema type Product has a state-field named productType, a query
over orders can be specified using this state-field. Such a query might be to find all orders for products
with product type office supplies. A query for this might be as follows.
SELECT DISTINCT o
FROM Order o JOIN o.lineItems l JOIN l.product p
WHERE p.productType = ‘office_supplies’
Because Order is related to Product by means of the relationships between Order and LineItem
and between LineItem and Product, navigation using the association-fields lineItems and
product is used to express the query. This query is specified by using the abstract schema name
Order, which designates the abstract schema type over which the query ranges. The basis for the navi-
gation is provided by the association-fields lineItems and product of the abstract schema types
Order and LineItem respectively.
Query Language Java Persistence 2.0, Early Draft The FROM Clause and Navigational Declarations
The FROM clause of a query defines the domain of the query by declaring identification variables. An
identification variable is an identifier declared in the FROM clause of a query. The domain of the query
may be constrained by path expressions.
Identification variables designate instances of a particular entity abstract schema type. The FROM
clause can contain multiple identification variable declarations separated by a comma (,).
from_clause ::=
FROM identification_variable_declaration
{, {identification_variable_declaration | collection_member_declaration}}*
identification_variable_declaration ::= range_variable_declaration { join | fetch_join }*
range_variable_declaration ::= abstract_schema_name [AS] identification_variable
join ::= join_spec join_association_path_expression [AS] identification_variable
fetch_join ::= join_spec FETCH join_association_path_expression
join_association_path_expression ::= join_collection_valued_path_expression |
join_single_valued_association_path_expression
join_spec::= [ LEFT [OUTER] | INNER ] JOIN
collection_member_declaration ::=
IN (collection_valued_path_expression) [AS] identification_variable
The following subsections discuss the constructs used in the FROM clause.
4.4.1 Identifiers
An identifier is a character sequence of unlimited length. The character sequence must begin with a Java
identifier start character, and all other characters must be Java identifier part characters. An identifier
start character is any character for which the method Character.isJavaIdentifierStart
returns true. This includes the underscore (_) character and the dollar sign ($) character. An identifier
part character is any character for which the method Character.isJavaIdentifierPart
returns true. The question mark (?) character is reserved for use by the Java Persistence query language.
The following are reserved identifiers: SELECT, FROM, WHERE, UPDATE, DELETE, JOIN, OUTER,
INNER, LEFT, GROUP, BY, HAVING, FETCH, DISTINCT, OBJECT, NULL, TRUE, FALSE, NOT,
AND, OR, BETWEEN, LIKE, IN, AS, UNKNOWN[40], EMPTY, MEMBER, OF, IS, AVG, MAX, MIN,
SUM, COUNT, ORDER, BY, ASC, DESC, MOD, UPPER, LOWER, TRIM, POSITION,
CHARACTER_LENGTH, CHAR_LENGTH, BIT_LENGTH, CURRENT_TIME, CURRENT_DATE,
CURRENT_TIMESTAMP, NEW, EXISTS, ALL, ANY, SOME.
Reserved identifiers are case insensitive. Reserved identifiers must not be used as identification vari-
ables.
It is recommended that other SQL reserved words also not be as identification variables in
queries because they may be used as reserved identifiers in future releases of this specification.
The FROM Clause and Navigational Declarations Java Persistence 2.0, Early Draft Query Language
All identification variables must be declared in the FROM clause. Identification variables cannot be
declared in other clauses.
An identification variable must not be a reserved identifier or have the same name as any entity in the
same persistence unit:
An identification variable evaluates to a value of the type of the expression used in declaring the vari-
able. For example, consider the previous query:
SELECT DISTINCT o
FROM Order o JOIN o.lineItems l JOIN l.product p
WHERE p.productType = ‘office_supplies’
In the FROM clause declaration o.lineItems l, the identification variable l evaluates to any
LineItem value directly reachable from Order. The association-field lineItems is a collection of
instances of the abstract schema type LineItem and the identification variable l refers to an element
of this collection. The type of l is the abstract schema type of LineItem.
An identification variable ranges over the abstract schema type of an entity. An identification variable
designates an instance of an entity abstract schema type or an element of a collection of entity abstract
schema type instances. Identification variables are existentially quantified in a query.
An identification variable always designates a reference to a single value. It is declared in one of three
ways: in a range variable declaration, in a join clause, or in a collection member declaration. The identi-
fication variable declarations are evaluated from left to right in the FROM clause, and an identification
variable declaration can use the result of a preceding identification variable declaration of the query
string.
The syntax for declaring an identification variable as a range variable is similar to that of SQL; option-
ally, it uses the AS keyword.
Range variable declarations allow the developer to designate a “root” for objects which may not be
reachable by navigation.
In order to select values by comparing more than one instance of an entity abstract schema type, more
than one identification variable ranging over the abstract schema type is needed in the FROM clause.
Query Language Java Persistence 2.0, Early Draft The FROM Clause and Navigational Declarations
The following query returns orders whose quantity is greater than the order quantity for John Smith.
This example illustrates the use of two different identification variables in the FROM clause, both of the
abstract schema type Order. The SELECT clause of this query determines that it is the orders with
quantities larger than John Smith’s that are returned.
SELECT DISTINCT o1
FROM Order o1, Order o2
WHERE o1.quantity > o2.quantity AND
o2.customer.lastname = ‘Smith’ AND
o2.customer.firstname= ‘John’
An identification variable followed by the navigation operator (.) and a state-field or association-field
is a path expression. The type of the path expression is the type computed as the result of navigation;
that is, the type of the state-field or association-field to which the expression navigates.
Depending on navigability, a path expression that leads to a association-field may be further composed.
Path expressions can be composed from other path expressions if the original path expression evaluates
to a single-valued type (not a collection) corresponding to a association-field.
Path expression navigability is composed using “inner join” semantics. That is, if the value of a non-ter-
minal association-field in the path expression is null, the path is considered to have no value, and does
not participate in the determination of the result.
The syntax for single-valued path expressions and collection valued path expressions is as follows:
single_valued_path_expression ::=
state_field_path_expression | single_valued_association_path_expression
state_field_path_expression ::=
{identification_variable | single_valued_association_path_expression}.state_field
single_valued_association_path_expression ::=
identification_variable.{single_valued_association_field.}*single_valued_association_field
collection_valued_path_expression ::=
identification_variable.{single_valued_association_field.}*collection_valued_association_field
state_field ::= {embedded_class_state_field.}*simple_state_field
An embedded_class_state _field is designated by the name of an entity state field that corresponds to an
embedded class.
Navigation to a related entity results in a value of the related entity’s abstract schema type.
The FROM Clause and Navigational Declarations Java Persistence 2.0, Early Draft Query Language
The evaluation of a path expression terminating in a state-field results in the abstract schema type corre-
sponding to the Java type designated by the state-field.
It is syntactically illegal to compose a path expression from a path expression that evaluates to a collec-
tion. For example, if o designates Order, the path expression o.lineItems.product is illegal
since navigation to lineItems results in a collection. This case should produce an error when the
query string is verified. To handle such a navigation, an identification variable must be declared in the
FROM clause to range over the elements of the lineItems collection. Another path expression must
be used to navigate over each such element in the WHERE clause of the query, as in the following:
4.4.5 Joins
An inner join may be implicitly specified by the use of a cartesian product in the FROM clause and a
join condition in the WHERE clause. In the absence of a join condition, this reduces to the cartesian
product.
The main use case for this generalized style of join is when a join condition does not involve a foreign
key relationship that is mapped to an entity relationship.
Example:
In general, use of this style of inner join (also referred to as theta-join) is less typical than explicitly
defined joins over entity relationships.
The following inner and outer join operation types are supported.
For example, the query below joins over the relationship between customers and orders. This type of
join typically equates to a join over a foreign key relationship in the database.
Query Language Java Persistence 2.0, Early Draft The FROM Clause and Navigational Declarations
This is equivalent to the following query using the earlier IN construct, defined in [7]. It selects those
customers of status 1 for which at least one order exists:
For example:
An important use case for LEFT JOIN is in enabling the prefetching of related data items as a side effect
of a query. This is accomplished by specifying the LEFT JOIN as a FETCH JOIN.
The association referenced by the right side of the FETCH JOIN clause must be an association that
belongs to an entity that is returned as a result of the query. It is not permitted to specify an identifica-
tion variable for the entities referenced by the right side of the FETCH JOIN clause, and hence refer-
ences to the implicitly fetched entities cannot appear elsewhere in the query.
The following query returns a set of departments. As a side effect, the associated employees for those
departments are also retrieved, even though they are not part of the explicit query result. The persistent
fields or properties of the employees that are eagerly fetched are fully initialized. The initialization of
the relationship properties of the employees that are retrieved is determined by the metadata for the
Employee entity class.
SELECT d
FROM Department d LEFT JOIN FETCH d.employees
WHERE d.deptno = 1
The FROM Clause and Navigational Declarations Java Persistence 2.0, Early Draft Query Language
A fetch join has the same join semantics as the corresponding inner or outer join, except that the related
objects specified on the right-hand side of the join operation are not returned in the query result or oth-
erwise referenced in the query. Hence, for example, if department 1 has five employees, the above query
returns five references to the department 1 entity.
An identification variable of a collection member declaration is declared using a special operator, the
reserved identifier IN. The argument to the IN operator is a collection-valued path expression. The path
expression evaluates to a collection type specified as a result of navigation to a collection-valued associ-
ation-field of an entity abstract schema type.
collection_member_declaration ::=
IN (collection_valued_path_expression) [AS] identification_variable
SELECT DISTINCT o
FROM Order o JOIN o.lineItems l JOIN l.product p
WHERE p.productType = ‘office_supplies’
SELECT DISTINCT o
FROM Order o, IN(o.lineItems) l
WHERE l.product.productType = ‘office_supplies’
The Java Persistence query language treats the FROM clause similarly to SQL in that the declared iden-
tification variables affect the results of the query even if they are not used in the WHERE clause. Appli-
cation developers should use caution in defining identification variables because the domain of the
query can depend on whether there are any values of the declared type.
For example, the FROM clause below defines a query over all orders that have line items and existing
products. If there are no Product instances in the database, the domain of the query is empty and no
order is selected.
SELECT o
FROM Order AS o, IN(o.lineItems) l, Product p
4.4.8 Polymorphism
Java Persistence queries are automatically polymorphic. The FROM clause of a query designates not
only instances of the specific entity class(es) to which explicitly refers but of subclasses as well. The
instances returned by a query include instances of the subclasses that satisfy the query criteria.[41]
The WHERE clause of a query consists of a conditional expression used to select objects or values that
satisfy the expression. The WHERE clause restricts the result of a select statement or the scope of an
update or delete operation.
The GROUP BY construct enables the aggregation of values according to the properties of an entity
class. The HAVING construct enables conditions to be specified that further restrict the query result as
restrictions upon the groups.
The GROUP BY and HAVING constructs are further discussed in Section 4.7.
The following sections describe the language constructs that can be used in a conditional expression of
the WHERE clause or HAVING clause.
State-fields that are mapped in serialized form or as lobs may not be portably used in condi-
tional expressions[42].
[41] Such query polymorphism does not apply to EJB 2.1 entity beans, since they do not support inheritance.
[42] The implementation is not expected to perform such query operations involving such fields in memory rather than in the database.
4.6.1 Literals
A string literal is enclosed in single quotes—for example: ‘literal’. A string literal that includes a single
quote is represented by two single quotes—for example: ‘literal’’s’. String literals in queries, like Java
String literals, use unicode character encoding. The use of Java escape notation is not supported in
query string literals
Exact numeric literals support the use of Java integer literal syntax as well as SQL exact numeric literal
syntax.
Approximate literals support the use Java floating point literal syntax as well as SQL approximate
numeric literal syntax.
Enum literals support the use of Java enum literal syntax. The enum class name must be specified.
Appropriate suffixes may be used to indicate the specific type of a numeric literal in accordance with
the Java Language Specification. Support for the use of hexadecimal and octal numeric literals is not
required by this specification.
Although predefined reserved literals appear in upper case, they are case insensitive.
All identification variables used in the WHERE or HAVING clause of a SELECT or DELETE state-
ment must be declared in the FROM clause, as described in Section 4.4.2. The identification variables
used in the WHERE clause of an UPDATE statement must be declared in the UPDATE clause.
Identification variables are existentially quantified in the WHERE and HAVING clause. This means
that an identification variable represents a member of a collection or an instance of an entity’s abstract
schema type. An identification variable never designates a collection in its entirety.
Either positional or named parameters may be used. Positional and named parameters may not be mixed
in a single query.
Input parameters can only be used in the WHERE clause or HAVING clause of a query.
Note that if an input parameter value is null, comparison operations or arithmetic operations
involving the input parameter will return an unknown value. See Section 4.11.
• Input parameters are designated by the question mark (?) prefix followed by an integer. For
example: ?1.
Example:
SELECT c
FROM Customer c
WHERE c.status = :stat
Section 3.6.1 describes the API for the binding of named query parameters.
Conditional expressions are composed of other conditional expressions, comparison operations, logical
operations, path expressions that evaluate to boolean values, boolean literals, and boolean input param-
eters.
Arithmetic expressions can be used in comparison expressions. Arithmetic expressions are composed of
other arithmetic expressions, arithmetic operations, path expressions that evaluate to numeric values,
numeric literals, and numeric input parameters.
between_expression |
like_expression |
in_expression |
null_comparison_expression |
empty_collection_comparison_expression |
collection_member_expression |
exists_expression
Aggregate functions can only be used in conditional expressions in a HAVING clause. See section 4.7.
• Arithmetic operators:
+, - unary
*, / multiplication and division
+, - addition and subtraction
• Comparison operators : =, >, >=, <, <=, <> (not equal), [NOT] BETWEEN, [NOT] LIKE,
[NOT] IN, IS [NOT] NULL, IS [NOT] EMPTY, [NOT] MEMBER [OF]
• Logical operators:
NOT
AND
OR
The syntax for the use of the comparison operator [NOT] BETWEEN in a conditional expression is as
follows:
x BETWEEN y AND z
The rules for unknown and NULL values in comparison operations apply. See Section 4.11.
Examples are:
4.6.8 In Expressions
The syntax for the use of the comparison operator [NOT] IN in a conditional expression is as follows:
in_expression ::=
state_field_path_expression [NOT] IN ( in_item {, in_item}* | subquery)
in_item ::= literal | input_parameter
The literal and/or input_parameter values must be like the same abstract schema type of the
state_field_path_expression in type. (See Section 4.12).
The results of the subquery must be like the same abstract schema type of the
state_field_path_expression in type. Subqueries are discussed in Section 4.6.15, “Subqueries”.
Examples are:
o.country IN (’UK’, ’US’, ’France’) is true for UK and false for Peru, and is equivalent
to the expression (o.country = ’UK’) OR (o.country = ’US’) OR (o.country = ’
France’).
o.country NOT IN (’UK’, ’US’, ’France’) is false for UK and true for Peru, and is
equivalent to the expression NOT ((o.country = ’UK’) OR (o.country = ’US’) OR
(o.country = ’France’)).
There must be at least one element in the comma separated list that defines the set of values for the IN
expression.
The syntax for the use of the comparison operator [NOT] LIKE in a conditional expression is as fol-
lows:
The string_expression must have a string value. The pattern_value is a string literal or a string-valued
input parameter in which an underscore (_) stands for any single character, a percent (%) character
stands for any sequence of characters (including the empty sequence), and all other characters stand for
themselves. The optional escape_character is a single-character string literal or a character-valued
input parameter (i.e., char or Character) and is used to escape the special meaning of the under-
score and percent characters in pattern_value.[43]
Examples are:
• address.phone LIKE ‘12%3’ is true for ‘123’ ‘12993’ and false for ‘1234’
• asentence.word LIKE ‘l_se’ is true for ‘lose’ and false for ‘loose’
• aword.underscored LIKE ‘\_%’ ESCAPE ‘\’ is true for ‘_foo’ and false for ‘bar’
• address.phone NOT LIKE ‘12%3’ is false for ‘123’ and ‘12993’ and true for ‘1234’
If the value of the string_expression or pattern_value is NULL or unknown, the value of the LIKE
expression is unknown. If the escape_character is specified and is NULL, the value of the LIKE expres-
sion is unknown.
The syntax for the use of the comparison operator IS NULL in a conditional expression is as follows:
A null comparison expression tests whether or not the single-valued path expression or input parameter
is a NULL value.
This expression tests whether or not the collection designated by the collection-valued path expression
is empty (i.e, has no elements).
Example:
SELECT o
FROM Order o
WHERE o.lineItems IS EMPTY
If the value of the collection-valued path expression in an empty collection comparison expression is
unknown, the value of the empty comparison expression is unknown.
This expression tests whether the designated value is a member of the collection specified by the collec-
tion-valued path expression.
If the collection valued path expression designates an empty collection, the value of the MEMBER OF
expression is FALSE and the value of the NOT MEMBER OF expression is TRUE. Otherwise, if the
value of the collection-valued path expression or single-valued association-field path expression in the
collection member expression is NULL or unknown, the value of the collection member expression is
unknown.
Example:
The result of this query consists of all employees whose spouses are also employees.
An ANY conditional expression is a predicate that is true if the comparison operation is true for some
value in the result of the subquery. An ANY conditional expression is false if the result of the subquery
is empty or if the comparison operation is false for every value in the result of the subquery, and is
unknown if neither true nor false. The keyword SOME is synonymous with ANY.
The comparison operators used with ALL or ANY conditional expressions are =, <, <=, >, >=, <>. The
result of the subquery must be like that of the other argument to the comparison operator in type. See
Section 4.12.
Example:
SELECT emp
FROM Employee emp
WHERE emp.salary > ALL (
SELECT m.salary
FROM Manager m
WHERE m.department = emp.department)
4.6.15 Subqueries
Subqueries may be used in the WHERE or HAVING clause.[45]
[45] Subqueries are restricted to the WHERE and HAVING clauses in this release. Support for subqueries in the FROM clause will be
considered in a later release of this specification.
[groupby_clause] [having_clause]
simple_select_clause ::= SELECT [DISTINCT] simple_select_expression
subquery_from_clause ::=
FROM subselect_identification_variable_declaration
{, subselect_identification_variable_declaration}*
subselect_identification_variable_declaration ::=
identification_variable_declaration |
association_path_expression [AS] identification_variable |
collection_member_declaration
simple_select_expression::=
single_valued_path_expression |
aggregate_expression |
identification_variable
Examples:
SELECT c
FROM Customer c
WHERE (SELECT COUNT(o) FROM c.orders o) > 10
Note that some contexts in which a subquery can be used require that the subquery be a scalar subquery
(i.e., produce a single result). This is illustrated in the following example involving a numeric compari-
son operation.
SELECT goodCustomer
FROM Customer goodCustomer
WHERE goodCustomer.balanceOwed < (
SELECT avg(c.balanceOwed) FROM Customer c)
The Java Persistence query language includes the following built-in functions, which may be used in the
WHERE or HAVING clause of a query.
If the value of any argument to a functional expression is null or unknown, the value of the functional
expression is unknown.
functions_returning_strings ::=
CONCAT(string_primary, string_primary) |
SUBSTRING(string_primary,
simple_arithmetic_expression, simple_arithmetic_expression) |
TRIM([[trim_specification] [trim_character] FROM] string_primary) |
LOWER(string_primary) |
UPPER(string_primary)
trim_specification ::= LEADING | TRAILING | BOTH
functions_returning_numerics::=
LENGTH(string_primary) |
LOCATE(string_primary, string_primary[, simple_arithmetic_expression]) |
The second and third arguments of the SUBSTRING function denote the starting position and length of
the substring to be returned. These arguments are integers. The first position of a string is denoted by 1.
The SUBSTRING function returns a string.
The TRIM function trims the specified character from a string. If the character to be trimmed is not
specified, it is assumed to be space (or blank). The optional trim_character is a single-character string
literal or a character-valued input parameter (i.e., char or Character)[46]. If a trim specification is
not provided, BOTH is assumed. The TRIM function returns the trimmed string.
The LOWER and UPPER functions convert a string to lower and upper case, respectively. They return a
string.
The LOCATE function returns the position of a given string within a string, starting the search at a spec-
ified position. It returns the first position at which the string was found as an integer. The first argument
is the string to be located; the second argument is the string to be searched; the optional third argument
is an integer that represents the string position at which the search is started (by default, the beginning of
the string to be searched). The first position in a string is denoted by 1. If the string is not found, 0 is
returned.[47]
The LENGTH function returns the length of the string in characters as an integer.
functions_returning_numerics::=
ABS(simple_arithmetic_expression) |
SQRT(simple_arithmetic_expression) |
MOD(simple_arithmetic_expression, simple_arithmetic_expression) |
SIZE(collection_valued_path_expression)
The ABS function takes a numeric argument and returns a number (integer, float, or double) of the same
type as the argument to the function.
[46] Note that not all databases support the use of a trim character other than the space character; use of this argument may result in
queries that are not portable.
[47] Note that not all databases support the use of the third argument to LOCATE; use of this argument may result in queries that are
not portable.
Query Language Java Persistence 2.0, Early Draft GROUP BY, HAVING
The MOD function takes two integer arguments and returns an integer.
The SIZE function returns an integer value, the number of elements of the collection. If the collection is
empty, the SIZE function evaluates to zero.
Numeric arguments to these functions may correspond to the numeric Java object types as well as the
primitive numeric types.
functions_returning_datetime:=
CURRENT_DATE |
CURRENT_TIME |
CURRENT_TIMESTAMP
The datetime functions return the value of current date, time, and timestamp on the database server.
The GROUP BY construct enables the aggregation of values according to a set of properties. The HAV-
ING construct enables conditions to be specified that further restrict the query result. Such conditions
are restrictions upon the groups.
If a query contains both a WHERE clause and a GROUP BY clause, the effect is that of first applying
the where clause, and then forming the groups and filtering them according to the HAVING clause. The
HAVING clause causes those groups to be retained that satisfy the condition of the HAVING clause.
The requirements for the SELECT clause when GROUP BY is used follow those of SQL: namely, any
item that appears in the SELECT clause (other than as an argument to an aggregate function) must also
appear in the GROUP BY clause. In forming the groups, null values are treated as the same for group-
ing purposes.
Grouping by an entity is permitted. In this case, the entity must contain no serialized state fields or
lob-valued state fields.
The HAVING clause must specify search conditions over the grouping items or aggregate functions that
apply to grouping items.
If there is no GROUP BY clause and the HAVING clause is used, the result is treated as a single group,
and the select list can only consist of aggregate functions. The use of HAVING in the absence of
GROUP BY is not required to be supported by an implementation of this specification. Portable appli-
cations should not rely on HAVING without the use of GROUP BY.
Examples:
The SELECT clause denotes the query result. More than one value may be returned from the SELECT
clause of a query.
The SELECT clause may contain one or more of the following elements: a single range variable or
identification variable that ranges over an entity abstract schema type, a single-valued path expression,
an aggregate select expression, a constructor expression.
For example:
Note that the SELECT clause must be specified to return only single-valued expressions. The query
below is therefore not valid:
The DISTINCT keyword is used to specify that duplicate values must be eliminated from the query
result. If DISTINCT is not specified, duplicate values are not eliminated.
Standalone identification variables in the SELECT clause may optionally be qualified by the OBJECT
operator. The SELECT clause must not use the OBJECT operator to qualify path expressions.
The type of the query result specified by the SELECT clause of a query is an entity abstract schema
type, a state-field type, the result of an aggregate function, the result of a construction operation, or
some sequence of these.
The result type of the SELECT clause is defined by the the result types of the select_expressions con-
tained in it. When multiple select_expressions are used in the SELECT clause, the result of the query
is of type Object[], and the elements in this result correspond in order to the order of their specifica-
tion in the SELECT clause and in type to the result types of each of the select_expressions.
• A single_valued_path_expression that is a
single_valued_association_path_expression results in an entity object of the type of the
relationship field or the subtype of the relationship field of the entity object as determined by
the object/relational mapping.
• The result type of an identification_variable is the type of the entity to which that identifica-
tion variable corresponds or a subtype as determined by the object/relational mapping.
• The result type of a constructor_expression is the type of the class for which the constructor
is defined. The types of the arguments to the constructor are defined by the above rules.
A constructor may be used in the SELECT list to return one or more Java instances. The specified class
is not required to be an entity or to be mapped to the database. The constructor name must be fully qual-
ified.
If an entity class name is specified in the SELECT NEW clause, the resulting entity instances are in the
new state.
If the result of a query corresponds to a association-field or state-field whose value is null, that null
value is returned in the result of the query method. The IS NOT NULL construct can be used to elimi-
nate such null values from the result set of the query.
Note, however, that state-field types defined in terms of Java numeric primitive types cannot produce
NULL values in the query result. A query that returns such a state-field type as a result type must not
return a null value.
The following aggregate functions can be used in the SELECT clause of a query: AVG, COUNT, MAX,
MIN, SUM.
For all aggregate functions except COUNT, the path expression that is the argument to the aggregate
function must terminate in a state-field. The path expression argument to COUNT may terminate in
either a state-field or a association-field, or the argument to COUNT may be an identification variable.
Arguments to the functions SUM and AVG must be numeric. Arguments to the functions MAX and
MIN must correspond to orderable state-field types (i.e., numeric types, string types, character types, or
date types).
The Java type that is contained in the result of a query using an aggregate function is as follows:
• MAX, MIN return the type of the state-field to which they are applied.
• SUM returns Long when applied to state-fields of integral types (other than BigInteger); Dou-
ble when applied to state-fields of floating point types; BigInteger when applied to state-fields
of type BigInteger; and BigDecimal when applied to state-fields of type BigDecimal.
If SUM, AVG, MAX, or MIN is used, and there are no values to which the aggregate function can be
applied, the result of the aggregate function is NULL.
If COUNT is used, and there are no values to which COUNT can be applied, the result of the aggregate
function is 0.
The argument to an aggregate function may be preceded by the keyword DISTINCT to specify that
duplicate values are to be eliminated before the aggregate function is applied.[48]
Null values are eliminated before the aggregate function is applied, regardless of whether the keyword
DISTINCT is specified.
4.8.4.1 Examples
The following query returns the total cost of the items that John Smith has ordered.
SELECT SUM(l.price)
FROM Order o JOIN o.lineItems l JOIN o.customer c
WHERE c.lastname = ‘Smith’ AND c.firstname = ‘John’
SELECT COUNT(o)
FROM Order o
The following query counts the number of items in John Smith’s order for which prices have been spec-
ified.
SELECT COUNT(l.price)
FROM Order o JOIN o.lineItems l JOIN o.customer c
WHERE c.lastname = ‘Smith’ AND c.firstname = ‘John’
SELECT COUNT(l)
FROM Order o JOIN o.lineItems l JOIN o.customer c
WHERE c.lastname = ‘Smith’ AND c.firstname = ‘John’
AND l.price IS NOT NULL
The ORDER BY clause allows the objects or values that are returned by the query to be ordered.
[48] It is legal to specify DISTINCT with MAX or MIN, but it does not affect the result.
When the ORDER BY clause is used in a query, each element of the SELECT clause of the query must
be one of the following:
2. a single_valued_association_path_expression
3. a state_field_path_expression
In the first two cases, each orderby_item must be an orderable state-field of the entity abstract schema
type value returned by the SELECT clause. In the third case, the orderby_item must evaluate to the same
state-field of the same entity abstract schema type as the state_field_path_expression in the SELECT
clause.
For example, the first two queries below are legal, but the third and fourth are not.
SELECT o
FROM Customer c JOIN c.orders o JOIN c.address a
WHERE a.state = ‘CA’
ORDER BY o.quantity, o.totalcost
The following two queries are not legal because the orderby_item is not reflected in the SELECT clause
of the query.
SELECT p.product_name
FROM Order o JOIN o.lineItems l JOIN l.product p JOIN o.customer c
WHERE c.lastname = ‘Smith’ AND c.firstname = ‘John’
ORDER BY p.price
SELECT p.product_name
FROM Order o, IN(o.lineItems) l JOIN o.customer c
WHERE c.lastname = ‘Smith’ AND c.firstname = ‘John’
ORDER BY o.quantity
If more than one orderby_item is specified, the left-to-right sequence of the orderby_item elements
determines the precedence, whereby the leftmost orderby_item has highest precedence.
The keyword ASC specifies that ascending ordering be used; the keyword DESC specifies that descend-
ing ordering be used. Ascending ordering is the default.
SQL rules for the ordering of null values apply: that is, all null values must appear before all non-null
values in the ordering or all null values must appear after all non-null values in the ordering, but it is not
specified which.
The ordering of the query result is preserved in the result of the query method if the ORDER BY clause
is used.
Query Language Java Persistence 2.0, Early Draft Bulk Update and Delete Operations
Bulk update and delete operations apply to entities of a single entity class (together with its subclasses,
if any). Only one entity abstract schema type may be specified in the FROM or UPDATE clause.
A delete operation only applies to entities of the specified class and its subclasses. It does not cascade to
related entities.
The new_value specified for an update operation must be compatible in type with the state-field to
which it is assigned.
Bulk update maps directly to a database update operation, bypassing optimistic locking checks. Portable
applications must manually update the value of the version column, if desired, and/or manually validate
the value of the version column.
The persistence context is not synchronized with the result of the bulk update or delete.
Caution should be used when executing bulk update or delete operations because they may result in
inconsistencies between the database and the entities in the active persistence context. In general, bulk
update and delete operations should only be performed within a separate transaction or at the begin-
ning of a transaction (before entities have been accessed whose state might be affected by such opera-
tions).
Examples:
DELETE
FROM Customer c
WHERE c.status = ‘inactive’
DELETE
FROM Customer c
WHERE c.status = ‘inactive’
AND c.orders IS EMPTY
UPDATE customer c
SET c.status = ‘outstanding’
WHERE c.balance < 10000
AND 1000 > (SELECT COUNT(o)
FROM customer cust JOIN cust.order o)
When the target of a reference does not exist in the database, its value is regarded as NULL. SQL NULL
semantics [4] defines the evaluation of conditional expressions containing NULL values.
• Comparison or arithmetic operations with a NULL value always yield an unknown value.
• Two NULL values are not considered to be equal, the comparison yields an unknown value.
• Comparison or arithmetic operations with an unknown value always yield an unknown value.
• The IS NULL and IS NOT NULL operators convert a NULL state-field or single-valued asso-
ciation-field value into the respective TRUE or FALSE value.
• Boolean operators use three valued logic, defined by Table 1, Table 2, and Table 3.
AND T F U
T T F U
F F F F
U U F U
Query Language Java Persistence 2.0, Early Draft Equality and Comparison Semantics
OR T F U
T T T T
F T F U
U T U U
NOT
T F
F T
U U
Note: The Java Persistence query language defines the empty string, ‘’, as a string with 0 length, which
is not equal to a NULL value. However, NULL values and empty strings may not always be distin-
guished when queries are mapped to some databases. Application developers should therefore not rely
on the semantics of query comparisons involving the empty string and NULL value.
Only the values of like types are permitted to be compared. A type is like another type if they corre-
spond to the same Java language type, or if one is a primitive Java language type and the other is the
wrappered Java class type equivalent (e.g., int and Integer are like types in this sense). There is one
exception to this rule: it is valid to compare numeric values for which the rules of numeric promotion
apply. Conditional expressions attempting to compare non-like type values are disallowed except for
this numeric case.
Note that the arithmetic operators and comparison operators are permitted to be applied to
state-fields and input parameters of the wrappered Java class equivalents to the primitive
numeric Java types.
Two entities of the same abstract schema type are equal if and only if they have the same primary key
value.
4.13 Examples
The following examples illustrate the syntax and semantics of the Java Persistence query language.
These examples are based on the example presented in Section 4.3.2.
SELECT o
FROM Order o
SELECT o
FROM Order o
WHERE o.shippingAddress.state = ‘CA’
SELECT DISTINCT o
FROM Order o, IN(o.lineItems) l
Note that the result of this query does not include orders with no associated line items. This query can
also be written as:
SELECT o
FROM Order o
WHERE o.lineItems IS NOT EMPTY
SELECT o
FROM Order o
WHERE o.lineItems IS EMPTY
SELECT DISTINCT o
FROM Order o JOIN o.lineItems l
WHERE l.shipped = FALSE
Find all orders in which the shipping address differs from the billing address. This example assumes
that the application developer uses two distinct entity types to designate shipping and billing addresses,
as in Figure 1.
SELECT o
FROM Order o
WHERE
NOT (o.shippingAddress.state = o.billingAddress.state AND
o.shippingAddress.city = o.billingAddress.city AND
o.shippingAddress.street = o.billingAddress.street)
If the application developer uses a single entity in two different relationships for both the shipping
address and the billing address, the above expression can be simplified based on the equality rules
defined in Section 4.12. The query can then be written as:
SELECT o
FROM Order o
WHERE o.shippingAddress <> o.billingAddress
The query checks whether the same entity abstract schema type instance (identified by its primary key)
is related to an order through two distinct relationships.
Find all orders for a book titled ‘Applying Enterprise JavaBeans: Component-Based Development for
the J2EE Platform’:
SELECT DISTINCT o
FROM Order o JOIN o.lineItems l
WHERE l.product.type = ‘book’ AND
l.product.name = ‘Applying Enterprise JavaBeans:
Component-Based Development for the J2EE Platform’
The following query finds the orders for a product whose name is designated by an input parameter:
SELECT DISTINCT o
FROM Order o, IN(o.lineItems) l
WHERE l.product.name = ?1
For this query, the input parameter must be of the type of the state-field name, i.e., a string.
4.14 BNF
• { ... } grouping
• boldface keywords
• * zero or more
• | alternates
The following is the BNF for the Java Persistence query language.
boolean_primary |
enum_primary
simple_entity_expression |
NULL
delete_clause ::= DELETE FROM abstract_schema_name [[AS] identification_variable]
select_clause ::= SELECT [DISTINCT] select_expression {, select_expression}*
select_expression ::=
single_valued_path_expression |
aggregate_expression |
identification_variable |
OBJECT(identification_variable) |
constructor_expression
constructor_expression ::=
NEW constructor_name ( constructor_item {, constructor_item}* )
constructor_item ::= single_valued_path_expression | aggregate_expression
aggregate_expression ::=
{ AVG | MAX | MIN | SUM } ([DISTINCT] state_field_path_expression) |
COUNT ([DISTINCT] identification_variable | state_field_path_expression |
single_valued_association_path_expression)
where_clause ::= WHERE conditional_expression
groupby_clause ::= GROUP BY groupby_item {, groupby_item}*
groupby_item ::= single_valued_path_expression | identification_variable
having_clause ::= HAVING conditional_expression
orderby_clause ::= ORDER BY orderby_item {, orderby_item}*
orderby_item ::= state_field_path_expression [ ASC | DESC ]
subquery ::= simple_select_clause subquery_from_clause [where_clause]
[groupby_clause] [having_clause]
subquery_from_clause ::=
FROM subselect_identification_variable_declaration
{, subselect_identification_variable_declaration}*
subselect_identification_variable_declaration ::=
identification_variable_declaration |
association_path_expression [AS] identification_variable |
collection_member_declaration
simple_select_clause ::= SELECT [DISTINCT] simple_select_expression
simple_select_expression::=
single_valued_path_expression |
aggregate_expression |
identification_variable
conditional_expression ::= conditional_term | conditional_expression OR conditional_term
conditional_term ::= conditional_factor | conditional_term AND conditional_factor
conditional_factor ::= [ NOT ] conditional_primary
conditional_primary ::= simple_cond_expression | (conditional_expression)
simple_cond_expression ::=
comparison_expression |
between_expression |
like_expression |
in_expression |
null_comparison_expression |
empty_collection_comparison_expression |
collection_member_expression |
exists_expression
between_expression ::=
arithmetic_expression [NOT] BETWEEN
arithmetic_expression AND arithmetic_expression |
string_expression [NOT] BETWEEN string_expression AND string_expression |
datetime_expression [NOT] BETWEEN
datetime_expression AND datetime_expression
in_expression ::=
state_field_path_expression [NOT] IN ( in_item {, in_item}* | subquery)
in_item ::= literal | input_parameter
like_expression ::=
string_expression [NOT] LIKE pattern_value [ESCAPE escape_character]
null_comparison_expression ::=
{single_valued_path_expression | input_parameter} IS [NOT] NULL
empty_collection_comparison_expression ::=
collection_valued_path_expression IS [NOT] EMPTY
collection_member_expression ::= entity_expression
[NOT] MEMBER [OF] collection_valued_path_expression
exists_expression::= [NOT] EXISTS (subquery)
all_or_any_expression ::= { ALL | ANY | SOME} (subquery)
comparison_expression ::=
string_expression comparison_operator {string_expression | all_or_any_expression} |
boolean_expression { =|<>} {boolean_expression | all_or_any_expression} |
enum_expression { =|<>} {enum_expression | all_or_any_expression} |
datetime_expression comparison_operator
{datetime_expression | all_or_any_expression} |
entity_expression { = | <> } {entity_expression | all_or_any_expression} |
arithmetic_expression comparison_operator
{arithmetic_expression | all_or_any_expression}
comparison_operator ::= = | > | >= | < | <= | <>
arithmetic_expression ::= simple_arithmetic_expression | (subquery)
simple_arithmetic_expression ::=
arithmetic_term | simple_arithmetic_expression { + | - } arithmetic_term
arithmetic_term ::= arithmetic_factor | arithmetic_term { * | / } arithmetic_factor
arithmetic_factor ::= [{ + | - }] arithmetic_primary
arithmetic_primary ::=
state_field_path_expression |
numeric_literal |
(simple_arithmetic_expression) |
input_parameter |
functions_returning_numerics |
aggregate_expression
string_expression ::= string_primary | (subquery)
string_primary ::=
state_field_path_expression |
string_literal |
input_parameter |
functions_returning_strings |
aggregate_expression
Persistence Contexts Java Persistence 2.0, Early Draft Entity Managers and Persistence Contexts
A persistence context is a set of managed entity instances in which for any persistent entity identity
there is a unique entity instance. Within the persistence context, the entity instances and their lifecycle
are managed by the entity manager.
In Java EE environments, a JTA transaction typically involves calls across multiple components. Such
components may often need to access the same persistence context within a single transaction. To facil-
itate such use of entity managers in Java EE environments, when an entity manager is injected into a
component or looked up directly in the JNDI naming context, its persistence context will automatically
be propagated with the current JTA transaction, and the EntityManager references that are mapped to
the same persistence unit will provide access to this same persistence context within the JTA transac-
tion. This propagation of persistence context by the Java EE container avoids the need for the applica-
tion to pass references to EntityManager instances from one component to another. An entity manager
for which the container manages the persistence context in this manner is termed a container-managed
entity manager. A container-managed entity manager’s lifecycle is managed by the Java EE container.
Entity Managers and Persistence Contexts Java Persistence 2.0, Early Draft Obtaining an EntityManager
In less common use cases within Java EE environments, applications may need to access a persistence
context that is “stand-alone”—i.e. not propagated along with the JTA transaction across the EntityMan-
ager references for the given persistence unit. Instead, each instance of creating an entity manager
causes a new isolated persistence context to be created that is not accessible through other EntityMan-
ager references within the same transaction. These use cases are supported through the createEnti-
tyManager methods of the EntityManagerFactory interface. An entity manager that is used by
the application to create and destroy a persistence context in this manner is termed an application-man-
aged entity manager. An application-managed entity manager’s lifecycle is managed by the application.
Both container-managed entity managers and application-managed entity managers and their persis-
tence contexts are required to be supported in Java EE web containers and EJB containers. Within an
EJB environment, container-managed entity managers are typically used.
In Java SE environments and in Java EE application client containers, only application-managed entity
managers are required to be supported[49].
The entity manager for a persistence context is obtained from an entity manager factory.
When container-managed entity managers are used (in Java EE environments), the application does not
interact with the entity manager factory. The entity managers are obtained directly through dependency
injection or from JNDI, and the container manages interaction with the entity manager factory transpar-
ently to the application.
When application-managed entity managers are used, the application must use the entity manager fac-
tory to manage the entity manager and persistence context lifecycle.
An entity manager may not be shared among multiple concurrently executing threads. Entity managers
may only be accessed in a single-threaded manner.
The PersistenceContext annotation is used for entity manager injection. The type element
specifies whether a transaction-scoped or extended persistence context is to be used, as described in sec-
tion 5.6. The unitName element may optionally be specified to designate the persistence unit whose
factory is used by the container. (See section 8.4.2).
[49] Note that the use of JTA is not required to be supported in application client containers.
Obtaining an Entity Manager Factory Java Persistence 2.0, Early Draft Entity Managers and Persistence Contexts
For example,
@PersistenceContext
EntityManager em;
@PersistenceContext(type=PersistenceContextType.EXTENDED)
EntityManager orderEM;
@Stateless
@PersistenceContext(name="OrderEM")
public class MySessionBean implements MyInterface {
@Resource SessionContext ctx;
Each entity manager factory provides entity manager instances that are all configured in the same man-
ner (e.g., configured to connect to the same database, use the same initial settings as defined by the
implementation, etc.).
More than one entity manager factory instance may be available simultaneously in the JVM.[51]
[50] It may also be used internally by the Java EE container. See section 5.9.
[51] This may be the case when using multiple databases, since in a typical configuration a single entity manager only communicates
with a single database. There is only one entity manager factory per persistence unit, however.
Entity Managers and Persistence Contexts Java Persistence 2.0, Early Draft EntityManagerFactory Interface
For example
@PersistenceUnit
EntityManagerFactory emf;
For example,
EntityManagerFactory emf =
javax.persistence.Persistence.createEntityManagerFactory("Order");
EntityManager em = emf.createEntityManager();
EntityManagerFactory Interface Java Persistence 2.0, Early Draft Entity Managers and Persistence Contexts
package javax.persistence;
/**
* Interface used to interact with the entity manager factory
* for the persistence unit.
*/
public interface EntityManagerFactory {
/**
* Create a new EntityManager.
* This method returns a new EntityManager instance each time
* it is invoked.
* The isOpen method will return true on the returned instance.
* @throws IllegalStateException if the entity manager factory
* has been closed.
*/
public EntityManager createEntityManager();
/**
* Create a new EntityManager with the specified Map of
* properties.
* This method returns a new EntityManager instance each time
* it is invoked.
* The isOpen method will return true on the returned instance.
* @throws IllegalStateException if the entity manager factory
* has been closed.
*/
public EntityManager createEntityManager(Map map);
/**
* Close the factory, releasing any resources that it holds.
* After a factory instance is closed, all methods invoked on
* it will throw an IllegalStateException, except for isOpen,
* which will return false. Once an EntityManagerFactory has
* been closed, all its entity managers are considered to be
* in the closed state.
* @throws IllegalStateException if the entity manager factory
* has been closed.
*/
public void close();
/**
* Indicates whether the factory is open. Returns true
* until the factory has been closed.
*/
public boolean isOpen();
/**
* Get the properties and associated values that are in effect
* for the entity manager factory. Changing the contents of the
* map does not change the configuration in effect.
* @return properties
*/
public Map getProperties();
/**
* Get the names of the properties that are supported for use
Entity Managers and Persistence Contexts Java Persistence 2.0, Early Draft Controlling Transactions
/**
* Access the cache that is associated with the entity manager
* factory (the "second level cache").
* @return instance of the Cache interface
* @throws IllegalStateException if the entity manager factory
* has been closed.
*/
public Cache getCache();
}
Any number of vendor-specific properties may be included in the map passed to createEntity-
Manager. Properties that are not recognized by a vendor must be ignored.
Depending on the transactional type of the entity manager, transactions involving EntityManager opera-
tions may be controlled either through JTA or through use of the resource-local EntityTransac-
tion API, which is mapped to a resource transaction over the resource that underlies the entities
managed by the entity manager.
An entity manager whose underlying transactions are controlled through JTA is termed a JTA entity
manager.
An entity manager whose underlying transactions are controlled by the application through the Enti-
tyTransaction API is termed a resource-local entity manager.
A container-managed entity manager must be a JTA entity manager. JTA entity managers are only spec-
ified for use in Java EE containers.
An application-managed entity manager may be either a JTA entity manager or a resource-local entity
manager.
Controlling Transactions Java Persistence 2.0, Early Draft Entity Managers and Persistence Contexts
Both JTA entity managers and resource-local entity managers are required to be supported in Java EE
web containers and EJB containers. Within an EJB environment, a JTA entity manager is typically used.
In general, in Java SE environments only resource-local entity managers are supported.
An entity manager whose transactions are controlled through JTA is a JTA entity manager. A JTA
entity manager participates in the current JTA transaction, which is begun and committed external to the
entity manager and propagated to the underlying resource manager.
When a resource-local entity manager is used, and the persistence provider runtime throws an exception
defined to cause transaction rollback, the persistence provider must mark the transaction for rollback.
Entity Managers and Persistence Contexts Java Persistence 2.0, Early Draft Controlling Transactions
If the EntityTransaction.commit operation fails, the persistence provider must roll back the
transaction.
/**
* Commit the current transaction, writing any unflushed
* changes to the database.
* @throws IllegalStateException if isActive() is false.
* @throws RollbackException if the commit fails.
*/
public void commit();
/**
* Roll back the current transaction.
* @throws IllegalStateException if isActive() is false.
* @throws PersistenceException if an unexpected error
* condition is encountered.
*/
public void rollback();
/**
* Mark the current transaction so that the only possible
* outcome of the transaction is for the transaction to be
* rolled back.
* @throws IllegalStateException if isActive() is false.
*/
public void setRollbackOnly();
/**
* Determine whether the current transaction has been marked
* for rollback.
* @throws IllegalStateException if isActive() is false.
*/
public boolean getRollbackOnly();
/**
* Indicate whether a transaction is in progress.
* @throws PersistenceException if an unexpected error
* condition is encountered.
*/
public boolean isActive();
}
Container-managed Persistence Contexts Java Persistence 2.0, Early Draft Entity Managers and Persistence Contexts
5.5.3 Example
The following example illustrates the creation of an entity manager factory in a Java SE environment,
and its use in creating and using a resource-local entity manager.
import javax.persistence.*;
public class PasswordChanger {
public static void main (String[] args) {
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("Order");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
User user = (User)em.createQuery
("SELECT u FROM User u WHERE u.name=:name AND
u.pass=:pass")
.setParameter("name", args[0])
.setParameter("pass", args[1])
.getSingleResult();
if (user!=null)
user.setPassword(args[2]);
em.getTransaction().commit();
em.close();
emf.close();
}
}
When a container-managed entity manager is used, the lifecycle of the persistence context is always
managed automatically, transparently to the application, and the persistence context is propagated with
the JTA transaction.
A container-managed persistence context may be defined to have either a lifetime that is scoped to a sin-
gle transaction or an extended lifetime that spans multiple transactions, depending on the Persis-
tenceContextType that is specified when its EntityManager is created. This specification refers to
such persistence contexts as transaction-scoped persistence contexts and extended persistence contexts
respectively.
The lifetime of the persistence context is declared using the PersistenceContext annotation or
the persistence-context-ref deployment descriptor element. By default, a transaction-scoped
persistence context is used.
Sections 5.6.1 and 5.6.2 describe transaction-scoped and extended persistence contexts in the absence of
persistence context propagation. Persistence context propagation is described in section 5.6.3.
Entity Managers and Persistence Contexts Java Persistence 2.0, Early Draft Container-managed Persistence Contexts
Persistence contexts are always associated with an entity manager factory. In the following, everywhere
that "the persistence context" appears, it should be understood to mean "the persistence context associ-
ated with a particular entity manager factory".
A new persistence context begins when the container-managed entity manager is invoked[52] in the
scope of an active JTA transaction, and there is no current persistence context already associated with
the JTA transaction. The persistence context is created and then associated with the JTA transaction.
The persistence context ends when the associated JTA transaction commits or rolls back, and all entities
that were managed by the EntityManager become detached.
If the entity manager is invoked outside the scope of a transaction, any entities loaded from the database
will immediately become detached at the end of the method call.
The persistence context is closed by the container when the @Remove method of the stateful session
bean completes (or the stateful session bean instance is otherwise destroyed).
If the persistence context has been inherited by any stateful session beans, the container does not close
the persistence context until all such stateful session beans have been removed or otherwise destroyed.
[52] Specifically, when one of the methods of the EntityManager interface is invoked.
Container-managed Persistence Contexts Java Persistence 2.0, Early Draft Entity Managers and Persistence Contexts
The persistence context is propagated across the entity manager instances as the JTA transaction is
propagated.
Propagation of persistence contexts only applies within a local environment. Persistence contexts are
not propagated to remote tiers.
Persistence contexts are propagated by the container across component invocations as follows.
If a component is called and there is no JTA transaction or the JTA transaction is not propagated, the
persistence context is not propagated.
If a component is called and the JTA transaction is propagated into that component:
• If the component is a stateful session bean to which an extended persistence context has been
bound and there is a different persistence context bound to the JTA transaction, an EJBEx-
ception is thrown by the container.
• Otherwise, if there is a persistence context bound to the JTA transaction, that persistence con-
text is propagated and used.
[53] Entity manager instances obtained from different entity manager factories never share the same persistence context.
Entity Managers and Persistence Contexts Java Persistence 2.0, Early Draft Container-managed Persistence Contexts
5.6.4 Examples
Application-managed Persistence Contexts Java Persistence 2.0, Early Draft Entity Managers and Persistence Contexts
@PersistenceContext(type=EXTENDED)
EntityManager em;
When an application-managed entity manager is used, the application interacts directly with the persis-
tence provider's entity manager factory to manage the entity manager lifecycle and to obtain and destroy
persistence contexts.
All such application-managed persistence contexts are extended in scope, and may span multiple trans-
actions.
The extended persistence context exists from the point at which the entity manager has been created
using EntityManagerFactory.createEntityManager until the entity manager is closed by
means of EntityManager.close. The extended persistence context obtained from the applica-
tion-managed entity manager is a stand-alone persistence context—it is not propagated with the transac-
tion.
Entity Managers and Persistence Contexts Java Persistence 2.0, Early Draft Application-managed Persistence Contexts
When a JTA application-managed entity manager is used, if the entity manager is created outside the
scope of the current JTA transaction, it is the responsibility of the application to associate the entity
manager with the transaction (if desired) by calling EntityManager.joinTransaction. If the
entity manager is created outside the scope of a JTA transaction, it is not associated with the transaction
unless EntityManager.joinTransaction is called.
The EntityManager.close method closes an entity manager to release its persistence context and
other resources. After calling close, the application must not invoke any further methods on the
EntityManager instance except for getTransaction and isOpen, or the IllegalState-
Exception will be thrown. If the close method is invoked when a transaction is active, the persis-
tence context remains managed until the transaction completes.
The EntityManager.isOpen method indicates whether the entity manager is open. The isOpen
method returns true until the entity manager has been closed.
Application-managed Persistence Contexts Java Persistence 2.0, Early Draft Entity Managers and Persistence Contexts
5.7.1 Examples
@Stateless
public class ShoppingCartImpl implements ShoppingCart {
@PersistenceUnit
private EntityManagerFactory emf;
Entity Managers and Persistence Contexts Java Persistence 2.0, Early Draft Application-managed Persistence Contexts
@PersistenceUnit
private EntityManagerFactory emf;
Application-managed Persistence Contexts Java Persistence 2.0, Early Draft Entity Managers and Persistence Contexts
@PostConstruct
public void init() {
em = emf.createEntityManager();
}
@Remove
public void destroy() {
em.close();
}
}
Entity Managers and Persistence Contexts Java Persistence 2.0, Early Draft Application-managed Persistence Contexts
public ShoppingCart() {
emf = Persistence.createEntityManagerFactory("orderMgt");
em = emf.createEntityManager();
}
em.getTransaction().commit();
return li;
}
Requirements on the Container Java Persistence 2.0, Early Draft Entity Managers and Persistence Contexts
When application-managed persistence contexts are used, the container must instantiate the entity man-
ager factory and expose it to the application via JNDI. The container might use internal APIs to create
the entity manager factory, or it might use the PersistenceProvider.createContainerEn-
tityManagerFactory method. However, the container is required to support third-party persis-
tence providers, and in this case the container must use the
PersistenceProvider.createContainerEntityManagerFactory method to create the
entity manager factory and the EntityManagerFactory.close method to destroy the entity
manager factory prior to shutdown (if it has not been previously closed by the application).
When operating with a third-party persistence provider, the container uses the contracts defined in sec-
tion 5.9 to create and destroy container-managed persistence contexts. It is undefined whether a new
entity manager instance is created for every persistence context, or whether entity manager instances are
sometimes reused. Exactly how the container maintains the association between persistence context and
JTA transaction is not defined.
If a persistence context is already associated with a JTA transaction, the container uses that persistence
context for subsequent invocations within the scope of that transaction, according to the semantics for
persistence context propagation defined in section 5.6.3.
This section describes contracts between the container and the persistence provider for the pluggability
of third-party persistence providers. Containers are required to support these pluggability contracts.[54]
[54] It is not required that these contracts be used when a third-party persistence provider is not used: the container might use these
same APIs or its might use its own internal APIs.
Entity Managers and Persistence Contexts Java Persistence 2.0, Early Draft Runtime Contracts between the Container and Per-
• After the JTA transaction has completed (either by transaction commit or rollback), The con-
tainer closes the entity manager by calling EntityManager.close. [55]
• The container closes the entity manager by calling EntityManager.close after the state-
ful session bean and all other stateful session beans that have inherited the same persistence
context as the entity manager have been removed.
• When a business method of the stateful session bean is invoked, if the stateful session bean
uses container managed transaction demarcation, and the entity manager is not already associ-
ated with the current JTA transaction, the container associates the entity manager with the cur-
rent JTA transaction and calls EntityManager.joinTransaction. If there is a
different persistence context already associated with the JTA transaction, the container throws
the EJBException.
• When a business method of the stateful session bean is invoked, if the stateful session bean
uses bean managed transaction demarcation and a UserTransaction is begun within the
method, the container associates the persistence context with the JTA transaction and calls
EntityManager.joinTransaction.
The container must throw the IllegalStateException if the application calls EntityMan-
ager.close on a container-managed entity manager.
When the container creates an entity manager, it may pass a map of properties to the persistence pro-
vider by using the EntityManagerFactory.createEntityManager(Map map) method. If
properties have been specified in the PersistenceContext annotation or the persis-
tence-context-ref deployment descriptor element, this method must be used and the map must
include the specified properties.
[55] The container may choose to pool EntityManagers and instead of creating and closing in each case acquire one from its pool and
call clear() on it.
Runtime Contracts between the Container and Persistence ProviderJava Persistence 2.0, Early Draft Entity Managers and Persistence
The Provider has no knowledge of the distinction between transaction-scoped and extended persistence
contexts. It provides entity managers to the container when requested and registers for synchronization
notifications for the transaction.
• When the JTA transaction commits, the provider must flush all modified entity state to the
database.
• When the JTA transaction rolls back, the provider must detach all managed entities.
• When the provider throws an exception defined to cause transaction rollback, the provider
must mark the transaction for rollback.
• When EntityManager.close is invoked, the provider should release all resources that it
may have allocated after any outstanding transactions involving the entity manager have com-
pleted. If the entity manager was already in a closed state, the provider must throw the Ille-
galStateException.
• When EntityManager.clear is invoked, the provider must detach all managed entities.
Entity Managers and Persistence Contexts Java Persistence 2.0, Early Draft Cache Interface
The Cache interface provides basic functionality over the persistence provider’s second level cache, if
used.
package javax.persistence;
/**
* Interface used to interact with the second-level cache.
* If a cache is not in use, the methods of this interface have
* no effect, except for contains, which returns false.
*/
public interface Cache {
/**
* Whether the cache contains data for the given entity.
*/
public boolean contains(Class cls, Object primaryKey);
/**
* Remove the data for the given entity from the cache.
*/
public void evict(Class cls, Object primaryKey);
/**
* Remove the data for entities of the specified class (and its
subclasses) from the cache.
*/
public void evict(Class cls);
/**
* Clear the cache.
*/
public void evictAll();
}
C ha p t e r 6 Entity Packaging
• An entity manager factory and its entity managers, together with their configuration informa-
tion.
• The set of managed classes included in the persistence unit and managed by the entity manag-
ers of the entity manager factory.
• Mapping metadata (in the form of metadata annotations and/or XML metadata) that specifies
the mapping of the classes to the database.
Entity Packaging Java Persistence 2.0, Early Draft Persistence Unit Packaging
Within Java EE environments, an EJB-JAR, WAR, EAR, or application client JAR can define a persis-
tence unit. Any number of persistence units may be defined within these scopes.
A persistence unit may be packaged within one or more jar files contained within a WAR or EAR, as a
set of classes within an EJB-JAR file or in the WAR classes directory, or as a combination of these
as defined below.
A persistence unit is defined by a persistence.xml file. The jar file or directory whose
META-INF directory contains the persistence.xml file is termed the root of the persistence unit.
In Java EE, the root of a persistence unit may be one of the following:
• an EJB-JAR file
It is not required that an EJB-JAR or WAR containing a persistence unit be packaged in an EAR unless
the persistence unit contains persistence classes in addition to those contained in the EJB-JAR or WAR.
See Section 6.2.1.6.
A persistence unit must have a name. Only one persistence unit of any given name may be defined
within a single EJB-JAR file, within a single WAR file, within a single application client jar, or within
an EAR (in the EAR root or lib directory). See Section 6.2.2, “Persistence Unit Scope”.
The persistence.xml file may be used to designate more than one persistence unit within the same
scope.
All persistence classes defined at the level of the Java EE EAR must be accessible to all other Java EE
components in the application—i.e. loaded by the application classloader—such that if the same entity
class is referenced by two different Java EE components (which may be using different persistence
units), the referenced class is the same identical class.
In Java SE environments, the metadata mapping files, jar files, and classes described in the following
sections can be used. To insure the portability of a Java SE application, it is necessary to explicitly list
the managed persistence classes that are included in the persistence unit. See Section 6.2.1.6.
[56] The root of the persistence unit is the WEB-INF/classes directory; the persistence.xml file is therefore contained in the
WEB-INF/classes/META-INF directory.
Persistence Unit Packaging Java Persistence 2.0, Early Draft Entity Packaging
The object/relational mapping information may take the form of annotations on the managed persis-
tence classes included in the persistence unit, one or more XML files contained in the root of the persis-
tence unit, one or more XML files outside the root of the persistence unit on the classpath and
referenced from the persistence.xml, or a combination of these.
The managed persistence classes may either be contained within the root of the persistence unit; or they
may be specified by reference—i.e., by naming the classes, class archives, or mapping XML files
(which in turn reference classes) that are accessible on the application classpath; or they may be speci-
fied by some combination of these means. See Section 6.2.1.6.
The persistence-unit element consists of the name and transaction-type attributes and
the following sub-elements: description, provider, jta-data-source,
non-jta-data-source, mapping-file, jar-file, class,
exclude-unlisted-classes, and properties.
The name attribute is required; the other attributes and elements are optional. Their semantics are
described in the following subsections.
Examples:
<persistence>
<persistence-unit name="OrderManagement">
<description>
This unit manages orders and customers.
It does not rely on any vendor-specific features and can
therefore be deployed to any persistence provider.
</description>
<jta-data-source>jdbc/MyOrderDB</jta-data-source>
<mapping-file>ormap.xml</mapping-file>
<jar-file>MyOrderApp.jar</jar-file>
<class>com.widgets.Order</class>
<class>com.widgets.Customer</class>
</persistence-unit>
</persistence>
Entity Packaging Java Persistence 2.0, Early Draft Persistence Unit Packaging
<persistence>
<persistence-unit name="OrderManagement2">
<description>
This unit manages inventory for auto parts.
It depends on features provided by the
com.acme.persistence implementation.
</description>
<provider>com.acme.AcmePersistence</provider>
<jta-data-source>jdbc/MyPartDB</jta-data-source>
<mapping-file>ormap2.xml</mapping-file>
<jar-file>MyPartsApp.jar</jar-file>
<properties>
<property name="com.acme.persistence.sql-logging"
value="on"/>
</properties>
</persistence-unit>
</persistence>
6.2.1.1 name
The name attribute defines the name for the persistence unit. This name may be used to identify a per-
sistence unit referred to by the PersistenceContext and PersistenceUnit annotations and
in the programmatic API for creating an entity manager factory.
6.2.1.2 transaction-type
The transaction-type attribute is used to specify whether the entity managers provided by the
entity manager factory for the persistence unit must be JTA entity managers or resource-local entity
managers. The value of this element is JTA or RESOURCE_LOCAL. A transaction-type of JTA
assumes that a JTA data source will be provided—either as specified by the jta-data-source ele-
ment or provided by the container. In general, in Java EE environments, a transaction-type of
RESOURCE_LOCAL assumes that a non-JTA datasource will be provided. In a Java EE environment, if
this element is not specified, the default is JTA. In a Java SE environment, if this element is not speci-
fied, a default of RESOURCE_LOCAL may be assumed.
6.2.1.3 description
The description element provides optional descriptive information about the persistence unit.
6.2.1.4 provider
The provider element specifies the name of the persistence provider's javax.persis-
tence.spi.PersistenceProvider class. The provider element must be specified if the
application is dependent upon a particular persistence provider being used.
These elements name the data source in the local environment; the format of these names and the ability
to specify the names are product specific.
Persistence Unit Packaging Java Persistence 2.0, Early Draft Entity Packaging
In Java SE environments, these elements may be used or the data source information may be specified
by other means—depending upon the requirements of the provider.
The set of managed persistence classes that are managed by a persistence unit is defined by using one or
more of the following:[57]
• The annotated managed persistence classes contained in the root of the persistence unit (unless
the exclude-unlisted-classes element is specified)
An object/relational mapping XML file contains mapping information for the classes listed in it. A
object/relational mapping XML file named orm.xml may be specified in the META-INF directory in
the root of the persistence unit or in the META-INF directory of any jar file referenced by the per-
sistence.xml. Alternatively, or in addition, other mapping files may be referenced by the map-
ping-file elements of the persistence-unit element, and may be present anywhere on the
class path. An orm.xml file or other mapping file is loaded as a resource by the persistence provider. If
a mapping file is specified, the classes and mapping information specified in the mapping file will be
used. If multiple mapping files are specified (possibly including one or more orm.xml files), the
resulting mappings are obtained by combining the mappings from all of the files. The result is unde-
fined if multiple mapping files (including any orm.xml file) referenced within a single persistence unit
contain overlapping mapping information for any given class. The object/relational mapping informa-
tion contained in any mapping file referenced within the persistence unit must be disjoint at the
class-level from object/relational mapping information contained in any other such mapping file.
One or more JAR files may be specified using the jar-file elements instead of, or in addition to the
mapping files specified in the mapping-file elements. If specified, these JAR files will be searched
for managed persistence classes, and any mapping metadata annotations found on them will be pro-
cessed, or they will be mapped using the mapping annotation defaults defined by this specification.
Such JAR files are specified relative to the root of the persistence unit (e.g., utils/myUtils.jar).
A list of named managed persistence classes may also be specified instead of, or in addition to, the JAR
files and mapping files. Any mapping metadata annotations found on these classes will be processed, or
they will be mapped using the mapping annotation defaults. The class element is used to list a man-
aged persistence class. A list of all named managed persistence classes must be specified in Java SE
environments to insure portability. Portable Java SE applications should not rely on the other mecha-
nisms described here to specify the managed persistence classes of a persistence unit. Persistence pro-
viders may also require that the set of entity classes and classes that are to be managed must be fully
enumerated in each of the persistence.xml files in Java SE environments.
[57] Note that an individual class may be used in more than one persistence unit.
Entity Packaging Java Persistence 2.0, Early Draft Persistence Unit Packaging
All classes contained in the root of the persistence unit are also searched for annotated managed persis-
tence classes and any mapping metadata annotations found on them will be processed, or they will be
mapped using the mapping annotation defaults. If it is not intended that the annotated persistence
classes contained in the root of the persistence unit be included in the persistence unit, the
exclude-unlisted-classes element should be used. The exclude-unlisted-classes
element is not intended for use in Java SE environments.
The resulting set of entities managed by the persistence unit is the union of these sources, with the map-
ping metadata annotations (or annotation defaults) for any given class being overridden by the XML
mapping information file if there are both annotations as well as XML mappings for that class. The min-
imum portable level of overriding is at the level of the persistent field or property.
The classes and/or jars that are named as part of a persistence unit must be on the classpath; referencing
them from the persistence.xml file does not cause them to be placed on the classpath.
All classes must be on the classpath to ensure that entity managers from different persistence units that
map the same class will be accessing the same identical class.
6.2.1.7 properties
The properties element is used to specify both standard and vendor-specific properties and hints
that apply to the persistence unit and its entity manager factory configuration.
The following properties defined by this specification are intended for use in both Java EE and Java SE
environments:
The following properties defined by this specification are intended for use in Java SE environments.
If a persistence provider does not recognize a property (other than a property defined by this specifica-
tion), the provider must ignore it.
Persistence Unit Packaging Java Persistence 2.0, Early Draft Entity Packaging
6.2.1.8 Examples
The following are sample contents of a persistence.xml file.
Example 1:
<persistence-unit name="OrderManagement"/>
Any annotated managed persistence classes found in the root of the persistence unit are added to the list
of managed persistence classes. If a META-INF/orm.xml file exists, any classes referenced by it and
mapping information contained in it are used as specified above. Because no provider is specified, the
persistence unit is assumed to be portable across providers. Because the transaction type is not speci-
fied, JTA is assumed. The container must provide the data source (it may be specified at application
deployment, for example); in Java SE environments, the data source may be specified by others means.
Example 2:
<persistence-unit name="OrderManagement2">
<mapping-file>mappings.xml</mapping-file>
</persistence-unit>
Example 3:
<persistence-unit name="OrderManagement3">
<jar-file>order.jar</jar-file>
<jar-file>order-supplemental.jar</jar-file>
</persistence-unit>
Entity Packaging Java Persistence 2.0, Early Draft Persistence Unit Packaging
Example 4:
<persistence-unit
name="OrderManagement4"
transaction-type=RESOURCE_LOCAL>
<non-jta-data-source>jdbc/MyDB</jta-data-source>
<mapping-file>order-mappings.xml</mapping-file>
<exclude-unlisted-classes/>
<class>com.acme.Order</class>
<class>com.acme.Customer</class>
<class>com.acme.Item</class>
</persistence-unit>
A persistence unit named OrderManagement4 is created. The order-mappings.xml is read as
a resource and any classes referenced by it and mapping information contained in it are used. The anno-
tated Order, Customer and Item classes are loaded and are added. No (other) classes contained in
the root of the persistence unit are added to the list of managed persistence classes. The persistence unit
is portable across providers. A entity manager factory supplying resource-local entity managers will be
created. The data source jdbc/MyDB must be used.
Example 5:
<persistence-unit name="OrderManagement5">
<provider>com.acme.AcmePersistence</provider>
<mapping-file>order1.xml</mapping-file>
<mapping-file>order2.xml</mapping-file>
<jar-file>order.jar</jar-file>
<jar-file>order-supplemental.jar</jar-file>
</persistence-unit>
Note that the persistence.xml file contained in order.jar is not used to augment the
persistence unit EM-5 with the classes of the persistence unit whose root is order.jar.
Persistence Unit Packaging Java Persistence 2.0, Early Draft Entity Packaging
When referencing a persistence unit using the unitName annotation element or persis-
tence-unit-name deployment descriptor element, the visibility scope of the persistence unit is
determined by its point of definition. A persistence unit that is defined at the level of an EJB-JAR,
WAR, or application client jar is scoped to that EJB-JAR, WAR, or application jar respectively and is
visible to the components defined in that jar or war. A persistence unit that is defined at the level of the
EAR is generally visible to all components in the application.
However, if a persistence unit of the same name is defined by an EJB-JAR, WAR, or application jar file
within the EAR, the persistence unit of that name defined at EAR level will not be visible to the compo-
nents defined by that EJB-JAR, WAR, or application jar file unless the persistence unit reference uses
the persistence unit name # syntax to specify a path name to disambiguate the reference. When the #
syntax is used, the path name is relative to the referencing application component jar file. For example,
the syntax ../lib/persistenceUnitRoot.jar#myPersistenceUnit refers to a persis-
tence unit whose name, as specified in the name element of the persistence.xml file, is myPer-
sistenceUnit and for which the relative path name of the root of the persistence unit is
../lib/persistenceUnitRoot.jar. The # syntax may be used with both the unitName
annotation element or persistence-unit-name deployment descriptor element to reference a
persistence unit defined at EAR level.
This section provides the XML schema for the persistence.xml file.
<xsd:annotation>
<xsd:documentation>
@(#)persistence_1_0.xsd 1.0 Feb 9 2006
</xsd:documentation>
</xsd:annotation>
<xsd:annotation>
<xsd:documentation><![CDATA[
http://java.sun.com/xml/ns/persistence
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
...
</persistence>
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType name="versionType">
<xsd:restriction base="xsd:token">
<xsd:pattern value="[0-9]+(\.[0-9]+)*"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:element name="persistence">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="persistence-unit"
minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- **************************************************** -->
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:documentation>
</xsd:annotation>
</xsd:element>
When set to true then only listed classes and jars will
be scanned for persistent classes, otherwise the enclosing
jar or directory will also be scanned. Not applicable to
Java SE persistence units.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="property"
minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
A name-value pair.
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="name" type="xsd:string"
use="required"/>
<xsd:attribute name="value" type="xsd:string"
use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="transaction-type"
type="persistence:persistence-unit-transac-
tion-type">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="version" type="persistence:versionType"
fixed="1.0" use="required"/>
</xsd:complexType>
</xsd:element>
<xsd:simpleType name="persistence-unit-transaction-type">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="JTA"/>
<xsd:enumeration value="RESOURCE_LOCAL"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
Java EE Deployment Java Persistence 2.0, Early Draft Container and Provider Contracts for Deployment
This chapter defines requirements on the Java EE container and on the persistence provider for deploy-
ment and bootstrapping.
Each persistence unit deployed into a Java EE container consists of a single persistence.xml file,
any number of mapping files, and any number of class files.
Container and Provider Contracts for Deployment and BootstrappingJava Persistence 2.0, Early Draft Java EE Deployment
When the container finds a persistence.xml file, it processes the persistence unit definitions that
it contains. The container must validate the persistence.xml file against the
persistence_1_0.xsd schema and report any validation errors. Provider or data source informa-
tion not specified in the persistence.xml file must be provided at deployment time or defaulted by
the container. The container may optionally add any container-specific properties to be passed to the
provider when creating the entity manager factory for the persistence unit.
Once the container has read the persistence metadata, it determines the javax.persis-
tence.spi.PersistenceProvider implementation class for each deployed named persistence
unit. It creates an instance of this implementation class and invokes the createContainerEnti-
tyManagerFactory method on that instance. The metadata—in the form of a Persistence-
UnitInfo class—is passed to the persistence provider as part of this call. The factory obtained as a
result will be used by the container to create container-managed entity managers. Only one EntityMan-
agerFactory is permitted to be created for each deployed persistence unit configuration. Any number of
EntityManager instances may be created from a given factory.
When a persistence unit is redeployed, the container should call the close method on the previous
EntityManagerFactory instance and call the createContainerEntityManagerFactory
method again, with the required PersistenceUnitInfo metadata, to achieve the redeployment.
The persistence provider processes the metadata annotations on the managed classes of the persistence
unit.
When the persistence provider obtains an object/relational mapping file, it processes the definitions that
it contains. The persistence provider must validate any object/relational mapping files against the
orm_1_0.xsd schema and report any validation errors.
In Java SE environments, the persistence provider must validate the persistence.xml file against
the persistence_1_0.xsd schema and report any validation errors.
7.1.3 javax.persistence.spi.PersistenceProvider
The interface javax.persistence.spi.PersistenceProvider is implemented by the per-
sistence provider.
Java EE Deployment Java Persistence 2.0, Early Draft Container and Provider Contracts for Deployment
package javax.persistence.spi;
/**
* Interface implemented by the persistence provider.
* This interface is used to create an EntityManagerFactory.
* It is invoked by the container in Java EE environments and
* by the Persistence class in Java SE environments.
*/
public interface PersistenceProvider {
/**
* Called by Persistence class when an EntityManagerFactory
* is to be created.
*
* @param emName The name of the persistence unit
* @param map A Map of properties for use by the
* persistence provider. These properties may be used to
* override the values of the corresponding elements in
* the persistence.xml file or specify values for
* properties not specified in the persistence.xml
* (and may be null if no properties are specified).
* @return EntityManagerFactory for the persistence unit,
* or null if the provider is not the right provider
*/
public EntityManagerFactory createEntityManagerFactory(String
emName, Map map);
/**
* Called by the container when an EntityManagerFactory
* is to be created.
*
* @param info Metadata for use by the persistence provider
* @return EntityManagerFactory for the persistence unit
* specified by the metadata
* @param map A Map of integration-level properties for use
* by the persistence provider (may be null if no properties
* are specified).
*/
public EntityManagerFactory createContainerEntityManagerFac-
tory(PersistenceUnitInfo info, Map map);
}
Container and Provider Contracts for Deployment and BootstrappingJava Persistence 2.0, Early Draft Java EE Deployment
Java EE Deployment Java Persistence 2.0, Early Draft Container and Provider Contracts for Deployment
package javax.persistence.spi;
import javax.sql.DataSource;
/**
* Interface implemented by the container and used by the
* persistence provider when creating an EntityManagerFactory.
*/
/**
* @return The name of the persistence unit.
* Corresponds to the name attribute in the persistence.xml file.
*/
public String getPersistenceUnitName();
/**
* @return The fully qualified name of the persistence provider
* implementation class.
* Corresponds to the <provider> element in the persistence.xml
* file.
*/
public String getPersistenceProviderClassName();
/**
* @return The transaction type of the entity managers created
* by the EntityManagerFactory.
* The transaction type corresponds to the transaction-type
* attribute in the persistence.xml file.
*/
public PersistenceUnitTransactionType getTransactionType();
/**
* @return The JTA-enabled data source to be used by the
* persistence provider.
* The data source corresponds to the <jta-data-source>
* element in the persistence.xml file or is provided at
* deployment or by the container.
*/
public DataSource getJtaDataSource();
/**
* @return The non-JTA-enabled data source to be used by the
* persistence provider for accessing data outside a JTA
* transaction.
* The data source corresponds to the named <non-jta-data-source>
* element in the persistence.xml file or provided at
* deployment or by the container.
*/
public DataSource getNonJtaDataSource();
/**
* @return The list of mapping file names that the persistence
* provider must load to determine the mappings for the entity
* classes. The mapping files must be in the standard XML
* mapping format, be uniquely named and be resource-loadable
Container and Provider Contracts for Deployment and BootstrappingJava Persistence 2.0, Early Draft Java EE Deployment
/**
* Returns a list of URLs for the jar files or exploded jar
* file directories that the persistence provider must examine
* for managed classes of the persistence unit. Each URL
* corresponds to a named <jar-file> element in the
* persistence.xml file. A URL will either be a file:
* URL referring to a jar file or referring to a directory
* that contains an exploded jar file, or some other URL from
* which an InputStream in jar format can be obtained.
*
* @return a list of URL objects referring to jar files or
* directories.
*/
public List<URL> getJarFileUrls();
/**
* Returns the URL for the jar file or directory that is the
* root of the persistence unit. (If the persistence unit is
* rooted in the WEB-INF/classes directory, this will be the
* URL of that directory.)
* The URL will either be a file: URL referring to a jar file
* or referring to a directory that contains an exploded jar
* file, or some other URL from which an InputStream in jar
* format can be obtained.
*
* @return a URL referring to a jar file or directory.
*/
public URL getPersistenceUnitRootUrl();
/**
* @return The list of the names of the classes that the
* persistence provider must add it to its set of managed
* classes. Each name corresponds to a named <class> element
* in the persistence.xml file.
*/
public List<String> getManagedClassNames();
/**
* @return Whether classes in the root of the persistence
* unit that have not been explicitly listed are to be
* included in the set of managed classes.
* This value corresponds to the <exclude-unlisted-classes>
* element in the persistence.xml file.
*/
public boolean excludeUnlistedClasses();
/**
* @return Properties object. Each property corresponds
* to a <property> element in the persistence.xml file
*/
public Properties getProperties();
/**
Java EE Deployment Java Persistence 2.0, Early Draft Container and Provider Contracts for Deployment
/**
* Return a new instance of a ClassLoader that the provider
* may use to temporarily load any classes, resources, or
* open URLs. The scope and classpath of this loader is
* exactly the same as that of the loader returned by
* PersistenceUnitInfo.getClassLoader. None of the classes loaded
* by this class loader will be visible to application
* components. The provider may only use this ClassLoader
* within the scope of the createContainerEntityManagerFactory
* call.
*
* @return Temporary ClassLoader with same visibility as current
* loader
*/
public ClassLoader getNewTempClassLoader();
}
Container and Provider Contracts for Deployment and BootstrappingJava Persistence 2.0, Early Draft Bootstrapping in Java SE Envi-
package javax.persistence.spi;
/**
* A persistence provider supplies an instance of this
* interface to the PersistenceUnitInfo.addTransformer
* method. The supplied transformer instance will get
* called to transform entity class files when they are
* loaded or redefined. The transformation occurs before
* the class is defined by the JVM.
*/
public interface ClassTransformer {
/**
* Invoked when a class is being loaded or redefined.
* The implementation of this method may transform the
* supplied class file and return a new replacement class
* file.
*
* @param loader The defining loader of the class to be
* transformed, may be null if the bootstrap loader
* @param className The name of the class in the internal form
* of fully qualified class and interface names
* @param classBeingRedefined If this is a redefine, the
* class being redefined, otherwise null
* @param protectionDomain The protection domain of the
* class being defined or redefined
* @param classfileBuffer The input byte buffer in class
* file format - must not be modified
* @return A well-formed class file buffer (the result of
* the transform), or null if no transform is performed
* @throws IllegalClassFormatException If the input does
* not represent a well-formed class file
*/
byte[] transform(ClassLoader loader,
String className,
Class<?> classBeingRedefined,
ProtectionDomain protectionDomain,
byte[] classfileBuffer)
throws IllegalClassFormatException;
}
[58] Use of these Java SE bootstrapping APIs may be supported in Java EE containers; however, support for such use is not required.
Bootstrapping in Java SE Environments Java Persistence 2.0, Early Draft Container and Provider Contracts for Deployment
A persistence provider implementation running in a Java SE environment should also act as a service
provider by supplying a service provider configuration file as described in the JAR File Specification
[6].
The provider configuration file serves to export the provider implementation class to the Persis-
tence bootstrap class, positioning the provider as a candidate for backing named persistence units.
The provider supplies the provider configuration file by creating a text file named javax.persis-
tence.spi.PersistenceProvider and placing it in the META-INF/services directory of
one of its JAR files. The contents of the file should be the name of the provider implementation class of
the javax.persistence.spi.PersistenceProvider interface.
Example:
A persistence vendor called ACME persistence products ships a JAR called acme.jar that contains
its persistence provider implementation. The JAR includes the provider configuration file.
acme.jar
META-INF/services/javax.persistence.spi.PersistenceProvider
com.acme.PersistenceProvider
…
Persistence provider jars may be installed or made available in the same ways as other service provid-
ers, e.g. as extensions or added to the application classpath according to the guidelines in the JAR File
Specification.
The Persistence bootstrap class will locate all of the persistence providers by their provider config-
uration files and call createEntityManagerFactory() on them in turn until an appropriate
backing provider returns an EntityManagerFactory. A provider may deem itself as appropriate for the
persistence unit if any of the following are true:
• Its implementation class has been specified in the provider element for that persistence unit
in the persistence.xml file.
• No provider was specified for the persistence unit in either the persistence.xml or the
property map.
If a provider does not qualify as the provider for the named persistence unit, it must return null when
createEntityManagerFactory is invoked on it.
Container and Provider Contracts for Deployment and BootstrappingJava Persistence 2.0, Early Draft Bootstrapping in Java SE Envi-
/**
* Create and return an EntityManagerFactory for the
* named persistence unit using the given properties.
*
* @param persistenceUnitName The name of the persistence unit
* @param props Additional properties to use when creating the
* factory. The values of these properties override any values
* that may have been configured elsewhere.
* @return The factory that creates EntityManagers configured
* according to the specified persistence unit.
*/
public static EntityManagerFactory createEntityManagerFac-
tory(String persistenceUnitName, Map properties) {...}
...
}
The properties argument is used to specify both standard and vendor-specific properties.
The following properties and hints defined by this specification are intended for use in creating the
entity manager factory.
Bootstrapping in Java SE Environments Java Persistence 2.0, Early Draft Container and Provider Contracts for Deployment
If a persistence provider does not recognize a property (other than a property defined by this specifica-
tion), the provider must ignore it.
Container and Provider Contracts for Deployment and BootstrappingJava Persistence 2.0, Early Draft Bootstrapping in Java SE Envi-
C ha p t e r 8 Metadata Annotations
This chapter and chapter 9 define the metadata annotations introduced by this specification.
The XML schema defined in chapter 10 provides an alternative to the use of metadata annotatations.
8.1 Entity
The Entity annotation specifies that the class is an entity. This annotation is applied to the entity
class.
The name annotation element specifies the entity name. It defaults to the unqualified name of the entity
class. This name is used to refer to the entity in queries. The name must not be a reserved literal in the
Java Persistence query language.
@Target(TYPE) @Retention(RUNTIME)
public @interface Entity {
String name() default "";
}
The EntityListeners annotation specifies the callback listener classes to be used for an entity or
mapped superclass. The EntityListeners annotation may be applied to an entity class or mapped
superclass.
@Target({TYPE}) @Retention(RUNTIME)
public @interface EntityListeners {
Class[] value();
}
@Target({TYPE}) @Retention(RUNTIME)
public @interface ExcludeSuperclassListeners {
}
@Target({TYPE}) @Retention(RUNTIME)
public @interface ExcludeDefaultListeners {
}
The following annotations are used to specify callback methods for the corresponding lifecycle events.
These annotations may be applied to methods of an entity class, of a mapped superclass, or of an entity
listener class.
@Target({METHOD}) @Retention(RUNTIME)
public @interface PrePersist {}
@Target({METHOD}) @Retention(RUNTIME)
public @interface PostPersist {}
@Target({METHOD}) @Retention(RUNTIME)
public @interface PreRemove {}
@Target({METHOD}) @Retention(RUNTIME)
public @interface PostRemove {}
@Target({METHOD}) @Retention(RUNTIME)
public @interface PreUpdate {}
@Target({METHOD}) @Retention(RUNTIME)
public @interface PostUpdate {}
@Target({METHOD}) @Retention(RUNTIME)
public @interface PostLoad {}
Annotations for Queries Java Persistence 2.0, Early Draft Metadata Annotations
The NamedQuery annotation is used to specify a named query in the Java Persistence query language.
The name element is used to refer to the query when using the EntityManager methods that create
query objects.
The query element must specify a query string in the Java Persistence query language.
The lockMode element specifies a lock mode for the results returned by the query. If a lock mode
other than NONE is specified, the query must be executed within a transaction.
The hints elements may be used to specify query hints. Vendor-specific hints that are not recognized
by a provider must be ignored.
The NamedQuery and NamedQueries annotations can be applied to an entity or mapped superclass.
@Target({TYPE}) @Retention(RUNTIME)
public @interface NamedQuery {
String name();
String query();
LockModeType lockMode() default NONE;
QueryHint[] hints() default {};
}
@Target({}) @Retention(RUNTIME)
public @interface QueryHint {
String name();
String value();
}
@Target({TYPE}) @Retention(RUNTIME)
public @interface NamedQueries {
NamedQuery[] value ();
}
The name element is used to refer to the query when using the EntityManager methods that create
query objects.
The resultClass element refers to the class of the result; the value of the resultSetMapping
element is the name of a SqlResultSetMapping, as defined in metadata.
Metadata Annotations Java Persistence 2.0, Early Draft Annotations for Queries
The hints elements may be used to specify query hints. Vendor-specific hints that are not recognized
by a provider must be ignored.
@Target({TYPE}) @Retention(RUNTIME)
public @interface NamedNativeQuery {
String name();
String query();
QueryHint[] hints() default {};
Class resultClass() default void.class;
String resultSetMapping() default ""; // name of SqlResultSetMap-
ping
}
@Target({TYPE}) @Retention(RUNTIME)
public @interface NamedNativeQueries {
NamedNativeQuery[] value ();
}
@Target({TYPE}) @Retention(RUNTIME)
public @interface SqlResultSetMapping {
String name();
EntityResult[] entities() default {};
ColumnResult[] columns() default {};
}
@Target({TYPE}) @Retention(RUNTIME)
public @interface SqlResultSetMappings {
SqlResultSetMapping[] value();
}
The name element is the name given to the result set mapping, and used to refer to it in the methods of
the Query API. The entities and columns elements are used to specify the mapping to entities
and to scalar values respectively.
@Target({}) @Retention(RUNTIME)
public @interface EntityResult {
Class entityClass();
FieldResult[] fields() default {};
String discriminatorColumn() default "";
}
The fields element is used to map the columns specified in the SELECT list of the query to the prop-
erties or fields of the entity class.
References to EntityManager and EntityManagerFactoryJava Persistence 2.0, Early Draft Metadata Annotations
The discriminatorColumn element is used to specify the column name (or alias) of the column in
the SELECT list that is used to determine the type of the entity instance.
@Target({}) @Retention(RUNTIME)
public @interface FieldResult {
String name();
String column();
}
The name element is the name of the persistent field or property of the class.
The column names that are used in these annotations refer to the names of the columns in the SELECT
clause—i.e., column aliases, if applicable.
@Target({}) @Retention(RUNTIME)
public @interface ColumnResult {
String name();
}
These annotations are used to express dependencies on entity managers and entity manager factories.
The name element refers to the name by which the entity manager is to be accessed in the environment
referencing context, and is not needed when dependency injection is used.
The optional unitName element refers to the name of the persistence unit. If the unitName element
is specified, the persistence unit for the entity manager that is accessible in JNDI must have the same
name.
The type element specifies whether a transaction-scoped or extended persistence context is to be used.
If the type element is not specified, a transaction-scoped persistence context is used.
The optional properties element may be used to specify properties for the container or persistence
provider. Vendor specific properties may be included in the set of properties, and are passed to the per-
sistence provider by the container when the entity manager is created. Properties that are not recognized
by a vendor must be ignored.
Metadata Annotations Java Persistence 2.0, Early Draft References to EntityManager and EntityManager-
@Target({}) @Retention(RUNTIME)
public @interface PersistenceProperty {
String name();
String value();
}
@Target({TYPE}) @Retention(RUNTIME)
public @interface PersistenceContexts{
PersistenceContext[] value();
}
The PersistenceUnit annotation is used to express a dependency on an entity manager factory and
its associated persistence unit.
The name element refers to the name by which the entity manager factory is to be accessed in the envi-
ronment referencing context, and is not needed when dependency injection is used.
The optional unitName element refers to the name of the persistence unit as defined in the persis-
tence.xml file. If the unitName element is specified, the persistence unit for the entity manager
factory that is accessible in JNDI must have the same name.
@Target(TYPE) @Retention(RUNTIME)
public @interface PersistenceUnits{
PersistenceUnit[] value();
}
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
The object/relational mapping metadata is part of the application domain model contract. It expresses
requirements and expectations on the part of the application as to the mapping of the entities and rela-
tionships of the application domain to a database. Queries (and, in particular, SQL queries) written
against the database schema that corresponds to the application domain model are dependent upon the
mappings expressed by means of the object/relational mapping metadata. The implementation of this
specification must assume this application dependency upon the object/relational mapping metadata and
insure that the semantics and requirements expressed by that mapping are observed.
It is permitted, but not required, that DDL generation be supported by an implementation of this specifi-
cation. Portable applications should not rely upon the use of DDL generation.
XML metadata may be used as an alternative to these annotations, or to override or augment annota-
tions, as described in Chapter 10.
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
The AssociationOverride annotation may be applied to an entity that extends a mapped super-
class to override a many-to-one or one-to-one mapping defined by the mapped superclass. If the Asso-
ciationOverride annotation is not specified, the association is mapped the same as in the original
mapping. When used to override a mapping defined by a mapped superclass, the Association-
Override annotation is applied to the entity class.
If the relationship mapping is a foreign key mapping, the joinColumns element of the Associa-
tionOverride annotation is used. If the relationship mapping uses a join table, the joinTable
element of the AssociationOverride element must be specified to override the mapping of the
join table and/or its join columns.[60]
[59] The use of map keys that contain embeddables that reference entities is not permitted.
[60] Note that either the joinColumns element or the joinTable element of the AssociationOverride annotation is spec-
ified for overriding a given relationship (but never both).
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
Table 4 lists the annotation elements that may be specified for an AssociationOverride annota-
tion.
The joinColumns element refers to the table for the class that contains the annotation.
JoinCol- joinCol- The join column that is being mapped to the persistent
umn[] umns attribute. The joinColumns element must be specified
if a foreign key mapping is used in the overriding of
the mapping of the relationship. The joinColumns ele-
ment must not be specified if a join table is used in the
overriding of the mapping of the relationship
JoinTable joinTable The join table that maps the relationship. The joinT- .
able element must be specified if a join table is used in
the overriding of the mapping of the relationship. The
joinTable element must not be specified if a foreign
key mapping is used in the overriding of the mapping
of the relationship.
Example 1:
@MappedSuperclass
public class Employee {
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
@Entity
@AssociationOverride(name="address",
joinColumns=@JoinColumn(name="ADDR_ID"))
public class PartTimeEmployee extends Employee {
// address field mapping overridden to ADDR_ID fk
@Column(name="WAGE")
protected Float hourlyWage;
public Float getHourlyWage() { ... }
public void setHourlyWage(Float wage) { ... }
}
Example 2: Overriding of the mapping for the phoneNumbers relationship defined in the Con-
tactInfo embeddable class.
@Entity
public class Employee {
@Id int id;
@AssociationOverride(
name="phoneNumbers",
joinTable=@JoinTable(
name="EMPPHONES",
joinColumns=@JoinColumn(name="EMP"),
inverseJoinColumns=@JoinColumn(name="PHONE")
)
)
@Embedded ContactInfo contactInfo;
...
}
@Embeddable
public class ContactInfo {
@ManyToOne Address address; // Unidirectional
@ManyToMany(targetEntity=PhoneNumber.class) List phoneNumbers;
}
@Entity
public class PhoneNumber {
@Id int number;
@ManyToMany(mappedBy="contactInfo.phoneNumbers")
Collection<Employee> employees;
}
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
Example:
@MappedSuperclass
public class Employee {
@Entity
@AssociationOverrides({
@AssociationOverride(name="address",
joinColumns=@JoinColumn("ADDR_ID")),
@AssociationOverride(name="locker",
joinColumns=@JoinColumn("LCKR_ID"))})
The AttributeOverride annotation may be applied to an entity that extends a mapped superclass
or to an embedded field or property to override a Basic mapping or Id mapping defined by the
mapped superclass or embeddable class (or embeddable class of one of its attributes).
If the AttributeOverride annotation is not specified, the column is mapped the same as in the
original mapping.
To override mappings at multiple levels of embedding, a dot (".") notation form must be used in the
name element to indicate an attribute within an embedded attribute. The value of each identifier used
with the dot notation is the name of the respective embedded field or property.
Table 5 lists the annotation elements that may be specified for an AttributeOverride annotation.
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
The column element refers to the table for the class that contains the annotation.
String name (Required) The name of the property whose mapping is being
overridden if property-based access is being used, or the name of
the field if field-based access is used.
Column column (Required) The column that is being mapped to the persistent
attribute. The mapping type will remain the same as is defined in
the embeddable class or mapped superclass.
Example 1:
@MappedSuperclass
public class Employee {
@Entity
@AttributeOverride(name="address", column=@Column(name="ADDR"))
public class PartTimeEmployee extends Employee {
// address field mapping overridden to ADDR
protected Float wage();
public Float getHourlyWage() { ... }
public void setHourlyWage(Float wage) { ... }
}
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
Example 2:
Example 3:
@Entity
public class PropertyRecord {
@EmbeddedId PropertyOwner owner;
@AttributeOverrides({
@AttributeOverride(name="key.street",
column=@Column(name="STREET_NAME")),
@AttributeOverride(name="value.size",
column=@Column(name="SQUARE_FEET")),
@AttributeOverride(name="value.tax",
column=@Column(name="ASSESSMENT"))
})
@ElementCollection
Map<Address, PropertyInfo> parcels;
}
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
Example:
@Embedded
@AttributeOverrides({
@AttributeOverride(name="startDate",
column=@Column(name="EMP_START")),
@AttributeOverride(name="endDate",
column=@Column(name="EMP_END"))
})
public EmploymentPeriod getEmploymentPeriod() { ... }
The Basic annotation is the simplest type of mapping to a database column. The Basic annotation
can be applied to a persistent property or instance variable of any of the following types: Java primitive
types, wrappers of the primitive types, java.lang.String, java.math.BigInteger,
java.math.BigDecimal, java.util.Date, java.util.Calendar, java.sql.Date,
java.sql.Time, java.sql.Timestamp, byte[], Byte[], char[], Character[],
enums, and any other type that implements Serializable. As described in Section 2.8, the use of
the Basic annotation is optional for persistent fields and properties of these types. If the Basic anno-
tation is not specified for such a field or property, the default values of the Basic annotation will apply.
Table 6 lists the annotation elements that may be specified for a Basic annotation and their default val-
ues.
The FetchType enum defines strategies for fetching data from the database:
The EAGER strategy is a requirement on the persistence provider runtime that data must be eagerly
fetched. The LAZY strategy is a hint to the persistence provider runtime that data should be fetched
lazily when it is first accessed. The implementation is permitted to eagerly fetch data for which the
LAZY strategy hint has been specified. In particular, lazy fetching might only be available for Basic
mappings for which property-based access is used.
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
The optional element is a hint as to whether the value of the field or property may be null. It is disre-
garded for primitive types.
FetchType fetch (Optional) Whether the value of the field or property EAGER
should be lazily loaded or must be eagerly fetched. The
EAGER strategy is a requirement on the persistence pro-
vider runtime that the value must be eagerly fetched. The
LAZY strategy is a hint to the persistence provider runt-
ime.
boolean optional (Optional) Whether the value of the field or property may true
be null. This is a hint and is disregarded for primitive
types; it may be used in schema generation.
Example 1:
@Basic
protected String name;
Example 2:
@Basic(fetch=LAZY)
protected String getName() { return name; }
By default, the columns of the collection table that correspond to the embeddable class or basic type are
derived from the attributes of the embeddable class or from the basic type according to the default val-
ues of the Column annotation, as described in Section 9.1.8. In the case of a basic type, the column
name is derived from the name of the collection-valued field or property. In the case of an embeddable
class, the column names are derived from the field or property names of the embeddable class.
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
Open issue: Should we use some “standard” name (e.g., “CVALUE”) as the default column
name for a basic type? Alternatively: attribute_VALUE or attribute_ELEMENT? Note that this
is relevant for Maps whose values are basic types as well.
To override the default properties of the column used for a basic type, the Column annotation is used
on the collection-valued attribute in addition to the ElementCollection annotation. The value of
the table element of the Column annotation defaults to the name of the collection table
To override these defaults for an embeddable class, the AttributeOverride and/or Attribu-
teOverrides annotations must be used in addition to the ElementCollection annotation. The
value of the table element of the Column annotation used in the AttributeOverride annota-
tion defaults to the name of the collection table. If the embeddable class contains references to other
entities, the default values for the columns corresponding to those references may be overridden by
means of the AssociationOverride and/or AssociationOverrides annotations.
Table 7 lists the annotation elements that may be specified for the CollectionTable annotation and
their default values.
String name (Optional) The name of the collec- The concatenation of the name of
tion table. the containing entity and the
name of the collection attribute,
separated by an underscore.
String schema (Optional) The schema of the table. Default schema for user.
JoinColumn[] joinColumns (Optional) The foreign key col- (Default only applies if a single
umns of the collection table which join column is used.) The same
reference the primary table of the defaults as for JoinColumn (i.e.,
entity. the concatenation of the follow-
ing: the name of the entity; "_";
the name of the referenced pri-
mary key column.) However, if
there is more than one join col-
umn, a JoinColumn annotation
must be specified for each join
column using the JoinColumns
annotation. Both the name and
the referencedColumnName ele-
ments must be specified in each
such JoinColumn annotation.
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
Example:
The Column annotation is used to specify a mapped column for a persistent property or field.
Table 8 lists the annotation elements that may be specified for a Column annotation and their default
values.
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
String name (Optional) The name of the column. The property or field
name
boolean unique (Optional) Whether the column is a unique key. This false
is a shortcut for the UniqueConstraint annotation at
the table level and is useful for when the unique key
constraint corresponds to only a single column. This
constraint applies in addition to any constraint
entailed by primary key mapping and to constraints
specified at the table level.
String columnDefinition (Optional) The SQL fragment that is used when gen- Generated SQL to cre-
erating the DDL for the column. ate a column of the
inferred type.
String table (Optional) The name of the table that contains the Column is in primary
column. If absent the column is assumed to be in the table.
primary table for the mapped object.
int precision (Optional) The precision for a decimal (exact 0 (Value must be set by
numeric) column. (Applies only if a decimal column developer.)
is used.)
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
Example 1:
Example 2:
@Column(name="DESC",
columnDefinition="CLOB NOT NULL",
table="EMP_DETAIL")
@Lob
public String getDescription() { return description; }
Example 3:
For the SINGLE_TABLE mapping strategy, and typically also for the JOINED strategy, the persistence
provider will use a type discriminator column. The DiscriminatorColumn annotation is used to
define the discriminator column for the SINGLE_TABLE and JOINED inheritance mapping strategies.
The strategy and the discriminator column are only specified in the root of an entity class hierarchy or
subhierarchy in which a different inheritance strategy is applied.
Table 9 lists the annotation elements that may be specified for a DiscriminatorColumn annotation
and their default values.
The type of the discriminator column, if specified in the optional columnDefinition element, must
be consistent with the discriminator type.
@Target({TYPE}) @Retention(RUNTIME)
public @interface DiscriminatorColumn {
String name() default "DTYPE";
DiscriminatorType discriminatorType() default STRING;
String columnDefinition() default "";
int length() default 31;
}
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
String columnDefinition (Optional) The SQL fragment that is used Provider-generated SQL to
when generating the DDL for the discrimina- create a column of the speci-
tor column. fied discriminator type.
Example:
@Entity
@Table(name="CUST")
@DiscriminatorColumn(name="DISC", discriminatorType=STRING,length=20)
public class Customer { ... }
@Entity
public class ValuedCustomer extends Customer { ... }
The DiscriminatorValue annotation is used to specify the value of the discriminator column for
entities of the given type. The DiscriminatorValue annotation can only be specified on a con-
crete entity class. If the DiscriminatorValue annotation is not specified and a discriminator col-
umn is used, a provider-specific function will be used to generate a value representing the entity type.
The inheritance strategy and the discriminator column are only specified in the root of an entity class
hierarchy or subhierarchy in which a different inheritance strategy is applied. The discriminator value, if
not defaulted, should be specified for each entity class in the hierarchy.
Table 10 lists the annotation elements that may be specified for a DiscriminatorValue annotation
and their default values.
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
The discriminator value must be consistent in type with the discriminator type of the specified or
defaulted discriminator column. If the discriminator type is an integer, the value specified must be able
to be converted to an integer value (e.g., "1").
@Target({TYPE}) @Retention(RUNTIME)
public @interface DiscriminatorValue {
String value();
}
String value (Optional) The value that indicates that If the DiscriminatorValue annotation is
the row is an entity of the annotated entity not specified, a provider-specific func-
type. tion to generate a value representing
the entity type is used for the value of
the discriminator column. If the Dis-
criminatorType is STRING, the dis-
criminator value default is the entity
name.
Example:
@Entity
@Table(name="CUST")
@Inheritance(strategy=SINGLE_TABLE)
@DiscriminatorColumn(name="DISC", discriminatorType=STRING,length=20)
@DiscriminatorValue("CUSTOMER")
public class Customer { ... }
@Entity
@DiscriminatorValue("VCUSTOMER")
public class ValuedCustomer extends Customer { ... }
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
Class target- (Optional) The basic or embeddable class that The parameterized type of the
Class is the element type of the collection. Optional collection when defined using
only if the collection field or property is generics.
defined using Java generics. Must be specified
otherwise.
Example:
@ElementCollection
protected Set<String> nickNames = new HashSet();
...
}
The Embeddable annotation is used to specify a class whose instances are stored as an intrinsic part
of an owning entity and share the identity of the entity.
@Target({TYPE}) @Retention(RUNTIME)
public @interface Embeddable {
}
Example 1:
@Embeddable
public class EmploymentPeriod {
@Temporal(DATE) java.util.Date startDate;
@Temporal(DATE) java.util.Date endDate;
...
}
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
Example 2:
Example 3:
The Embedded annotation is used to specify a persistent field or property of an entity or embeddable
class whose value is an instance of an embeddable class.[62] Each of the persistent properties or fields of
the embedded object is mapped to the database table for the entity or embeddable class. The
embeddable class must be annotated as Embeddable.
Implementations are not required to support embedded objects that are mapped across more than one
table (e.g., split across primary and secondary tables or multiple secondary tables).
[62] If the embeddable class is used as a primary key, the EmbeddedId rather than the Embedded annotation is used.
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
Example:
@Embedded
@AttributeOverrides({
@AttributeOverride(name="startDate",
column=@Column(name="EMP_START")),
@AttributeOverride(name="endDate",
column=@Column(name="EMP_END"))
})
public EmploymentPeriod getEmploymentPeriod() { ... }
The EmbeddedId annotation is applied to a persistent field or property of an entity class or mapped
superclass to denote a composite primary key that is an embeddable class. The embeddable class must
be annotated as Embeddable.[63]
The AttributeOverride annotation may be used to override the column mappings declared within
the embeddable class.[64]
There must be only one EmbeddedId annotation and no Id annotation when the EmbeddedId anno-
tation is used.
The MappedById annotation may be used in conjunction with the EmbeddedId annotation to spec-
ify a derived primary key. See Sections 2.4.1 and 9.1.31.
Example:
@EmbeddedId
protected EmployeePK empPK;
An Enumerated annotation specifies that a persistent property or field should be persisted as a enu-
merated type. The Enumerated annotation may be used in conjunction with the Basic annotation.
An enum can be mapped as either a string or an integer[65]. The EnumType enum defines the mapping
for enumerated types.
[63] Note that theId annotation is not used in the embeddable class.
[64] Relationship mappings defined within an embedded id class are not supported.
[65] Mapping of enum values that contain state is not supported.
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
If the enumerated type is not specified or the Enumerated annotation is not used, the enumerated type
is assumed to be ORDINAL.
Table 12 lists the annotation elements that may be specified for a Enumerated annotation and their
default values.
EnumType value (Optional) The type used in mapping an enum type. ORDINAL
Example:
@Enumerated(STRING)
public SalaryRate getPayScale() {...}
...
}
If the status property is mapped to a column of integer type, and the payscale property to a column of
varchar type, an instance that has a status of PART_TIME and a pay rate of JUNIOR will be stored with
STATUS set to 1 and PAYSCALE set to "JUNIOR".
The GeneratedValue annotation provides for the specification of generation strategies for the val-
ues of primary keys. The GeneratedValue annotation may be applied to a primary key property or
field of an entity or mapped superclass in conjunction with the Id annotation. [66] The use of the Gen-
eratedValue annotation is only required to be supported for simple primary keys. Use of the Gen-
eratedValue annotation is not supported for derived primary keys.
Table 13 lists the annotation elements that may be specified for a GeneratedValue annotation and
their default values.
[66] Portable applications should not use the GeneratedValue annotation on other persistent fields or properties.
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
The types of primary key generation are defined by the GenerationType enum:
The TABLE generator type value indicates that the persistence provider must assign primary keys for
the entity using an underlying database table to ensure uniqueness.
The SEQUENCE and IDENTITY values specify the use of a database sequence or identity column,
respectively.[67]
The AUTO value indicates that the persistence provider should pick an appropriate strategy for the par-
ticular database. The AUTO generation strategy may expect a database resource to exist, or it may
attempt to create one. A vendor may provide documentation on how to create such resources in the
event that it does not support schema generation or cannot create the schema resource at runtime.
This specification does not define the exact behavior of these strategies.
String generator (Optional) The name of the primary key gen- Default primary key generator
erator to use as specified in the SequenceGen- supplied by persistence pro-
erator or TableGenerator annotation. vider.
Example 1:
@Id
@GeneratedValue(strategy=SEQUENCE, generator="CUST_SEQ")
@Column(name="CUST_ID")
public Long getId() { return id; }
Example 2:
@Id
@GeneratedValue(strategy=TABLE, generator="CUST_GEN")
@Column(name="CUST_ID")
Long id;
[67] Note that SEQUENCE and IDENTITY are not portable across all databases.
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
9.1.17 Id Annotation
The Id annotation specifies the primary key property or field of an entity. The Id annotation may be
applied in an entity or mapped superclass.
By default, the mapped column for the primary key of the entity is assumed to be the primary key of the
primary table. If no Column annotation is specified, the primary key column name is assumed to be the
name of the primary key property or field.
Example:
@Id
public Long getId() { return id; }
The names of the fields or properties in the primary key class and the primary key fields or properties of
the entity must correspond and their types must match according to the rules specified in Section 2.4,
“Primary Keys and Entity Identity” and Section 2.4.1, “Primary Keys Corresponding to Derived Identi-
ties”.
The Id annotation must also be applied to the corresponding fields or properties of the entity.
@Target({TYPE}) @Retention(RUNTIME)
public @interface IdClass {
Class value();
}
Example:
@IdClass(com.acme.EmployeePK.class)
@Entity
public class Employee {
@Id String empName;
@Id Date birthDay;
...
}
The Inheritance annotation defines the inheritance strategy to be used for an entity class hierarchy.
It is specified on the entity class that is the root of the entity class hierarchy.
If the Inheritance annotation is not specified or if no inheritance type is specified for an entity class
hierarchy, the SINGLE_TABLE mapping strategy is used.
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
Support for the combination of inheritance strategies is not required by this specification. Portable
applications should only use a single inheritance strategy within an entity hierarchy.
The three inheritance mapping strategies are the single table per class hierarchy, joined subclass, and
table per concrete class strategies. See Section 2.12 for a more detailed discussion of inheritance strate-
gies. The inheritance strategy options are defined by the InheritanceType enum:
[Note to readers] We would like feedback as to the importance of requiring support for the table per class map-
ping strategy.
Table 14 lists the annotation elements that may be specified for a Inheritance annotation and their
default values.
@Target({TYPE}) @Retention(RUNTIME)
public @interface Inheritance {
InheritanceType strategy() default SINGLE_TABLE;
}
Example:
@Entity
@Inheritance(strategy=JOINED)
public class Customer { ... }
@Entity
public class ValuedCustomer extends Customer { ... }
The JoinColumn annotation is used to specify a mapped column for joining an entity association or
element collection.
Table 15 lists the annotation elements that may be specified for a JoinColumn annotation and their
default values.
If the JoinColumn annotation itself is defaulted, a single join column is assumed and the default val-
ues described in Table 15 apply.
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
The name annotation element defines the name of the foreign key column. The remaining annotation
elements (other than referencedColumnName) refer to this column and have the same semantics as
for the Column annotation.
If the referencedColumnName element is missing, the foreign key is assumed to refer to the pri-
mary key of the referenced table.
Support for referenced columns that are not primary key columns of the referenced table is optional.
Applications that use such mappings will not be portable.
If there is more than one join column, a JoinColumn annotation must be specified for each join col-
umn using the JoinColumns annotation. Both the name and the referencedColumnName ele-
ments must be specified in each such JoinColumn annotation.
String name (Optional) The name of the foreign key (Default only applies if a single
column. The table in which it is found join column is used.) The concat-
depends upon the context. If the join is for enation of the following: the name
a OneToOne or ManyToOne mapping of the referencing relationship
using a foreign key mapping strategy, the property or field of the referenc-
foreign key column is in the table of the ing entity or embeddable class;
source entity or embeddable. If the join is "_"; the name of the referenced
for a unidirectional OneToMany mapping primary key column. If there is no
using a foreign key mapping strategy, the such referencing relationship
foreign key is in the table of the target property or field in the entity, or if
entity. If the join is for a ManyToMany the join is for an element collec-
mapping or for a one-to-one or bidirec- tion, the join column name is
tional ManyToOne/OneToMany mapping formed as the concatenation of the
using a join table, the foreign key is in a following: the name of the entity;
join table. If the join is for an element col- "_"; the name of the referenced
lection, the foreign key is in a collection primary key column.
table.
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
String referencedCol- (Optional) The name of the column refer- (Default only applies if single join
umnName enced by this foreign key column. When column is being used.) The same
used with entity relationship mappings name as the primary key column
other than a unidirectional OneToMany of the referenced table.
foreign key mapping, the referenced col-
umn is in the table of the target entity.
When used with a unidirectional OneTo-
Many foreign key mapping, the referenced
column is in the table of the source entity.
When used inside a JoinTable annotation,
the referenced key column is in the entity
table of the owning entity, or inverse entity
if the join is part of the inverse join defini-
tion. When used in a collection table map-
ping, the referenced column is in the table
of the entity containing the collection.
String columnDefini- (Optional) The SQL fragment that is used Generated SQL for the column.
tion when generating the DDL for the column.
String table (Optional) The name of the table that con- If the join is for a OneToOne or
tains the column. ManyToOne mapping using a for-
eign key mapping strategy, the
name of the table of the source
entity or embeddable. If the join is
for a unidirectional OneToMany
mapping using a foreign key map-
ping strategy, the name of the
table of the target entity. If the
join is for a ManyToMany map-
ping or for a one-to-one or bidi-
rectional
ManyToOne/OneToMany map-
ping using a join table, the name
of the join table. If the join is for
an element collection, the name of
the collection table.
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
Example 1:
@ManyToOne
@JoinColumn(name="ADDR_ID")
public Address getAddress() { return address; }
In Customer class:
@OneToMany
@JoinColumn(name="CUST_ID") // join column is in table for Order
public Set<Order> getOrders() {return orders;}
Composite foreign keys are supported by means of the JoinColumns annotation. The JoinCol-
umns annotation groups JoinColumn annotations for the same relationship.
When the JoinColumns annotation is used, both the name and the referencedColumnName
elements must be specified in each of the grouped JoinColumn annotations.
Example:
@ManyToOne
@JoinColumns({
@JoinColumn(name="ADDR_ID", referencedColumnName="ID"),
@JoinColumn(name="ADDR_ZIP", referencedColumnName="ZIP")
})
public Address getAddress() { return address; }
public Customer getCustomer() { return customer; }
The JoinTable annotation is used in the mapping of entity associations. A JoinTable annotation
is specified on the owning side of the association. A join table is typically used in the mapping of
many-to-many and unidirectional one-to-many associations. It may also be used to map bidirectional
many-to-one/one-to-many associations and one-to-one associations (both bidirectional and unidirec-
tional).
Table 16 lists the annotation elements that may be specified for a JoinTable annotation and their
default values.
If the JoinTable annotation is not explicitly specified for the mapping of a many-to-many or unidi-
rectional one-to-many relationship, the default values of the annotation elements apply.
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
The name of the join table is assumed to be the table names of the associated primary tables concate-
nated together (owning side first) using an underscore.
When a join table is used in mapping a relationship with an embeddable class on the owning side of the
relationship, the containing entity rather than the embeddable class is considered the owner of the rela-
tionship.
String name (Optional) The name of the join table. The concatenated names of
the two associated primary
entity tables, separated by an
underscore.
String schema (Optional) The schema of the table. Default schema for user.
JoinColumn[] joinColumns (Optional) The foreign key columns The same defaults as for
of the join table which reference the JoinColumn.
primary table of the entity owning the
association (i.e. the owning side of
the association).
JoinColumn[] inverseJoinColumns (Optional) The foreign key columns The same defaults as for
of the join table which reference the JoinColumn.
primary table of the entity that does
not own the association (i.e. the
inverse side of the association).
Example:
@JoinTable(
name="CUST_PHONE",
joinColumns=
@JoinColumn(name="CUST_ID", referencedColumnName="ID"),
inverseJoinColumns=
@JoinColumn(name="PHONE_ID", referencedColumnName="ID")
)
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
A Lob annotation specifies that a persistent property or field should be persisted as a large object to a
database-supported large object type. Portable applications should use the Lob annotation when map-
ping to a database Lob type. The Lob annotation may be used in conjunction with the Basic annota-
tion. A Lob may be either a binary or character type. The Lob type is inferred from the type of the
persistent field or property, and except for string and character-based types defaults to Blob.
Example 1:
@Lob @Basic(fetch=EAGER)
@Column(name="REPORT")
protected String report;
Example 2:
@Lob @Basic(fetch=LAZY)
@Column(name="EMP_PIC", columnDefinition="BLOB NOT NULL")
protected byte[] pic;
Every many-to-many association has two sides, the owning side and the non-owning, or inverse, side.If
the association is bidirectional, either side may be designated as the owning side. If the relationship is
bidirectional, the non-owning side must use the mappedBy element of the ManyToMany annotation to
specify the relationship field or property of the owning side.
The join table for the relationship, if not defaulted, is specified on the owning side. .
The ManyToMany annotation may be used within an embeddable class contained within an entity class
to specify a relationship to a collection of entities[68].
If the relationship is bidirectional and the entity containing the embeddable class is the owner of the
relationship, the non-owning side must use the mappedBy element of the ManyToMany annotation to
specify the relationship field or property of the embeddable class. The dot (".") notation syntax must
be used in the mappedBy element to indicate the relationship attribute within the embedded attribute.
The value of each identifier used with the dot notation is the name of the respective embedded field or
property.
[68] The ManyToMany annotation may not be used within an embeddable class used in an element collection.
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
Table 17 lists these annotation elements that may be specified for a ManyToMany annotation and their
default values.
The cascade element specifies the set of cascadable operations that are propagated to the associated
entity. The operations that are cascadable are defined by the CascadeType enum:
The EAGER strategy is a requirement on the persistence provider runtime that the associated entity must
be eagerly fetched. The LAZY strategy is a hint to the persistence provider runtime that the associated
entity should be fetched lazily when it is first accessed. The implementation is permitted to eagerly
fetch associations for which the LAZY strategy hint has been specified.
When the collection is a java.util.Map, the cascade element applies to the map value.
Open Issue: Do we need a cascade option for the map key? If so, what form should this best
take?
Class targetEntity (Optional) The entity class that is the target The parameterized type of
of the association. Optional only if the col- the collection when defined
lection-valued relationship property is using generics.
defined using Java generics. Must be speci-
fied otherwise.
CascadeType[] cascade (Optional) The operations that must be cas- No operations are cascaded.
caded to the target of the association.
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
Example 1:
In Customer class:
@ManyToMany
@JoinTable(name="CUST_PHONES")
public Set<PhoneNumber> getPhones() { return phones; }
In PhoneNumber class:
@ManyToMany(mappedBy="phones")
public Set<Customer> getCustomers() { return customers; }
Example 2:
In Customer class:
@ManyToMany(targetEntity=com.acme.PhoneNumber.class)
public Set getPhones() { return phones; }
In PhoneNumber class:
@ManyToMany(targetEntity=com.acme.Customer.class, mappedBy="phones")
public Set getCustomers() { return customers; }
Example 3:
In Customer class:
@ManyToMany
@JoinTable(
name="CUST_PHONE",
joinColumns=
@JoinColumn(name="CUST_ID", referencedColumnName="ID"),
inverseJoinColumns=
@JoinColumn(name="PHONE_ID", referencedColumnName="ID")
)
public Set<PhoneNumber> getPhones() { return phones; }
In PhoneNumberClass:
@ManyToMany(mappedBy="phones")
public Set<Customer> getCustomers() { return customers; }
Example 4:
@Entity
public class Employee {
@Id int id;
@Embedded ContactInfo contactInfo;
...
}
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
@Embeddable
public class ContactInfo {
@ManyToOne Address address; // Unidirectional
@ManyToMany List<PhoneNumber> phoneNumbers; // Bidirectional
}
@Entity
public class PhoneNumber {
@Id int number;
@ManyToMany(mappedBy="contactInfo.phoneNumbers")
Collection<Employee> employees;
}
The ManyToOne annotation defines a single-valued association to another entity class that has
many-to-one multiplicity. It is not normally necessary to specify the target entity explicitly since it can
usually be inferred from the type of the object being referenced.
The ManyToOne annotation may be used within an embeddable class to specify a relationship from the
embeddable class to an entity class. If the relationship is bidirectional, the non-owning OneToMany
entity side must use the mappedBy element of the OneToMany annotation to specify the relationship
field or property of the embeddable field or property on the owning side of the relationship. The dot
(".") notation syntax must be used in the mappedBy element to indicate the relationship attribute
within the embedded attribute. The value of each identifier used with the dot notation is the name of the
respective embedded field or property.
Table 18 lists the annotation elements that may be specified for a ManyToOne annotation and their
default values.
The EAGER strategy is a requirement on the persistence provider runtime that the associated entity must
be eagerly fetched. The LAZY strategy is a hint to the persistence provider runtime that the associated
entity should be fetched lazily when it is first accessed. The implementation is permitted to eagerly
fetch associations for which the LAZY strategy hint has been specified.
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
Class targetEntity (Optional) The entity class that is the target of The type of the field or
the association. property that stores the
association.
CascadeType[] cascade (Optional) The operations that must be cas- No operations are cas-
caded to the target of the association. caded.
Example 1:
@ManyToOne(optional=false)
@JoinColumn(name="CUST_ID", nullable=false, updatable=false)
public Customer getCustomer() { return customer; }
Example 2:
@Entity
public class Employee {
@Id int id;
@Embedded JobInfo jobInfo;
...
}
@Embeddable
public class JobInfo {
String jobDescription;
@ManyToOne ProgramManager pm; // Bidirectional
}
@Entity
public class ProgramManager {
@Id int id;
@OneToMany(mappedBy="jobInfo.pm")
Collection<Employee> manages;
}
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
If a persistent field or property other than the primary key is used as a map key then it is expected to
have a uniqueness constraint associated with it.
The MapKeyClass annotation is not used when MapKey is specified and vice versa.
Example 1:
@Entity
public class Department {
...
@OneToMany(mappedBy="department")
@MapKey(name="empId")
public Map<Integer, Employee> getEmployees() {... }
...
}
@Entity
public class Employee {
...
@Id Integer getEmpid() { ... }
@ManyToOne
@JoinColumn(name="dept_id")
public Department getDepartment() { ... }
...
}
Example 2:
@Entity
public class Department {
...
@OneToMany(mappedBy="department")
@MapKey(name="empPK")
public Map<EmployeePK, Employee> getEmployees() {... }
...
}
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
@Entity
public class Employee {
@EmbeddedId public EmployeePK getEmpPK() { ... }
...
@ManyToOne
@JoinColumn(name="dept_id")
public Department getDepartment() { ... }
...
}
@Embeddable
public class EmployeePK implements Serializable {
String name;
Date bday;
}
The MapKeyClass annotation is used in conjunction with ElementCollection or one of the col-
lection-valued relationship annotations (OneToMany or ManyToMany).
The MapKey annotation is not used when MapKeyClass is specified and vice versa.
Example 1:
@Entity
public class Item {
@Id int id;
...
@ElementCollection(targetClass=String.class)
@MapKeyClass(String.class)
Map images; // map from image name to image filename
...
}
Example 2:
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
@Entity
public class Company {
@Id int id;
...
@OneToMany(targetEntity=com.example.VicePresident.class)
@MapKeyClass(com.example.Division.class)
Map organization;
}
Example 4:
@Entity
public class Company {
@Id int id;
...
@OneToMany
Map<Division, VicePresident> organization;
}
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
String name (Optional) The name of the map key col- The concatenation of the follow-
umn. The table in which it is found ing: the name of the referencing
depends upon the context. If the map property or field name; "_";
key is for an element collection, the map "KEY".
key column is in the collection table for
the map value. If the map key is for a
ManyToMany entity relationship or for a
OneToMany entity relationship using a
join table, the map key column is in a
join table. If the map key is for a OneTo-
Many entity relationship using a foreign
key mapping strategy, the map key col-
umn is in the table of the entity that is
the value of the map.
String columnDefinition (Optional) The SQL fragment that is Generated SQL to create a column
used when generating the DDL for the of the inferred type.
column.
String table (Optional) The name of the table that If the map key is for an element
contains the column. collection, the name of the collec-
tion table for the map value. If the
map key is for a OneToMany or
ManyToMany entity relationship
using a join table, the name of the
join table for the map. If the map
key is for a OneToMany entity
relationship using a foreign key
mapping strategy, the name of the
primary table of the entity that is
the value of the map
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
int precision (Optional) The precision for a decimal 0 (Value must be set by developer.)
(exact numeric) column. (Applies only if
a decimal column is used.)
Example:
@Entity
public class Item {
@Id int id;
...
@ElementCollection
@MapKeyColumn(name="IMAGE_NAME")
@Column(name="IMAGE_FILENAME")
@CollectionTable(name="IMAGE_MAPPING")
Map<String, String> images; // map from image name to filename
...
}
Table 20 lists the annotation elements that may be specified for a MapKeyJoinColumn annotation
and their default values.
If no MapKeyJoinColumn annotation is specified, a single join column is assumed and the default
values described below (and in Table 20) apply.
The name annotation element defines the name of the foreign key column. The remaining annotation
elements (other than referencedColumnName) refer to this column.
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
If there is a single map key join column, and if the name annotation member is missing, the map key
join column name is formed as the concatenation of the following: the name of the referencing relation-
ship property or field of the referencing entity or embeddable; "_"; "KEY".
Open Issue: Or should this be the name of the referencing relationship property or field of the
referencing entity or embeddable; "_"; the name of the referenced primary key column?
If the referencedColumnName element is missing, the foreign key is assumed to refer to the pri-
mary key of the referenced table. Support for referenced columns that are not primary key columns of
the referenced table is optional. Applications that use such mappings will not be portable.
If there is more than one map key join column, a MapKeyJoinColumn annotation must be specified
for each join column using the MapKeyJoinColumns annotation. Both the name and the refer-
encedColumnName elements must be specified in each such MapKeyJoinColumn annotation.
String name (Optional) The name of the foreign key (Default only applies if a
column for the map key. The table in single join column is used.)
which it is found depends upon the con- The concatenation of the
text. If the join is for a map key for an following: the name of the
element collection, the foreign key col- referencing relationship
umn is in the collection table for the map property or field of the ref-
value. If the join is for a map key for a erencing entity or
ManyToMany entity relationship or for a embeddable class; "_";
OneToMany entity relationship using a "KEY".
join table, the foreign key column is in a
join table. If the join is for a OneToMany
entity relationship using a foreign key
mapping strategy, the foreign key col-
umn for the map key is in the table of the
entity that is the value of the map.
String referencedColumnName (Optional) The name of the column ref- (Default only applies if sin-
erenced by this foreign key column. The gle join column is being
referenced column is in the table of the used.) The same name as
target entity. the primary key column of
the referenced table.
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
String columnDefinition (Optional) The SQL fragment that is Generated SQL for the col-
used when generating the DDL for the umn.
column.
String table (Optional) The name of the table that If the map key is for an ele-
contains the foreign key column. If the ment collection, the name
join is for a map key for an element col- of the collection table for
lection, the foreign key column is in the the map value. If the map
collection table for the map value. If the key is for a OneToMany or
join is for a map key for a ManyToMany ManyToMany entity rela-
entity relationship or for a OneToMany tionship using a join table,
entity relationship using a join table, the the name of the join table
foreign key column is in a join table. If for the map. If the map key
the join is for a OneToMany entity rela- is for a OneToMany entity
tionship using a foreign key mapping relationship using a foreign
strategy, the foreign key column for the key mapping strategy, the
map key is in the table of the entity that name of the primary table of
is the value of the map. the entity that is the value of
the map.
Example 1:
@Entity
public class Company {
@Id int id;
...
@OneToMany // unidirectional
@JoinTable(name="COMPANY_ORGANIZATION",
joinColumns=@JoinColumn(name="COMPANY"),
inverseJoinColumns=@JoinColumn(name="VICEPRESIDENT"))
@MapKeyJoinColumn(name="DIVISION")
Map<Division, VicePresident> organization;
}
Example 2:
@Entity
public class VideoStore {
@Id int id;
String name;
Address location;
...
@ElementCollection
@CollectionTable(name="INVENTORY",
joinColumns=@JoinColumn(name="STORE"))
@Column(name="COPIES_IN_STOCK")
@MapKeyJoinColumn(name="MOVIE", referencedColumnName="ID")
Map<Movie, Integer> videoInventory;
...
}
@Entity
public class Movie {
@Id long id;
String title;
...
}
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
Example 3:
@Entity
public class Student {
@Id int studentId;
...
@ManyToMany // students and courses are also many-many
@JoinTable(name="ENROLLMENTS",
joinColumns=@JoinColumn(name="STUDENT"),
inverseJoinColumns=@JoinColumn(name="SEMESTER"))
@MapKeyJoinColumn(name="COURSE")
Map<Course, Semester> enrollment;
...
}
When the MapKeyJoinColumns annotation is used, both the name and the referencedCol-
umnName elements must be specified in each of the grouped MapKeyJoinColumn annotations.
The value attribute specifies the attribute within a composite key to which the relationship attribute
corresponds. If the entity’s primary key is of the same Java type as the primary key of the entity refer-
enced by the relationship, the value attribute is not specified.
Open Issue: Allow MappedBy to be extended to mapping against non-id persistent attributes?
Example:
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
@Entity
public class Employee {
@Id long empId;
String name;
...
}
@Embeddable
public class DependentId {
String name;
long empid; // corresponds to PK type of Employee
}
@Entity
public class Dependent {
@EmbeddedId DependentId id;
...
@MappedById("empid") // maps to empid attribute of embedded id
@ManyToOne Employee emp;
}
A class designated with the MappedSuperclass annotation can be mapped in the same way as an
entity except that the mappings will apply only to its subclasses since no table exists for the mapped
superclass itself. When applied to the subclasses the inherited mappings will apply in the context of the
subclass tables. Mapping information may be overridden in such subclasses by using the Attribu-
teOverride and AttributeOverrides annotations.
@Target(TYPE) @Retention(RUNTIME)
public @interface MappedSuperclass {}
Table 21 lists the annotation elements that may be specified for a OneToMany annotation and their
default values.
If the collection is defined using generics to specify the element type, the associated target entity class
need not be specified; otherwise it must be specified.
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
The OneToMany annotation may be used within an embeddable class contained within an entity class
to specify a relationship to a collection of entities[69]. If the relationship is bidirectional, the mappedBy
element must be used to specify the relationship field or property of the entity that is the owner of the
relationship.
When the collection is a java.util.Map, the cascade element applies to the map value.
Open Issue: Do we need a cascade option for the map key? If so, what form should this best
take?
If orphanRemoval is true and an entity that is the target of the relationship is removed from the
relationship (either by removal from the collection or by setting the relationship to null), the remove
operation will be applied to the entity being orphaned. If the entity being orphaned is a detached, new,
or removed entity, the semantics of orphanRemoval do not apply.
If orphanRemoval is true and the remove operation is applied to the source entity, the remove
operation will be cascaded to the relationship target in accordance with the rules of section 3.2.3, (and
hence it is not necessary to specify cascade=REMOVE for the relationship)[70].
The remove operation is applied at the time of the flush operation. The orphanRemoval functionality
is intended for entities that are privately "owned" by their parent entity. Portable applications must oth-
erwise not depend upon a specific order of removal, and must not reassign an entity that has been
orphaned to another relationship or otherwise attempt to persist it.
[Note to readers] Open Issue: We also discussed the alternative of introducing a separate annotation for the
orphanRemoval functionality and the alternative of introducing a REMOVE_ORPHAN cas-
cade option. We would welcome feedback on the form that this metadata should take.
The default schema-level mapping for unidirectional one-to-many relationships uses a join table, as
described in Section 2.10.5. Unidirectional one-to-many relationships may be implemented using
one-to-many foreign key mappings, using the JoinColumn and JoinColumns annotations.
[69] The OneToMany annotation may not be used within an embeddable class used in an element collection.
[70] If the parent is detached or new or was previously removed before the orphan was associated with it, the remove operation is not
applied to the entity being orphaned.
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
Class targetEntity (Optional) The entity class that is the target The parameterized type of
of the association. Optional only if the col- the collection when defined
lection-valued relationship property is using generics.
defined using Java generics. Must be speci-
fied otherwise.
CascadeType[] cascade (Optional) The operations that must be cas- No operations are cascaded.
caded to the target of the association.
In Customer class:
In Order class:
@ManyToOne
@JoinColumn(name="CUST_ID", nullable=false)
public Customer getCustomer() { return customer; }
In Customer class:
@OneToMany(targetEntity=com.acme.Order.class, cascade=ALL,
mappedBy=”customer”, orphanRemoval=true)
public Set getOrders() { return orders; }
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
In Order class:
@ManyToOne
@JoinColumn(name="CUST_ID", nullable=false)
protected Customer customer;
In Customer class:
@OneToMany(orphanRemoval=true)
@JoinColumn(name="CUST_ID") // join column is in table for Order
public Set<Order> getOrders() {return orders;}
The OneToOne annotation defines a single-valued association to another entity that has one-to-one
multiplicity. It is not normally necessary to specify the associated target entity explicitly since it can
usually be inferred from the type of the object being referenced.
If the relationship is bidirectional, the mappedBy element must be used to specify the relationship field
or property of the entity that is the owner of the relationship.
The OneToOne annotation may be used within an embeddable class to specify a relationship from the
embeddable class to an entity class. If the relationship is bidirectional and the entity containing the
embeddable class is on the owning side of the relationship, the non-owning side must use the
mappedBy element of the OneToOne annotation to specify the relationship field or property of the
embeddable class. The dot (".") notation syntax must be used in the mappedBy element to indicate
the relationship attribute within the embedded attribute. The value of each identifier used with the dot
notation is the name of the respective embedded field or property.
Table 22 lists the annotation elements that may be specified for a OneToOne annotation and their
default values.
If orphanRemoval is true and an entity that is the target of the relationship is removed from the
relationship (by setting the relationship to null), the remove operation will be applied to the entity being
orphaned. If the entity being orphaned is a detached, new, or removed entity, the semantics of
orphanRemoval do not apply.
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
If orphanRemoval is true and the remove operation is applied to the source entity, the remove
operation will be cascaded to the relationship target in accordance with the rules of section 3.2.3, (and
hence it is not necessary to specify cascade=REMOVE for the relationship)[71].
The remove operation is applied at the time of the flush operation. The orphanRemoval functionality
is intended for entities that are privately "owned" by their parent entity. Portable applications must oth-
erwise not depend upon a specific order of removal, and must not reassign an entity that has been
orphaned to another relationship or otherwise attempt to persist it.
Class targetEntity (Optional) The entity class that is the target of The type of the field or
the association. property that stores the
association.
CascadeType[] cascade (Optional) The operations that must be cas- No operations are cas-
caded to the target of the association. caded.
On Customer class:
@OneToOne(optional=false)
@JoinColumn(
name="CUSTREC_ID", unique=true, nullable=false, updatable=false)
public CustomerRecord getCustomerRecord() { return customerRecord; }
[71] If the parent is detached or new or was previously removed before the orphan was associated with it, the remove operation is not
applied to the entity being orphaned.
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
On CustomerRecord class:
@OneToOne(optional=false, mappedBy="customerRecord")
public Customer getCustomer() { return customer; }
Example 2: One-to-one association where both source and target share the same primary key values.
On Employee class:
@Entity
public class Employee {
@Id Integer id;
@OneToOne(orphanRemoval=true)
@MappedById
EmployeeInfo info;
...
}
On EmployeeInfo class:
@Entity
public class EmployeeInfo {
@Id Integer id;
...
}
@Entity
public class Employee {
@Id int id;
@Embedded LocationDetails location;
...
}
@Embeddable
public class LocationDetails {
int officeNumber;
@OneToOne ParkingSpot parkingSpot;
...
}
@Entity
public class ParkingSpot {
@Id int id;
String garage;
@OneToOne(mappedBy="location.parkingSpot") Employee assignedTo;
...
}
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
If orderby_list is not specified or if ASC or DESC is not specified, ASC (ascending order) is assumed.
If the ordering element is not specified for an entity association, ordering by the primary key of the
associated entity is assumed.[72]
A property or field name specified as an orderby_item must correspond to a basic persistent property
or field of the associated class or embedded class within it. The properties or fields used in the ordering
must correspond to columns for which comparison operators are supported.
The dot (".") notation is used to refer to an attribute within an embedded attribute. The value of each
identifier used with the dot notation is the name of the respective embedded field or property.
The OrderBy annotation may be applied to an element collection. To specify an ordering by a basic
type, the orderby_item is referred to as "value".
Open Issue: Specification of ordering by a basic type. Should this be “element” or some
other name?
The OrderBy annotation is not used when an order column is specified. See section 9.1.36.
Example 1:
[72] If the primary key is a composite primary key, the precedence of ordering among the attributes within the primary key is not
futher defined. To assign such a precedence within these attributes, each of the individual attributes must be specified as an
orderby_item.
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
Example 2:
Example 3:
[73] The OrderBy annotation should be used for ordering that is visible as persistent state and maintained by the application.
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
Table 23 lists the annotation elements that may be specified for an OrderColumn annotation and their
default values.
If name is not specified, the column name is the concatenation of the following: the name of the refer-
encing relationship property or field of the referencing entity or embeddable class; "_"; "ORDER".
The contiguous element specifies whether the values of the order column need to be contiguous (the
default) or may be sparse. If contiguous is true, the order column must be of integral type. If con-
tiguous is false, the list order cannot be (portably) queried.
The base element specifies the column value for the first element of the list.
Open Issue: Should the default for the base element be 0 or 1? Note that this has impact on
queries.
The table element specifies the table containing the order column. By default: if the relationship is a
many-to-many or unidirectional one-to-many relationship, the table is the join table for the relationship;
if the relationship is a bidirectional one-to-many or unidirectional one-to-many mapped by a join col-
umn, the table is the primary table for the entity on the many side of the relationship; if the ordering is
for a collection of elements, the table is the collection table for the element collection.
String name (Optional) The name of the ordering col- The concatenation of the name of
umn. the referencing property or field;
"_"; "ORDER".
boolean nullable (Optional) Whether the database column true
is nullable.
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
String columnDefinition (Optional) The SQL fragment that is Generated SQL to create a column
used when generating the DDL for the of the inferred type.
column.
String table (Optional) The name of the table that If the relationship is a
contains the column. many-to-many or unidirectional
one-to-many relationship, the
table is the join table for the
relationship. If the relationship
is a bidirectional one-to-many
or unidirectional one-to-many
mapped by a join column, the
table is the primary table for the
entity on the mapny side of the
relationship. If the ordering is
for a collection of elements, the
table is the collection table for
the element collection.
Example 1:
@Entity
public class CreditCard {
@OneToMany // unidirectional
@OrderColumn
List<CardTransaction> transactionHistory;
...
}
Example 2:
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
SELECT s
FROM course c JOIN c.waitlist w, student s
WHERE c.name = "geometry" AND w[0] = s
The PrimaryKeyJoinColumn annotation specifies a primary key column that is used as a foreign
key to join to another table.
The PrimaryKeyJoinColumn annotation is used to join the primary table of an entity subclass in
the JOINED mapping strategy to the primary table of its superclass; it is used within a Second-
aryTable annotation to join a secondary table to a primary table; and it may be used in a OneToOne
mapping in which the primary key of the referencing entity is used as a foreign key to the referenced
entity[74].
Table 24 lists the annotation elements that may be specified for a PrimaryKeyJoinColumn annota-
tion and their default values.
[74] The derived id mechanisms described in section 2.4.1.1 are now to be preferred over PrimaryKeyJoinColumn for the OneToOne
mapping case.
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
String name The name of the primary key col- The same name as the primary key
umn of the current table. column of the primary table of the
superclass (JOINED mapping strat-
egy); the same name as the primary
key column of the primary table
(SecondaryTable mapping); or the
same name as the primary key col-
umn for the table for the referencing
entity (OneToOne mapping).
String referencedColumnName (Optional) The name of the pri- The same name as the primary key
mary key column of the table column of the primary table of the
being joined to. superclass (JOINED mapping strat-
egy); the same name as the primary
key column of the primary table
(SecondaryTable mapping); or the
same name as the primary key col-
umn of the table for the referenced
entity (OneToOne mapping).
String columnDefinition (Optional) The SQL fragment that Generated SQL to create a column
is used when generating the DDL of the inferred type.
for the column. This should not be
specified for a OneToOne primary
key association.
@Entity
@Table(name="CUST")
@Inheritance(strategy=JOINED)
@DiscriminatorValue("CUST")
public class Customer { ... }
@Entity
@Table(name="VCUST")
@DiscriminatorValue("VCUST")
@PrimaryKeyJoinColumn(name="CUST_ID")
public class ValuedCustomer extends Customer { ... }
Composite foreign keys are supported by means of the PrimaryKeyJoinColumns annotation. The
PrimaryKeyJoinColumns annotation groups PrimaryKeyJoinColumn annotations.
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
@Entity
@Table(name="VCUST")
@DiscriminatorValue("VCUST")
@PrimaryKeyJoinColumns({
@PrimaryKeyJoinColumn(name="CUST_ID",
referencedColumnName="ID"),
@PrimaryKeyJoinColumn(name="CUST_TYPE",
referencedColumnName="TYPE")
})
public class ValuedCustomer extends Customer { ... }
@Entity
@IdClass(com.acme.EmpPK.class)
public class Employee {
@OneToOne
@PrimaryKeyJoinColumns({
@PrimaryKeyJoinColumn(name="ID", referencedColumn-
Name="EMP_ID"),
@PrimaryKeyJoinColumn(name="NAME", referencedColumn-
Name="EMP_NAME")})
EmployeeInfo info;
...
}
@Entity
@IdClass(com.acme.EmpPK.class)
public class EmployeeInfo {
@Id @Column(name="EMP_ID")
Integer id;
@Id @Column(name="EMP_NAME")
String name;
...
}
[75] Note that the derived identity mechanisms decribed in section 2.4.1.1 is now preferred to the use of PrimaryKeyJoinColumn for
this case.
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
The SecondaryTable annotation is used to specify a secondary table for the annotated entity class.
Table 25 lists the annotation elements that may be specified for a SecondaryTable annotation and
their default values.
If no primary key join columns are specified, the join columns are assumed to reference the primary key
columns of the primary table, and have the same names and types as the referenced primary key col-
umns of the primary table.
@Target({TYPE}) @Retention(RUNTIME)
public @interface SecondaryTable {
String name();
String catalog() default "";
String schema() default "";
PrimaryKeyJoinColumn[] pkJoinColumns() default {};
UniqueConstraint[] uniqueConstraints() default {};
}
String schema (Optional) The schema of the table. Default schema for user
PrimaryKeyJoin- pkJoinColumns (Optional) The columns that are Column(s) of the same
Column[] used to join with the primary table. name(s) as the primary key
column(s) in the primary
table
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
@Entity
@Table(name="CUSTOMER")
@SecondaryTable(name="CUST_DETAIL",
pkJoinColumns=@PrimaryKeyJoinColumn(name="CUST_ID"))
public class Customer { ... }
@Entity
@Table(name="CUSTOMER")
@SecondaryTable(name="CUST_DETAIL",
pkJoinColumns={
@PrimaryKeyJoinColumn(name="CUST_ID"),
@PrimaryKeyJoinColumn(name="CUST_TYPE")})
public class Customer { ... }
@Target({TYPE}) @Retention(RUNTIME)
public @interface SecondaryTables {
SecondaryTable[] value();
}
Example 1: Multiple secondary tables assuming primary key columns are named the same in all tables.
@Entity
@Table(name="EMPLOYEE")
@SecondaryTables({
@SecondaryTable(name="EMP_DETAIL"),
@SecondaryTable(name="EMP_HIST")
})
public class Employee { ... }
Example 2: Multiple secondary tables with differently named primary key columns.
@Entity
@Table(name="EMPLOYEE")
@SecondaryTables({
@SecondaryTable(name="EMP_DETAIL",
pkJoinColumns=@PrimaryKeyJoinColumn(name="EMPL_ID")),
@SecondaryTable(name="EMP_HIST",
pkJoinColumns=@PrimaryKeyJoinColumn(name="EMPLOYEE_ID"))
})
public class Employee { ... }
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
The SequenceGenerator annotation defines a primary key generator that may be referenced by
name when a generator element is specified for the GeneratedValue annotation. A sequence gener-
ator may be specified on the entity class or on the primary key field or property. The scope of the gener-
ator name is global to the persistence unit (across all generator types).
Table 26 lists the annotation elements that may be specified for a SequenceGenerator annotation
and their default values.
String sequenceName (Optional) The name of the database sequence object from which A provider-
to obtain primary key values. chosen
value
String catalog (Optional) The catalog of the sequence generator. Default cat-
alog
int initialValue (Optional) The value from which the sequence object is to start 1
generating.
Example:
@SequenceGenerator(name="EMP_SEQ", allocationSize=25)
The Table annotation specifies the primary table for the annotated entity. Additional tables may be
specified using SecondaryTable or SecondaryTables annotation.
Table 27 lists the annotation elements that may be specified for a Table annotation and their default
values.
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
If no Table annotation is specified for an entity class, the default values defined in Table 27 apply.
@Target({TYPE}) @Retention(RUNTIME)
public @interface Table {
String name() default "";
String catalog() default "";
String schema() default "";
UniqueConstraint[] uniqueConstraints() default {};
}
Example:
@Entity
@Table(name="CUST", schema="RECORDS")
public class Customer { ... }
The TableGenerator annotation defines a primary key generator that may be referenced by name
when a generator element is specified for the GeneratedValue annotation. A table generator may be
specified on the entity class or on the primary key field or property. The scope of the generator name is
global to the persistence unit (across all generator types).
Table 28 lists the annotation elements that may be specified for a TableGenerator annotation and
their default values.
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
The table element specifies the name of the table that is used by the persistence provider to store gen-
erated primary key values for entities. An entity type will typically use its own row in the table for the
generation of primary key values. The primary key values are normally positive integers.
String table (Optional) Name of table that stores the Name is chosen by persistence
generated primary key values. provider
String schema (Optional) The schema of the table. Default schema for user
String pkColumnName (Optional) Name of the primary key col- A provider-chosen name
umn in the table.
String valueColumn- (Optional) Name of the column that stores A provider-chosen name
Name the last value generated.
String pkColumnValue (Optional) The primary key value in the A provider-chosen value to store
generator table that distinguishes this set in the primary key column of the
of generated values from others that may generator table
be stored in the table.
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
Example 1:
Example 2:
The Temporal annotation must be specified for persistent fields or properties of type
java.util.Date and java.util.Calendar. It may only be specified for fields or properties of
these types.
The Temporal annotation may be used in conjunction with the Basic or Id annotation.
The TemporalType enum defines the mapping for these temporal types.
Annotations for Object/Relational Mapping Java Persistence 2.0, Early Draft Metadata for Object/Relational Mapping
Table 29 lists the annotation elements that may be specified for a Temporal annotation and their
default values.
Example:
@Embeddable
public class EmploymentPeriod {
@Temporal(DATE) java.util.Date startDate;
@Temporal(DATE) java.util.Date endDate;
...
}
Example:
@Entity
public class Employee {
@Id int id;
@Transient User currentUser;
...
}
Table 30 lists the annotation elements that may be specified for a UniqueConstraint annotation.
@Target({}) @Retention(RUNTIME)
public @interface UniqueConstraint {
String[] columnNames();
}
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Annotations for Object/Relational Mapping
String[] columnNames (Required) An array of the column names that make up the
constraint.
Example:
@Entity
@Table(
name="EMPLOYEE",
uniqueConstraints=
@UniqueConstraint(columnNames={"EMP_ID", "EMP_NAME"})
)
public class Employee { ... }
The Version annotation specifies the version field or property of an entity class that serves as its opti-
mistic lock value. The version is used to ensure integrity when performing the merge operation and for
optimistic concurrency control.
Only a single Version property or field should be used per class; applications that use more than one
Version property or field will not be portable.
The Version property should be mapped to the primary table for the entity class; applications that
map the Version property to a table other than the primary table will not be portable.
In general, fields or properties that are specified with the Version annotation should not be updated
by the application.[76]
The following types are supported for version properties: int, Integer, short, Short, long,
Long, Timestamp.
Example:
@Version
@Column(name="OPTLOCK")
protected int getVersionNum() { return versionNum; }
Examples of the Application of Annotations for Object/Relational MappingJava Persistence 2.0, Early Draft Metadata for Object/Rela-
@Entity
public class Customer {
@Entity
public class Address {
@Version
public int getVersion() { return version; }
protected void setVersion(int version) {
this.version = version;
}
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Examples of the Application of Annotations for
@Entity
public class Order {
@Id @GeneratedValue(strategy=AUTO)
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
@Version
protected int getVersion() { return version; }
protected void setVersion(int version) {
this.version = version;
}
@ManyToOne
public Customer getCustomer() { return cust; }
public void setCustomer(Customer cust) {
this.cust = cust;
}
}
@Entity
@Table(name="DLVY_SVC")
public class DeliveryService {
@Id
public String getServiceName() { return serviceName; }
public void setServiceName(String serviceName) {
this.serviceName = serviceName;
}
public int getPriceCategory() { return priceCategory; }
Examples of the Application of Annotations for Object/Relational MappingJava Persistence 2.0, Early Draft Metadata for Object/Rela-
@ManyToMany(targetEntity=com.acme.Customer.class)
@JoinTable(name="CUST_DLVRY")
public Collection getCustomers() { return customers; }
public setCustomers(Collection customers) {
this.customers = customers;
}
}
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Examples of the Application of Annotations for
@Entity
@Table(name="EMPL")
@SecondaryTable(name="EMP_SALARY",
pkJoinColumns=@PrimaryKeyJoinColumn(name="EMP_ID",
referencedColumnName="ID"))
public class Employee implements Serializable {
@Id @GeneratedValue(strategy=TABLE)
public Integer getId() { return id; }
protected void setId(Integer id) { this.id = id; }
@Version
@Column(name="EMP_VERSION", nullable=false)
public int getVersion() { return version; }
protected void setVersion(int version) {
this.version = version;
}
@Column(name="EMP_NAME", length=80)
public String getName() { return name; }
public void setName(String name) { this.name = name; }
@ManyToOne(cascade=PERSIST, optional=false)
@JoinColumn(name="ADDR_ID",
referencedColumnName="ID", nullable=false)
public Address getAddress() { return address; }
public void setAddress(Address address) {
this.address = address;
}
@OneToMany(targetEntity=com.acme.PhoneNumber.class,
cascade=ALL, mappedBy="employee")
public Collection getPhoneNumbers() { return phoneNumbers; }
public void setPhoneNumbers(Collection phoneNumbers) {
this.phoneNumbers = phoneNumbers;
}
@ManyToMany(cascade=PERSIST, mappedBy="employees")
@JoinTable(
name="EMP_PROJ",
joinColumns=@JoinColumn(
name="EMP_ID", referencedColumnName="ID"),
inverseJoinColumns=@JoinColumn(
name="PROJ_ID", referencedColumnName="ID"))
public Collection<Project> getProjects() { return projects; }
public void setProjects(Collection<Project> projects) {
Examples of the Application of Annotations for Object/Relational MappingJava Persistence 2.0, Early Draft Metadata for Object/Rela-
this.projects = projects;
}
@Column(name="EMP_SAL", table="EMP_SALARY")
public Long getSalary() { return salary; }
public void setSalary(Long salary) {
this.salary = salary;
}
@Embedded
@AttributeOverrides({
@AttributeOverride(name="startDate",
column=@Column(name="EMP_START")),
@AttributeOverride(name="endDate",
column=@Column(name="EMP_END"))
})
public EmploymentPeriod getEmploymentPeriod() {
return period;
}
public void setEmploymentPeriod(EmploymentPeriod period) {
this.period = period;
}
}
@Entity
public class Address implements Serializable {
@Id @GeneratedValue(strategy=IDENTITY)
public Integer getId() { return id; }
protected void setId(Integer id) { this.id = id; }
@Column(name="RUE")
public String getStreet() { return street; }
public void setStreet(String street) {
this.street = street;
}
@Column(name="VILLE")
public String getCity() { return city; }
public void setCity(String city) { this.city = city; }
}
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Examples of the Application of Annotations for
@Table(name="PHONE")
public class PhoneNumber implements Serializable {
@Id
public String getNumber() { return number; }
public void setNumber(String number) {
this.number = number;
}
@Column(name="PTYPE")
public int getPhonetype() { return phonetype; }
public void setPhoneType(int phoneType) {
this.phoneType = phoneType;
}
@ManyToOne(optional=false)
@JoinColumn(name="EMP_ID", nullable=false)
public Employee getEmployee() { return employee; }
public void setEmployee(Employee employee) {
this.employee = employee;
}
}
@Entity
@Inheritance(strategy=JOINED)
DiscriminatorValue("Proj")
@DiscriminatorColumn(name="DISC")
public class Project implements Serializable {
@Id @GeneratedValue(strategy=TABLE)
public Integer getId() { return projId; }
protected void setId(Integer id) { this.projId = id; }
@Version
public int getVersion() { return version; }
protected void setVersion(int version) { this.version = version; }
@Column(name="PROJ_NAME")
public String getName() { return name; }
public void setName(String name) { this.name = name; }
@ManyToMany(mappedBy="projects")
public Set<Employee> getEmployees() { return employees; }
public void setEmployees(Set<Employee> employees) {
this.employees = employees;
}
}
Examples of the Application of Annotations for Object/Relational MappingJava Persistence 2.0, Early Draft Metadata for Object/Rela-
@Entity
@Table(name="GOVT_PROJECT")
@DiscriminatorValue("GovtProj")
@PrimaryKeyJoinColumn(name="GOV_PROJ_ID",
referencedColumnName="ID")
public class GovernmentProject extends Project {
private String fileInfo;
@Column(name="INFO")
public String getFileInfo() { return fileInfo; }
public void setFileInfo(String fileInfo) {
this.fileInfo = fileInfo;
}
}
@Entity
@Table(name="C_PROJECT")
@DiscriminatorValue("CovProj")
@PrimaryKeyJoinColumn(name="COV_PROJ_ID",
referencedColumnName="ID")
public class CovertProject extends Project {
@Column(updatable=false)
public String getClassified() { return classified; }
protected void setClassified(String classified) {
this.classified = classified;
}
}
@Embeddable
public class EmploymentPeriod implements Serializable {
@Column(nullable=false)
public Date getStartDate() { return start; }
public void setStartDate(Date start) {
this.start = start;
Metadata for Object/Relational Mapping Java Persistence 2.0, Early Draft Examples of the Application of Annotations for
}
public Date getEndDate() { return end; }
public void setEndDate(Date end) {
this.end = end;
}
}
XML Overriding Rules Java Persistence 2.0, Early Draft XML Descriptor
C ha p t e r 1 0 XML Descriptor
The XML descriptor is intended to serve as both an alternative to and an overriding mecha-
nism for Java language metadata annotations.
[Note to reviewers] This chapter and the XML O/R mapping descriptor will be updated to cover the new mapping
metadata introduced via annotations, once that metadata is finalized.
This section defines the rules that apply when the XML descriptor is used to override annotations, and
the rules pertaining to the interaction of XML elements specified as subelements of the persis-
tence-unit-defaults, entity-mappings, entity, mapped-superclass, and
embeddable elements.
XML Descriptor Java Persistence 2.0, Early Draft XML Overriding Rules
10.1.1.1 schema
The schema subelement applies to all entities, table generators, and join tables in the persistence unit.
The schema subelement is overridden by any schema subelement of the entity-mappings ele-
ment; any schema element explicitly specified in the Table or SecondaryTable annotation on an
entity or any schema attribute on any table or secondary-table subelement defined within an
entity element; any schema element explicitly specified in a TableGenerator annotation or
table-generator subelement; and any schema element explicitly specified in a JoinTable
annotation or join-table subelement.
10.1.1.2 catalog
The catalog subelement applies to all entities, table generators, and join tables in the persistence unit.
10.1.1.3 access
The access subelement applies to all managed classes in the persistence unit.
The access subelement is overridden by the use of any annotations specifying mapping information
on the fields or properties of the entity class, by any access subelement of the entity-mappings
element, or by any access attribute defined within an entity, mapped-superclass, or
embeddable XML element.
10.1.1.4 cascade-persist
Specifying this subelement adds the cascade persist option to all relationships in addition to any settings
specified in annotations or XML.
[77] If the xml-mapping-metadata-complete element is specified, any metadata-complete attributes specified within
the entity, mapped-superclass, and embeddable elements are ignored.
XML Overriding Rules Java Persistence 2.0, Early Draft XML Descriptor
10.1.1.5 entity-listeners
The entity-listeners subelement defines default entity listeners for the persistence unit. These
entity listeners are called before any other entity listeners for an entity unless the entity listener order is
overridden within a mapped-superclass or entity element, or the ExcludeDefaultLis-
teners annotation is present on the entity or mapped superclass or if the
exclude-default-listeners subelement is specified within the corresponding entity or
mapped-superclass XML element.
10.1.2.1 package
The package subelement specifies the package of the classes listed within the subelements and
attributes of the same mapping file only. The package subelement is overridden if the fully qualified
class name is specified for a class and the two disagree.
10.1.2.2 schema
The schema subelement applies only to the entities listed within the same mapping file.
The schema subelement is overridden by any schema element explicitly specified in the Table or
SecondaryTable annotation on an entity listed within the mapping file, or any schema attribute on
any table or secondary-table subelement defined within an such an entity element.
10.1.2.3 catalog
The catalog subelement applies only to the entities listed within the same mapping file.
The catalog subelement is overridden by any catalog element explicitly specified in the Table
or SecondaryTable annotation on an entity listed within the mapping file, or any catalog
attribute on any table or secondary-table subelement defined within such an entity element.
10.1.2.4 access
The access subelement applies to the managed classes listed within the same mapping file.
The access subelement is overridden by the use of any annotations specifying mapping information
on the fields or properties of the entity class or by any access attribute defined within an entity,
mapped-superclass, or embeddable XML element.
10.1.2.5 sequence-generator
The generator defined by the sequence-generator subelement applies to the persistence unit. It is
undefined if multiple mapping files for the persistence unit contain generators of the same name.
The generator defined is added to any generators defined in annotations. If a generator of the same name
is defined in annotations, the generator defined by this subelement overrides that definition.
10.1.2.6 table-generator
The generator defined by the table-generator subelement applies to the persistence unit. It is
undefined if multiple mapping files for the persistence unit contain generators of the same name.
XML Descriptor Java Persistence 2.0, Early Draft XML Overriding Rules
The generator defined is added to any generators defined in annotations. If a generator of the same name
is defined in annotations, the generator defined by this subelement overrides that definition.
10.1.2.7 named-query
The named query defined by the named-query subelement applies to the persistence unit. It is unde-
fined if multiple mapping files for the persistence unit contain named queries of the same name.
The named query defined is added to the named queries defined in annotations. If a named query of the
same name is defined in annotations, the named query defined by this subelement overrides that defini-
tion.
10.1.2.8 named-native-query
The named native query defined by the named-native-query subelement applies to the persis-
tence unit. It is undefined if multiple mapping files for the persistence unit contain named queries of the
same name.
The named native query defined is added to the named native queries defined in annotations. If a
named query of the same name is defined in annotations, the named query defined by this subelement
overrides that definition.
10.1.2.9 sql-result-set-mapping
The SQL result set mapping defined by the sql-result-set-mapping subelement applies to the
persistence unit. It is undefined if multiple mapping files for the persistence unit contain SQL result set
mappings of the same name.
The SQL result set mapping defined is added to the SQL result set mappings defined in annotations. If
a SQL result set mapping of the same name is defined in annotations, the SQL result set mapping
defined by this subelement overrides that definition.
10.1.2.10 entity
The entity subelement defines an entity of the persistence unit. It is undefined if multiple mapping
files for the persistence unit contain entries for the same entity.
The entity class may or may not have been annotated as Entity. The subelements of the entity ele-
ment override as specified in section 10.1.3.
10.1.2.11 mapped-superclass
The mapped-superclass subelement defines a mapped superclass of the persistence unit. It is
undefined if multiple mapping files for the persistence unit contain entries for the same mapped super-
class.
The mapped superclass may or may not have been annotated as MappedSuperclass. The subele-
ments of the mapped-superclass element override as specified in section 10.1.4.
10.1.2.12 embeddable
The embeddable subelement defines an embeddable class of the persistence unit. It is undefined if
multiple mapping files for the persistence unit contain entries for the same embeddable class.
XML Overriding Rules Java Persistence 2.0, Early Draft XML Descriptor
The embeddable class may or may not have been annotated as Embeddable. The subelements of
the embeddable element override as specified in section 10.1.5.
10.1.3.1 metadata-complete
If the metadata-complete attribute is specified on the entity element itself, any annotations on
the entity class (and its fields and properties) are ignored. When metadata-complete is specified
on the entity element and XML elements are omitted, the default values apply to the given class.
10.1.3.2 access
The access attribute defines the access type for the entity. The access attribute overrides any access
type specified by the persistence-unit-defaults element or entity-mappings element
for the given entity.
Portable applications must not specify the access attribute if mapping annotations have been applied
to the fields or properties of the entity class and the value differs from the access type defined by means
of annotations.
Portable applications must not use more than one access type within an entity hierarchy.
10.1.3.3 name
The name attribute defines the entity name. The name attribute overrides the value of the entity name
defined by the name element of the Entity annotation (whether explicitly specified or defaulted).
Caution must be exercised in overriding the entity name,as doing so may cause applications to break.
10.1.3.4 table
The table subelement overrides any Table annotation (including defaulted Table values) on the
entity.
10.1.3.5 secondary-table
The secondary-table subelement overrides all SecondaryTable and SecondaryTables
annotations (including defaulted SecondaryTable values) on the entity.
10.1.3.6 primary-key-join-column
The primary-key-join-column subelement overrides all PrimaryKeyJoinColumn and
PrimaryKeyJoinColumns annotations (including defaulted PrimaryKeyJoinColumn values)
on the entity.
10.1.3.7 id-class
The id-class subelement overrides any IdClass annotation specified on the entity.
XML Descriptor Java Persistence 2.0, Early Draft XML Overriding Rules
10.1.3.8 inheritance
The inheritance subelement overrides any Inheritance annotation (including defaulted
Inheritance values) on the entity.
This element applies to the entity and its subclasses (unless otherwise overridden for a subclass by an
annotation or XML element).
10.1.3.9 discriminator-value
The discriminator-value subelement overrides any DiscriminatorValue annotations
(including defaulted DiscriminatorValue values) on the entity.
10.1.3.10 discriminator-column
The discriminator-column subelement overrides any DiscriminatorColumn annotation
(including defaulted DiscriminatorColumn values) on the entity.
This element applies to the entity and its subclasses (unless otherwise overridden for a subclass by an
annotation or XML element).
10.1.3.11 sequence-generator
The generator defined by the sequence-generator subelement is added to any generators defined
in annotations and any other generators defined in XML. If a generator of the same name is defined in
annotations, the generator defined by this subelement overrides that definition.
The generator defined by the sequence-generator subelement applies to the persistence unit. It is
undefined if multiple mapping files for the persistence unit contain generators of the same name.
10.1.3.12 table-generator
The generator defined by the table-generator subelement is added to any generators defined in
annotations and any other generators defined in XML. If a generator of the same name is defined in
annotations, the generator defined by this subelement overrides that definition.
The generator defined by the table-generator subelement applies to the persistence unit. It is
undefined if multiple mapping files for the persistence unit contain generators of the same name.
10.1.3.13 attribute-override
The attribute-override subelement is additive to any AttributeOverride or Attribu-
teOverrides annotations on the entity. It overrides any AttributeOverride elements for the
same attribute name.
10.1.3.14 association-override
The association-override subelement is additive to any AssociationOverride or
AssociationOverrides annotations on the entity. It overrides any AssociationOverride
elements for the same attribute name.
XML Overriding Rules Java Persistence 2.0, Early Draft XML Descriptor
10.1.3.15 named-query
The named query defined by the named-query subelement is added to any named queries defined in
annotations, and any other named queries defined in XML. If a named query of the same name is
defined in annotations, the named query defined by this subelement overrides that definition.
The named query defined by the named-query subelement applies to the persistence unit. It is unde-
fined if multiple mapping files for the persistence unit contain named queries of the same name.
10.1.3.16 named-native-query
The named query defined by the named-native-query subelement is added to any named queries
defined in annotations, and any other named queries defined in XML. If a named query of the same
name is defined in annotations, the named query defined by this subelement overrides that definition.
The named native query defined by the named-native-query subelement applies to the persis-
tence unit. It is undefined if multiple mapping files for the persistence unit contain named queries of the
same name.
10.1.3.17 sql-result-set-mapping
The SQL result set mapping defined by the sql-result-set-mapping is added to the SQL result
set mappings defined in annotations, and any other SQL result set mappings defined in XML. If a SQL
result set mapping of the same name is defined in annotations, the SQL result set mapping defined by
this subelement overrides that definition.
The SQL result set mapping defined by the sql-result-set-mapping subelement applies to the
persistence unit. It is undefined if multiple mapping files for the persistence unit contain SQL result set
mappings of the same name.
10.1.3.18 exclude-default-listeners
The exclude-default-listeners subelement applies whether or not the ExcludeDefault-
Listeners annotation was specified on the entity.
This element causes the default entity listeners to be excluded for the entity and its subclasses.
10.1.3.19 exclude-superclass-listeners
The exclude-superclass-listeners subelement applies whether or not the ExcludeSu-
perclassListeners annotation was specified on the entity.
This element causes any superclass listeners to be excluded for the entity and its subclasses.
10.1.3.20 entity-listeners
The entity-listeners subelement overrides any EntityListeners annotation on the entity.
These listeners apply to the entity and its subclasses unless otherwise excluded.
XML Descriptor Java Persistence 2.0, Early Draft XML Overriding Rules
post-load
These subelements override any lifecycle callback methods defined by the corresponding annotations
on the entity.
10.1.3.22 id
The id subelement overrides the mapping for the specified field or property.
10.1.3.23 embedded-id
The embedded-id subelement overrides the mapping for the specified field or property.
10.1.3.24 basic
The basic subelement overrides the mapping for the specified field or property.
10.1.3.25 version
The version subelement overrides the mapping for the specified field or property.
10.1.3.26 many-to-one
The many-to-one subelement overrides the mapping for the specified field or property.
10.1.3.27 one-to-many
The one-to-many subelement overrides the mapping for the specified field or property.
10.1.3.28 one-to-one
The one-to-one subelement overrides the mapping for the specified field or property.
10.1.3.29 many-to-many
The many-to-many subelement overrides the mapping for the specified field or property.
10.1.3.30 embedded
The embedded subelement overrides the mapping for the specified field or property.
10.1.3.31 transient
The transient subelement overrides the mapping for the specified field or property.
10.1.4.1 metadata-complete
XML Overriding Rules Java Persistence 2.0, Early Draft XML Descriptor
10.1.4.2 access
The access attribute defines the access type for the mapped superclass. The access attribute over-
rides any access type specified by the persistence-unit-defaults element or entity-map-
pings element for the given mapped superclass.
Portable applications must not specify the access attribute if mapping annotations have been applied
to the fields or properties of the mapped superclass and the value differs from the access type defined by
means of annotations.
Portable applications must not use more than one access type within an entity hierarchy.
10.1.4.3 id-class
The id-class subelement overrides any IdClass annotation specified on the mapped superclass.
10.1.4.4 exclude-default-listeners
The exclude-default-listeners subelement applies whether or not the ExcludeDefault-
Listeners annotation was specified on the mapped superclass.
This element causes the default entity listeners to be excluded for the mapped superclass and its sub-
classes.
10.1.4.5 exclude-superclass-listeners
The exclude-superclass-listeners subelement applies whether or not the ExcludeSu-
perclassListeners annotation was specified on the mapped superclass.
This element causes any superclass listeners to be excluded for the mapped superclass and its sub-
classes.
10.1.4.6 entity-listeners
The entity-listeners subelement overrides any EntityListeners annotation on the
mapped superclass.
These listeners apply to the mapped superclass and its subclasses unless otherwise excluded.
10.1.4.8 id
The id subelement overrides the mapping for the specified field or property.
10.1.4.9 embedded-id
The embedded-id subelement overrides the mapping for the specified field or property.
10.1.4.10 basic
The basic subelement overrides the mapping for the specified field or property.
XML Descriptor Java Persistence 2.0, Early Draft XML Overriding Rules
10.1.4.11 version
The version subelement overrides the mapping for the specified field or property.
10.1.4.12 many-to-one
The many-to-one subelement overrides the mapping for the specified field or property.
10.1.4.13 one-to-many
The one-to-many subelement overrides the mapping for the specified field or property.
10.1.4.14 one-to-one
The one-to-one subelement overrides the mapping for the specified field or property.
10.1.4.15 many-to-many
The many-to-many subelement overrides the mapping for the specified field or property.
10.1.4.16 embedded
The embedded subelement overrides the mapping for the specified field or property.
10.1.4.17 transient
The transient subelement overrides the mapping for the specified field or property.
10.1.5.1 metadata-complete
If the metadata-complete attribute is specified on the embeddable element itself, any annota-
tions on the embeddable class (and its fields and properties) are ignored. When metadata-com-
plete is specified on the embeddable element and XML elements are omitted, the default values
apply to the given class.
10.1.5.2 access
The access attribute defines the access type for the embeddable class. The access attribute over-
rides any access type specified by the persistence-unit-defaults element or entity-map-
pings element for the given embeddable class.
Portable applications must not specify the access attribute if mapping annotations have been applied
to the fields or properties of the embeddable class or the entity with which it is associated and the value
differs from the access type defined by means of annotations.
Portable applications must not use more than one access type within an entity hierarchy.
10.1.5.3 basic
The basic subelement overrides the mapping for the specified field or property.
XML Overriding Rules Java Persistence 2.0, Early Draft XML Descriptor
10.1.5.4 transient
The transient subelement overrides the mapping for the specified field or property.
This section provides the XML schema for use with the persistence API.
<xsd:annotation>
<xsd:documentation>
@(#)orm_1_0.xsd 1.0 Feb 14 2006
</xsd:documentation>
</xsd:annotation>
<xsd:annotation>
<xsd:documentation><![CDATA[
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType name="emptyType"/>
<xsd:simpleType name="versionType">
<xsd:restriction base="xsd:token">
<xsd:pattern value="[0-9]+(\.[0-9]+)*"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:element name="entity-mappings">
<xsd:complexType>
<xsd:annotation>
<xsd:documentation>
persistence unit.
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="description" type="xsd:string"
minOccurs="0"/>
<xsd:element name="persistence-unit-metadata"
type="orm:persistence-unit-metadata"
minOccurs="0"/>
<xsd:element name="package" type="xsd:string"
minOccurs="0"/>
<xsd:element name="schema" type="xsd:string"
minOccurs="0"/>
<xsd:element name="catalog" type="xsd:string"
minOccurs="0"/>
<xsd:element name="access" type="orm:access-type"
minOccurs="0"/>
<xsd:element name="sequence-generator" type="orm:sequence-generator"
minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="table-generator" type="orm:table-generator"
minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="named-query" type="orm:named-query"
minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="named-native-query" type="orm:named-native-query"
minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="sql-result-set-mapping"
type="orm:sql-result-set-mapping"
minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="mapped-superclass" type="orm:mapped-superclass"
minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="entity" type="orm:entity"
minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="embeddable" type="orm:embeddable"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="version" type="orm:versionType"
fixed="1.0" use="required"/>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="persistence-unit-metadata">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="xml-mapping-metadata-complete" type="orm:emptyType"
minOccurs="0"/>
<xsd:element name="persistence-unit-defaults"
type="orm:persistence-unit-defaults"
minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="persistence-unit-defaults">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="schema" type="xsd:string"
minOccurs="0"/>
<xsd:element name="catalog" type="xsd:string"
minOccurs="0"/>
<xsd:element name="access" type="orm:access-type"
minOccurs="0"/>
<xsd:element name="cascade-persist" type="orm:emptyType"
minOccurs="0"/>
<xsd:element name="entity-listeners" type="orm:entity-listeners"
minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="entity">
<xsd:annotation>
<xsd:documentation>
@Target(TYPE) @Retention(RUNTIME)
public @interface Entity {
String name() default "";
}
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="description" type="xsd:string" minOccurs="0"/>
<xsd:element name="table" type="orm:table"
minOccurs="0"/>
<xsd:complexType name="attributes">
<xsd:annotation>
<xsd:documentation>
<xsd:simpleType name="access-type">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="PROPERTY"/>
<xsd:enumeration value="FIELD"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="entity-listeners">
<xsd:annotation>
<xsd:documentation>
@Target({TYPE}) @Retention(RUNTIME)
public @interface EntityListeners {
Class[] value();
}
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="entity-listener" type="orm:entity-listener"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="pre-persist" type="orm:pre-persist" minOccurs="0"/>
<xsd:element name="post-persist" type="orm:post-persist"
minOccurs="0"/>
<xsd:element name="pre-remove" type="orm:pre-remove" minOccurs="0"/>
<xsd:element name="post-remove" type="orm:post-remove" minOccurs="0"/>
<xsd:element name="pre-update" type="orm:pre-update" minOccurs="0"/>
<xsd:element name="post-update" type="orm:post-update" minOccurs="0"/>
<xsd:element name="post-load" type="orm:post-load" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="class" type="xsd:string" use="required"/>
</xsd:complexType>
@Target({METHOD}) @Retention(RUNTIME)
public @interface PrePersist {}
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="method-name" type="xsd:string" use="required"/>
</xsd:complexType>
<xsd:complexType name="post-persist">
<xsd:annotation>
<xsd:documentation>
@Target({METHOD}) @Retention(RUNTIME)
public @interface PostPersist {}
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="method-name" type="xsd:string" use="required"/>
</xsd:complexType>
<xsd:complexType name="pre-remove">
<xsd:annotation>
<xsd:documentation>
@Target({METHOD}) @Retention(RUNTIME)
public @interface PreRemove {}
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="method-name" type="xsd:string" use="required"/>
</xsd:complexType>
@Target({METHOD}) @Retention(RUNTIME)
public @interface PostRemove {}
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="method-name" type="xsd:string" use="required"/>
</xsd:complexType>
<xsd:complexType name="pre-update">
<xsd:annotation>
<xsd:documentation>
@Target({METHOD}) @Retention(RUNTIME)
public @interface PreUpdate {}
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="method-name" type="xsd:string" use="required"/>
</xsd:complexType>
<xsd:complexType name="post-update">
<xsd:annotation>
<xsd:documentation>
@Target({METHOD}) @Retention(RUNTIME)
public @interface PostUpdate {}
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="method-name" type="xsd:string" use="required"/>
</xsd:complexType>
<xsd:complexType name="post-load">
<xsd:annotation>
<xsd:documentation>
@Target({METHOD}) @Retention(RUNTIME)
public @interface PostLoad {}
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="method-name" type="xsd:string" use="required"/>
</xsd:complexType>
<xsd:complexType name="query-hint">
<xsd:annotation>
<xsd:documentation>
@Target({}) @Retention(RUNTIME)
public @interface QueryHint {
String name();
String value();
}
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="value" type="xsd:string" use="required"/>
</xsd:complexType>
<xsd:complexType name="named-query">
<xsd:annotation>
<xsd:documentation>
@Target({TYPE}) @Retention(RUNTIME)
public @interface NamedQuery {
String name();
String query();
QueryHint[] hints() default {};
}
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="query" type="xsd:string"/>
<xsd:element name="hint" type="orm:query-hint"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:complexType>
<xsd:complexType name="named-native-query">
<xsd:annotation>
<xsd:documentation>
@Target({TYPE}) @Retention(RUNTIME)
public @interface NamedNativeQuery {
String name();
String query();
QueryHint[] hints() default {};
Class resultClass() default void.class;
String resultSetMapping() default ""; //named SqlResultSetMapping
}
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="query" type="xsd:string"/>
<xsd:element name="hint" type="orm:query-hint"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="result-class" type="xsd:string"/>
<xsd:attribute name="result-set-mapping" type="xsd:string"/>
</xsd:complexType>
<xsd:complexType name="sql-result-set-mapping">
<xsd:annotation>
<xsd:documentation>
@Target({TYPE}) @Retention(RUNTIME)
public @interface SqlResultSetMapping {
String name();
EntityResult[] entities() default {};
ColumnResult[] columns() default {};
}
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="entity-result" type="orm:entity-result"
minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="column-result" type="orm:column-result"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:complexType>
<xsd:complexType name="entity-result">
<xsd:annotation>
<xsd:documentation>
@Target({}) @Retention(RUNTIME)
public @interface EntityResult {
Class entityClass();
FieldResult[] fields() default {};
String discriminatorColumn() default "";
}
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="field-result" type="orm:field-result"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="entity-class" type="xsd:string" use="required"/>
<xsd:attribute name="discriminator-column" type="xsd:string"/>
</xsd:complexType>
<xsd:complexType name="field-result">
<xsd:annotation>
<xsd:documentation>
@Target({}) @Retention(RUNTIME)
public @interface FieldResult {
String name();
String column();
}
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="column" type="xsd:string" use="required"/>
</xsd:complexType>
<xsd:complexType name="column-result">
<xsd:annotation>
<xsd:documentation>
@Target({}) @Retention(RUNTIME)
public @interface ColumnResult {
String name();
}
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:complexType>
<xsd:complexType name="table">
<xsd:annotation>
<xsd:documentation>
@Target({TYPE}) @Retention(RUNTIME)
public @interface Table {
String name() default "";
String catalog() default "";
String schema() default "";
UniqueConstraint[] uniqueConstraints() default {};
}
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="unique-constraint" type="orm:unique-constraint"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string"/>
<xsd:attribute name="catalog" type="xsd:string"/>
<xsd:attribute name="schema" type="xsd:string"/>
</xsd:complexType>
<xsd:complexType name="secondary-table">
<xsd:annotation>
<xsd:documentation>
@Target({TYPE}) @Retention(RUNTIME)
public @interface SecondaryTable {
String name();
String catalog() default "";
String schema() default "";
PrimaryKeyJoinColumn[] pkJoinColumns() default {};
UniqueConstraint[] uniqueConstraints() default {};
}
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="primary-key-join-column"
type="orm:primary-key-join-column"
minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="unique-constraint" type="orm:unique-constraint"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="catalog" type="xsd:string"/>
<xsd:attribute name="schema" type="xsd:string"/>
</xsd:complexType>
<xsd:complexType name="unique-constraint">
<xsd:annotation>
<xsd:documentation>
@Target({}) @Retention(RUNTIME)
public @interface UniqueConstraint {
String[] columnNames();
}
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="column-name" type="xsd:string"
maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="column">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="name" type="xsd:string"/>
<xsd:attribute name="unique" type="xsd:boolean"/>
<xsd:attribute name="nullable" type="xsd:boolean"/>
<xsd:attribute name="insertable" type="xsd:boolean"/>
<xsd:attribute name="updatable" type="xsd:boolean"/>
<xsd:attribute name="column-definition" type="xsd:string"/>
<xsd:attribute name="table" type="xsd:string"/>
<xsd:attribute name="length" type="xsd:int"/>
<xsd:attribute name="precision" type="xsd:int"/>
<xsd:attribute name="scale" type="xsd:int"/>
</xsd:complexType>
<xsd:complexType name="join-column">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="name" type="xsd:string"/>
<xsd:attribute name="referenced-column-name" type="xsd:string"/>
<xsd:attribute name="unique" type="xsd:boolean"/>
<xsd:attribute name="nullable" type="xsd:boolean"/>
<xsd:simpleType name="generation-type">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="TABLE"/>
<xsd:enumeration value="SEQUENCE"/>
<xsd:enumeration value="IDENTITY"/>
<xsd:enumeration value="AUTO"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="attribute-override">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="column" type="orm:column"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:complexType>
<xsd:complexType name="association-override">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="join-column" type="orm:join-column"
maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:complexType>
<xsd:complexType name="id-class">
<xsd:annotation>
<xsd:documentation>
@Target({TYPE}) @Retention(RUNTIME)
public @interface IdClass {
Class value();
}
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="class" type="xsd:string" use="required"/>
</xsd:complexType>
<xsd:complexType name="id">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="column" type="orm:column"
minOccurs="0"/>
<xsd:element name="generated-value" type="orm:generated-value"
minOccurs="0"/>
<xsd:element name="temporal" type="orm:temporal"
minOccurs="0"/>
<xsd:element name="table-generator" type="orm:table-generator"
minOccurs="0"/>
<xsd:element name="sequence-generator" type="orm:sequence-generator"
minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:complexType>
<xsd:complexType name="embedded-id">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="attribute-override" type="orm:attribute-override"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:complexType>
<xsd:complexType name="transient">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:complexType>
<xsd:complexType name="version">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="column" type="orm:column" minOccurs="0"/>
<xsd:element name="temporal" type="orm:temporal" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:complexType>
<xsd:complexType name="basic">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="column" type="orm:column" minOccurs="0"/>
<xsd:choice>
<xsd:element name="lob" type="orm:lob" minOccurs="0"/>
<xsd:element name="temporal" type="orm:temporal" minOccurs="0"/>
<xsd:element name="enumerated" type="orm:enumerated" minOccurs="0"/>
</xsd:choice>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="fetch" type="orm:fetch-type"/>
<xsd:attribute name="optional" type="xsd:boolean"/>
</xsd:complexType>
<xsd:simpleType name="fetch-type">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="LAZY"/>
<xsd:enumeration value="EAGER"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="lob">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
</xsd:complexType>
<xsd:simpleType name="temporal">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="orm:temporal-type"/>
</xsd:simpleType>
<xsd:simpleType name="temporal-type">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="DATE"/>
<xsd:enumeration value="TIME"/>
<xsd:enumeration value="TIMESTAMP"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="enumerated">
<xsd:annotation>
<xsd:documentation>
</xsd:simpleType>
<xsd:simpleType name="enum-type">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="ORDINAL"/>
<xsd:enumeration value="STRING"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="many-to-one">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:choice>
<xsd:element name="join-column" type="orm:join-column"
minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="join-table" type="orm:join-table"
minOccurs="0"/>
</xsd:choice>
<xsd:element name="cascade" type="orm:cascade-type"
minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="target-entity" type="xsd:string"/>
<xsd:attribute name="fetch" type="orm:fetch-type"/>
<xsd:attribute name="optional" type="xsd:boolean"/>
</xsd:complexType>
<xsd:complexType name="cascade-type">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="cascade-all" type="orm:emptyType"
minOccurs="0"/>
<xsd:complexType name="one-to-one">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:choice>
<xsd:element name="primary-key-join-column"
type="orm:primary-key-join-column"
minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="join-column" type="orm:join-column"
minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="join-table" type="orm:join-table"
minOccurs="0"/>
</xsd:choice>
<xsd:element name="cascade" type="orm:cascade-type"
minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="target-entity" type="xsd:string"/>
<xsd:attribute name="fetch" type="orm:fetch-type"/>
<xsd:attribute name="optional" type="xsd:boolean"/>
<xsd:attribute name="mapped-by" type="xsd:string"/>
</xsd:complexType>
<xsd:complexType name="one-to-many">
<xsd:annotation>
<xsd:documentation>
minOccurs="0"/>
<xsd:element name="map-key" type="orm:map-key"
minOccurs="0"/>
<xsd:choice>
<xsd:element name="join-table" type="orm:join-table"
minOccurs="0"/>
<xsd:element name="join-column" type="orm:join-column"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:choice>
<xsd:element name="cascade" type="orm:cascade-type"
minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="target-entity" type="xsd:string"/>
<xsd:attribute name="fetch" type="orm:fetch-type"/>
<xsd:attribute name="mapped-by" type="xsd:string"/>
</xsd:complexType>
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="join-column" type="orm:join-column"
minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="inverse-join-column" type="orm:join-column"
minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="unique-constraint" type="orm:unique-constraint"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string"/>
<xsd:attribute name="catalog" type="xsd:string"/>
<xsd:attribute name="schema" type="xsd:string"/>
</xsd:complexType>
<xsd:complexType name="many-to-many">
<xsd:annotation>
<xsd:documentation>
<xsd:complexType name="generated-value">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="strategy" type="orm:generation-type"/>
<xsd:attribute name="generator" type="xsd:string"/>
</xsd:complexType>
<xsd:complexType name="map-key">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="name" type="xsd:string"/>
</xsd:complexType>
<xsd:simpleType name="order-by">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<xsd:complexType name="inheritance">
<xsd:annotation>
<xsd:documentation>
@Target({TYPE}) @Retention(RUNTIME)
public @interface Inheritance {
InheritanceType strategy() default SINGLE_TABLE;
}
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="strategy" type="orm:inheritance-type"/>
</xsd:complexType>
<xsd:simpleType name="inheritance-type">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="SINGLE_TABLE"/>
<xsd:enumeration value="JOINED"/>
<xsd:enumeration value="TABLE_PER_CLASS"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="discriminator-value">
<xsd:annotation>
<xsd:documentation>
@Target({TYPE}) @Retention(RUNTIME)
public @interface DiscriminatorValue {
String value();
}
</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="discriminator-type">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="STRING"/>
<xsd:enumeration value="CHAR"/>
<xsd:enumeration value="INTEGER"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="primary-key-join-column">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="name" type="xsd:string"/>
<xsd:attribute name="referenced-column-name" type="xsd:string"/>
<xsd:attribute name="column-definition" type="xsd:string"/>
</xsd:complexType>
<!-- **************************************************** -->
<xsd:complexType name="discriminator-column">
<xsd:annotation>
<xsd:documentation>
@Target({TYPE}) @Retention(RUNTIME)
public @interface DiscriminatorColumn {
String name() default "DTYPE";
DiscriminatorType discriminatorType() default STRING;
String columnDefinition() default "";
int length() default 31;
}
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="name" type="xsd:string"/>
<xsd:attribute name="discriminator-type" type="orm:discriminator-type"/>
<xsd:attribute name="column-definition" type="xsd:string"/>
<xsd:attribute name="length" type="xsd:int"/>
</xsd:complexType>
<xsd:complexType name="embeddable">
<xsd:annotation>
<xsd:documentation>
@Target({TYPE}) @Retention(RUNTIME)
public @interface Embeddable {}
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="description" type="xsd:string" minOccurs="0"/>
<xsd:element name="attributes" type="orm:embeddable-attributes"
minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="class" type="xsd:string" use="required"/>
<xsd:complexType name="embeddable-attributes">
<xsd:sequence>
<xsd:element name="basic" type="orm:basic"
minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="transient" type="orm:transient"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="embedded">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="attribute-override" type="orm:attribute-override"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:complexType>
<xsd:complexType name="mapped-superclass">
<xsd:annotation>
<xsd:documentation>
@Target(TYPE) @Retention(RUNTIME)
public @interface MappedSuperclass{}
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="description" type="xsd:string" minOccurs="0"/>
<xsd:element name="id-class" type="orm:id-class" minOccurs="0"/>
<xsd:element name="exclude-default-listeners" type="orm:emptyType"
minOccurs="0"/>
<xsd:element name="exclude-superclass-listeners" type="orm:emptyType"
minOccurs="0"/>
<xsd:element name="entity-listeners" type="orm:entity-listeners"
minOccurs="0"/>
<xsd:element name="pre-persist" type="orm:pre-persist" minOccurs="0"/>
<xsd:element name="post-persist" type="orm:post-persist"
minOccurs="0"/>
<xsd:element name="pre-remove" type="orm:pre-remove" minOccurs="0"/>
<xsd:element name="post-remove" type="orm:post-remove" minOccurs="0"/>
<xsd:element name="pre-update" type="orm:pre-update" minOccurs="0"/>
<xsd:complexType name="sequence-generator">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="sequence-name" type="xsd:string"/>
<xsd:attribute name="initial-value" type="xsd:int"/>
<xsd:attribute name="allocation-size" type="xsd:int"/>
</xsd:complexType>
<xsd:complexType name="table-generator">
<xsd:annotation>
<xsd:documentation>
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="unique-constraint" type="orm:unique-constraint"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="table" type="xsd:string"/>
<xsd:attribute name="catalog" type="xsd:string"/>
<xsd:attribute name="schema" type="xsd:string"/>
<xsd:attribute name="pk-column-name" type="xsd:string"/>
<xsd:attribute name="value-column-name" type="xsd:string"/>
<xsd:attribute name="pk-column-value" type="xsd:string"/>
<xsd:attribute name="initial-value" type="xsd:int"/>
<xsd:attribute name="allocation-size" type="xsd:int"/>
</xsd:complexType>
</xsd:schema>
C ha p t e r 11 Related Documents
A pp e n d i x A Revision History
This appendix lists the significant changes that have been made during the development of the Java Per-
sistence 2.0 specification.
Created document from EJB 3.0 Java Persistence API Final Release draft.
Added support for multiple levels of embeddable classes and embeddable classes.
Added support for embeddable classes containing collections of embeddables and basic types.
Added more generalized support for Map collections. Basic, embeddable, and entity types can be map
keys and map values.
Added support for persistently ordered lists using OrderColumn and provider-managed ordering col-
umn.
Extended OrderBy annotation to handle element collections and ordering by embeddable classes.
Defined support for combinations of access types within an entity hierarchy and within a managed
class.
Defined support for foreign key mapping strategy for unidirectional one-to-many relationships.
Added support for join table mappings for many-to-one and one-to-one relationships.
Added clear method to EntityManager interface to allow entities to be evicted from the persistence con-
text; added CLEAR cascade option.
Added support for pessimistic locking and new lock mode types.
Added overloaded find and refresh methods added to support locking with standardized and ven-
dor-specific properties and hints.
Added QueryTimeoutException.