Вы находитесь на странице: 1из 380

Sun Microsystems JSR 317: JavaTM Persistence API, Version 2.

Java Persistence 2.0 Expert Group


Specification Lead: Linda DeMichiel, Sun Microsystems Please send comments to: jsr-317-pdr-feedback@sun.com

lic ub P
Version 2.0, Public Review Draft

e R

ew vi

ft ra D

October 31, 2008

Java Persistence 2.0, Public Review Draft

Sun Microsystems, Inc.

Specification: JSR-000317 Java(tm) Persistence API Specification ("Specification") Version: 2.0 Status: Public Review Release: 30 October 2008 Copyright 2008 Sun Microsystems, Inc. 4150 Network Circle, Santa Clara, California 95054, U.S.A All rights reserved.
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 following 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 Specification and the information described therein will be governed by the terms and conditions of this Agreement. 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 implementations 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 significant portion of the Technology. 2.Distribute implementations of the Specification to third parties for their testing and evaluation use, provided 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 "INCOMPATIBLE" 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 contingent upon your agreement to terminate development and distribution of your "early draft" implementation 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

10/31/08

Java Persistence 2.0, Public Review 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 addition, 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, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT THAT THE CONTENTS OF THE SPECIFICATION ARE SUITABLE FOR ANY PURPOSE OR THAT ANY PRACTICE OR IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADE SECRETS OR OTHER RIGHTS. This document does not represent any commitment to release or implement any portion of the Specification in any product. THE SPECIFICATION COULD INCLUDE TECHNICAL INACCURACIES OR TYPOGRAPHICAL ERRORS. CHANGES ARE PERIODICALLY ADDED TO THE INFORMATION THEREIN; THESE CHANGES WILL BE INCORPORATED INTO NEW VERSIONS OF THE SPECIFICATION, IF ANY. SUN MAY MAKE IMPROVEMENTS AND/OR CHANGES TO THE PRODUCT(S) AND/OR THE PROGRAM(S) DESCRIBED IN THE SPECIFICATION AT ANY TIME. Any use of such changes in the Specification will be governed by the then-current license for the applicable version of the Specification. 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 PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, 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 ADVISED 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. RESTRICTED RIGHTS LEGEND If this Software is being acquired by or on behalf of the U.S. Government or by a U.S. Government prime contractor or subcontractor (at any tier), then the Government's rights in the Software and accompanying documentation shall be only as set forth in this license; this is in accordance with 48 C.F.R. 227.7201

10/31/08

Java Persistence 2.0, Public Review 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 Feedback, you hereby: (i) agree that such Feedback is provided on a non-proprietary and non-confidential basis, 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 limitation 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 regulations in other countries. Licensee agrees to comply strictly with all such laws and regulations and acknowledges 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 communication between the parties relating to its subject matter during the term of this Agreement. No modification to this Agreement will be binding, unless in writing and signed by an authorized representative of each party.

10/31/08

Sun Microsystems, Inc.


Java Persistence 2.0, Public Review Draft

Table of Contents
Chapter 1 Introduction.................................................................................................................... 17 1.1 Expert Group ................................................................................................... 17 1.2 Document Conventions ................................................................................... 17 Entities ........................................................................................................................... 19 2.1 The Entity Class .............................................................................................. 19 2.2 Persistent Fields and Properties....................................................................... 20 2.2.1 Example ............................................................................................ 22 2.3 Access Type..................................................................................................... 23 2.3.1 Default Access Type ......................................................................... 23 2.3.2 Explicit Access Type......................................................................... 24 2.3.3 Access Type of an Embeddable Class............................................... 25 2.4 Primary Keys and Entity Identity .................................................................... 25 2.4.1 Primary Keys Corresponding to Derived Identities .......................... 26 2.4.1.1 Specification of Derived Identities ..................................... 27 2.4.1.2 Examples of Derived Identities .......................................... 28 2.5 Embeddable Classes ........................................................................................ 34 2.6 Collections of Embeddable Classes and Basic Types ..................................... 35 2.7 Map Collections .............................................................................................. 35 2.7.1 Map Keys .......................................................................................... 35 2.7.2 Map Values........................................................................................ 36 2.8 Mapping Defaults for Non-Relationship Fields or Properties......................... 36 2.9 Entity Relationships ........................................................................................ 37 2.10 Relationship Mapping Defaults....................................................................... 39 2.10.1 Bidirectional OneToOne Relationships ............................................ 39 2.10.2 Bidirectional ManyToOne / OneToMany Relationships................... 40 2.10.3 Unidirectional Single-Valued Relationships ..................................... 42 2.10.3.1 Unidirectional OneToOne Relationships............................ 42 2.10.3.2 Unidirectional ManyToOne Relationships ......................... 43 2.10.4 Bidirectional ManyToMany Relationships ....................................... 44 2.10.5 Unidirectional Multi-Valued Relationships ...................................... 45 2.10.5.1 Unidirectional OneToMany Relationships ......................... 46 2.10.5.2 Unidirectional ManyToMany Relationships....................... 47 2.11 Inheritance ....................................................................................................... 48 2.11.1 Abstract Entity Classes ..................................................................... 48 2.11.2 Mapped Superclasses ........................................................................ 49 2.11.3 Non-Entity Classes in the Entity Inheritance Hierarchy................... 51 2.12 Inheritance Mapping Strategies ....................................................................... 52 2.12.1 Single Table per Class Hierarchy Strategy........................................ 52 2.12.2 Table per Concrete Class Strategy .................................................... 52 2.12.3 Joined Subclass Strategy ................................................................... 53 2.13 Naming of Database Objects ........................................................................... 53

Chapter 2

10/31/08

Sun Microsystems, Inc.


Java Persistence 2.0, Public Review Draft

Chapter 3

Entity Operations ........................................................................................................... 55 3.1 EntityManager ................................................................................................. 55 3.1.1 EntityManager Interface.................................................................... 57 3.1.2 Example of Use of EntityManager API ............................................ 67 3.2 Entity Instances Life Cycle ............................................................................ 68 3.2.1 Entity Instance Creation .................................................................... 68 3.2.2 Persisting an Entity Instance ............................................................. 68 3.2.3 Removal ............................................................................................ 69 3.2.4 Synchronization to the Database ....................................................... 69 3.2.5 Refreshing an Entity Instance ........................................................... 70 3.2.6 Evicting an Entity Instance from the Persistence Context ................ 71 3.2.7 Detached Entities............................................................................... 71 3.2.7.1 Merging Detached Entity State ........................................... 72 3.2.7.2 Detached Entities and Lazy Loading .................................. 73 3.2.8 Managed Instances ............................................................................ 73 3.3 Persistence Context Lifetime........................................................................... 74 3.3.1 Transaction Commit .......................................................................... 74 3.3.2 Transaction Rollback......................................................................... 75 3.4 Locking and Concurrency ............................................................................... 75 3.4.1 Optimistic Locking............................................................................ 75 3.4.2 Version Attributes.............................................................................. 76 3.4.3 Pessimistic Locking........................................................................... 76 3.4.4 Lock Modes....................................................................................... 77 3.4.4.1 OPTIMISTIC, OPTIMISTIC_FORCE_INCREMENT...... 78 3.4.4.2 PESSIMISTIC, PESSIMISTIC_FORCE_INCREMENT .. 79 3.4.4.3 Lock Mode Hints ................................................................ 80 3.4.5 OptimisticLockException.................................................................. 81 3.5 Entity Listeners and Callback Methods........................................................... 81 3.5.1 Lifecycle Callback Methods.............................................................. 82 3.5.2 Semantics of the Life Cycle Callback Methods for Entities ............. 83 3.5.3 Example............................................................................................. 84 3.5.4 Multiple Lifecycle Callback Methods for an Entity Lifecycle Event85 3.5.5 Example............................................................................................. 86 3.5.6 Exceptions ......................................................................................... 88 3.5.7 Specification of Callback Listener Classes and Lifecycle Methods in the XML Descriptor88 3.5.7.1 Specification of Callback Listeners .................................... 88 3.5.7.2 Specification of the Binding of Entity Listener Classes to Entities 88 3.6 Query API........................................................................................................ 89 3.6.1 Query Interface.................................................................................. 89 3.6.1.1 Example .............................................................................. 94 3.6.2 Queries and Flush Mode ................................................................... 94 3.6.3 Queries and Lock Mode .................................................................... 95 3.6.4 Query Hints ....................................................................................... 95 3.6.5 Named Parameters............................................................................. 96 3.6.6 Named Queries.................................................................................. 96 3.6.7 Polymorphic Queries......................................................................... 96 3.6.8 SQL Queries...................................................................................... 97

10/31/08

Sun Microsystems, Inc.


Java Persistence 2.0, Public Review Draft

3.7 Summary of Exceptions .................................................................................. 100 Chapter 4 Query Language............................................................................................................. 103 4.1 Overview ......................................................................................................... 103 4.2 Statement Types............................................................................................... 104 4.2.1 Select Statements .............................................................................. 104 4.2.2 Update and Delete Statements .......................................................... 105 4.3 Abstract Schema Types and Query Domains .................................................. 105 4.3.1 Naming.............................................................................................. 106 4.3.2 Example ............................................................................................ 106 4.4 The FROM Clause and Navigational Declarations ......................................... 108 4.4.1 Identifiers .......................................................................................... 108 4.4.2 Identification Variables ..................................................................... 109 4.4.3 Range Variable Declarations............................................................. 110 4.4.4 Path Expressions ............................................................................... 110 4.4.5 Joins .................................................................................................. 112 4.4.5.1 Inner Joins (Relationship Joins) ......................................... 113 4.4.5.2 Left Outer Joins .................................................................. 113 4.4.5.3 Fetch Joins .......................................................................... 114 4.4.6 Collection Member Declarations ...................................................... 114 4.4.7 FROM Clause and SQL .................................................................... 115 4.4.8 Polymorphism ................................................................................... 115 4.4.9 Entity Type Expressions.................................................................... 116 4.5 WHERE Clause ............................................................................................... 116 4.6 Conditional Expressions.................................................................................. 117 4.6.1 Literals .............................................................................................. 117 4.6.2 Identification Variables ..................................................................... 118 4.6.3 Path Expressions ............................................................................... 118 4.6.4 Input Parameters ............................................................................... 118 4.6.4.1 Positional Parameters ......................................................... 118 4.6.4.2 Named Parameters .............................................................. 119 4.6.5 Conditional Expression Composition ............................................... 119 4.6.6 Operators and Operator Precedence.................................................. 119 4.6.7 Comparison Expressions................................................................... 120 4.6.8 Between Expressions ........................................................................ 120 4.6.9 In Expressions ................................................................................... 121 4.6.10 Like Expressions ............................................................................... 122 4.6.11 Null Comparison Expressions........................................................... 123 4.6.12 Empty Collection Comparison Expressions ..................................... 123 4.6.13 Collection Member Expressions ....................................................... 123 4.6.14 Exists Expressions............................................................................. 124 4.6.15 All or Any Expressions ..................................................................... 124 4.6.16 Subqueries......................................................................................... 125 4.6.17 Scalar Expressions ............................................................................ 126 4.6.17.1 Arithmetic Expressions....................................................... 126 4.6.17.2 String, Arithmetic, and Datetime Functional Expressions . 127 4.6.17.2.1 String Functions ................................................... 127 4.6.17.2.2 Arithmetic Functions............................................ 128

10/31/08

Sun Microsystems, Inc.


Java Persistence 2.0, Public Review Draft

4.7 4.8

4.9 4.10 4.11 4.12 4.13

4.14 Chapter 5

4.6.17.2.3 Datetime Functions............................................... 128 4.6.17.3 Case Expressions ................................................................ 129 GROUP BY, HAVING .................................................................................... 130 SELECT Clause............................................................................................... 131 4.8.1 Result Type of the SELECT Clause.................................................. 132 4.8.2 Constructor Expressions in the SELECT Clause .............................. 133 4.8.3 Null Values in the Query Result........................................................ 134 4.8.4 Aggregate Functions in the SELECT Clause.................................... 134 4.8.4.1 Examples............................................................................. 135 ORDER BY Clause ......................................................................................... 136 Bulk Update and Delete Operations ................................................................ 137 Null Values ...................................................................................................... 138 Equality and Comparison Semantics ............................................................... 139 Examples ......................................................................................................... 140 4.13.1 Simple Queries .................................................................................. 140 4.13.2 Queries with Relationships................................................................ 140 4.13.3 Queries Using Input Parameters........................................................ 141 BNF ................................................................................................................. 142

Criteria API .................................................................................................................... 149 5.1 Overview ......................................................................................................... 149 5.2 Criteria API Interfaces..................................................................................... 150 5.2.1 QueryBuilder Interface...................................................................... 150 5.2.2 QueryDefinition Interface ................................................................. 151 5.2.3 Subquery Interface ............................................................................ 160 5.2.4 DomainObject Interface .................................................................... 161 5.2.5 FetchJoinObject Interface ................................................................. 163 5.2.6 PathExpression Interface................................................................... 163 5.2.7 PredicateOperand Interface ............................................................... 165 5.2.8 Predicate Interface............................................................................. 174 5.2.9 Expression Interface.......................................................................... 175 5.2.10 TrimSpec Enum................................................................................. 183 5.2.11 CaseExpression Interface .................................................................. 184 5.2.12 Aggregate Interface ........................................................................... 189 5.2.13 SelectItem Interface........................................................................... 189 5.2.14 OrderByItem Interface ...................................................................... 190 5.3 Query Construction.......................................................................................... 190 5.4 Query Roots ..................................................................................................... 190 5.5 Domain Objects ............................................................................................... 190 5.6 Joins ................................................................................................................. 192 5.6.1 Fetch Joins......................................................................................... 192 5.7 Path Expressions.............................................................................................. 193 5.8 Expressions ...................................................................................................... 194 5.8.1 Literals............................................................................................... 196 5.8.2 Parameters ......................................................................................... 197 5.9 Restricting the Query Result............................................................................ 197

10/31/08

Sun Microsystems, Inc.


Java Persistence 2.0, Public Review Draft

5.10 5.11 5.12 5.13 5.14 5.15 Chapter 6

Subqueries ....................................................................................................... 198 Specifying the Select List................................................................................ 202 GroupBy and Having....................................................................................... 203 Ordering the Query Results ............................................................................. 204 Query Definition Modification........................................................................ 206 Query Execution.............................................................................................. 206

Entity Managers and Persistence Contexts .................................................................... 207 6.1 Persistence Contexts........................................................................................ 207 6.2 Obtaining an EntityManager ........................................................................... 208 6.2.1 Obtaining an Entity Manager in the Java EE Environment .............. 208 6.2.2 Obtaining an Application-managed Entity Manager ........................ 209 6.3 Obtaining an Entity Manager Factory ............................................................. 209 6.3.1 Obtaining an Entity Manager Factory in a Java EE Container ......... 210 6.3.2 Obtaining an Entity Manager Factory in a Java SE Environment .... 210 6.4 EntityManagerFactory Interface...................................................................... 210 6.5 Controlling Transactions ................................................................................. 212 6.5.1 JTA EntityManagers.......................................................................... 213 6.5.2 Resource-local EntityManagers ........................................................ 213 6.5.2.1 The EntityTransaction Interface ......................................... 213 6.5.3 Example ............................................................................................ 215 6.6 Container-managed Persistence Contexts ....................................................... 215 6.6.1 Container-managed Transaction-scoped Persistence Context .......... 216 6.6.2 Container-managed Extended Persistence Context .......................... 216 6.6.2.1 Inheritance of Extended Persistence Context ..................... 216 6.6.3 Persistence Context Propagation....................................................... 217 6.6.3.1 Requirements for Persistence Context Propagation ........... 217 6.6.4 Examples........................................................................................... 218 6.6.4.1 Container-managed Transaction-scoped Persistence Context218 6.6.4.2 Container-managed Extended Persistence Context ............ 219 6.7 Application-managed Persistence Contexts .................................................... 219 6.7.1 Examples........................................................................................... 221 6.7.1.1 Application-managed Persistence Context used in Stateless Session Bean221 6.7.1.2 Application-managed Persistence Context used in Stateless Session Bean222 6.7.1.3 Application-managed Persistence Context used in Stateful Session Bean223 6.7.1.4 Application-managed Persistence Context with Resource Transaction224 6.8 Requirements on the Container ....................................................................... 225 6.8.1 Application-managed Persistence Contexts...................................... 225 6.8.2 Container Managed Persistence Contexts......................................... 225 6.9 Runtime Contracts between the Container and Persistence Provider ............. 225 6.9.1 Container Responsibilities ................................................................ 225 6.9.2 Provider Responsibilities .................................................................. 227 6.10 Cache Interface................................................................................................ 228

10/31/08

Sun Microsystems, Inc.


Java Persistence 2.0, Public Review Draft

Chapter 7

Entity Packaging ............................................................................................................ 229 7.1 Persistence Unit ............................................................................................... 229 7.2 Persistence Unit Packaging ............................................................................. 230 7.2.1 persistence.xml file............................................................................ 231 7.2.1.1 name.................................................................................... 232 7.2.1.2 transaction-type................................................................... 232 7.2.1.3 description........................................................................... 232 7.2.1.4 provider............................................................................... 232 7.2.1.5 jta-data-source, non-jta-data-source.................................... 232 7.2.1.6 mapping-file, jar-file, class, exclude-unlisted-classes ........ 233 7.2.1.6.1 Annotated Classes in the Root of the Persistence Unit233 7.2.1.6.2 Object/relational Mapping Files ........................... 233 7.2.1.6.3 Jar Files................................................................. 234 7.2.1.6.4 List of Managed Classes....................................... 234 7.2.1.7 properties ............................................................................ 234 7.2.1.8 Examples............................................................................. 235 7.2.2 Persistence Unit Scope ...................................................................... 237 7.3 persistence.xml Schema................................................................................... 238 Container and Provider Contracts for Deployment and Bootstrapping ......................... 243 8.1 Java EE Deployment ....................................................................................... 243 8.1.1 Responsibilities of the Container ...................................................... 243 8.1.2 Responsibilities of the Persistence Provider ..................................... 244 8.1.3 javax.persistence.spi.PersistenceProvider ......................................... 244 8.1.3.1 Persistence Unit Properties ................................................. 246 8.1.4 javax.persistence.spi.PersistenceUnitInfo Interface.......................... 247 8.2 Bootstrapping in Java SE Environments ......................................................... 250 8.2.1 javax.persistence.Persistence Class................................................... 252 Metadata Annotations .................................................................................................... 255 9.1 Entity ............................................................................................................... 255 9.2 Callback Annotations ...................................................................................... 256 9.3 Annotations for Queries................................................................................... 257 9.3.1 NamedQuery Annotation .................................................................. 257 9.3.2 NamedNativeQuery Annotation........................................................ 257 9.3.3 Annotations for SQL Query Result Set Mappings............................ 258 9.4 References to EntityManager and EntityManagerFactory .............................. 259 9.4.1 PersistenceContext Annotation ......................................................... 259 9.4.2 PersistenceUnit Annotation............................................................... 260 Metadata for Object/Relational Mapping ...................................................................... 261 10.1 Annotations for Object/Relational Mapping ................................................... 261 10.1.1 Access Annotation............................................................................. 262 10.1.2 AssociationOverride Annotation....................................................... 262 10.1.3 AssociationOverrides Annotation ..................................................... 265

Chapter 8

Chapter 9

Chapter 10

10/31/08

10

Sun Microsystems, Inc.


Java Persistence 2.0, Public Review Draft

10.1.4 AttributeOverride Annotation ........................................................... 265 10.1.5 AttributeOverrides Annotation ......................................................... 268 10.1.6 Basic Annotation............................................................................... 269 10.1.7 CollectionTable Annotation .............................................................. 270 10.1.8 Column Annotation........................................................................... 272 10.1.9 DiscriminatorColumn Annotation..................................................... 274 10.1.10 DiscriminatorValue Annotation ........................................................ 275 10.1.11 ElementCollection Annotation.......................................................... 276 10.1.12 Embeddable Annotation.................................................................... 277 10.1.13 Embedded Annotation....................................................................... 278 10.1.14 EmbeddedId Annotation ................................................................... 279 10.1.15 Enumerated Annotation .................................................................... 279 10.1.16 GeneratedValue Annotation .............................................................. 280 10.1.17 Id Annotation .................................................................................... 282 10.1.18 IdClass Annotation............................................................................ 282 10.1.19 Inheritance Annotation...................................................................... 283 10.1.20 JoinColumn Annotation .................................................................... 284 10.1.21 JoinColumns Annotation................................................................... 286 10.1.22 JoinTable Annotation ........................................................................ 287 10.1.23 Lob Annotation ................................................................................. 288 10.1.24 ManyToMany Annotation................................................................. 289 10.1.25 ManyToOne Annotation ................................................................... 292 10.1.26 MapKey Annotation.......................................................................... 293 10.1.27 MapKeyClass Annotation ................................................................. 295 10.1.28 MapKeyColumn Annotation............................................................. 297 10.1.29 MapKeyJoinColumn Annotation ...................................................... 299 10.1.30 MapKeyJoinColumns Annotation..................................................... 301 10.1.31 MappedById Annotation................................................................... 302 10.1.32 MappedSuperclass Annotation ......................................................... 303 10.1.33 OneToMany Annotation ................................................................... 303 10.1.34 OneToOne Annotation ...................................................................... 306 10.1.35 OrderBy Annotation.......................................................................... 309 10.1.36 OrderColumn Annotation ................................................................. 310 10.1.37 PrimaryKeyJoinColumn Annotation................................................. 313 10.1.38 PrimaryKeyJoinColumns Annotation ............................................... 315 10.1.39 SecondaryTable Annotation .............................................................. 316 10.1.40 SecondaryTables Annotation ............................................................ 317 10.1.41 SequenceGenerator Annotation ........................................................ 318 10.1.42 Table Annotation............................................................................... 319 10.1.43 TableGenerator Annotation............................................................... 320 10.1.44 Temporal Annotation ........................................................................ 322 10.1.45 Transient Annotation......................................................................... 323 10.1.46 UniqueConstraint Annotation ........................................................... 323 10.1.47 Version Annotation ........................................................................... 324 10.2 Examples of the Application of Annotations for Object/Relational Mapping 325 10.2.1 Examples of Simple Mappings ......................................................... 325 10.2.2 A More Complex Example ............................................................... 328

11

10/31/08

Sun Microsystems, Inc.


Java Persistence 2.0, Public Review Draft

Chapter 11

XML Object/Relational Mapping Descriptor ................................................................ 333 11.1 Use of the XML Descriptor ............................................................................. 333 11.2 XML Overriding Rules.................................................................................... 334 11.2.1 persistence-unit-defaults Subelements .............................................. 334 11.2.1.1 schema ................................................................................ 334 11.2.1.2 catalog ................................................................................. 334 11.2.1.3 access .................................................................................. 335 11.2.1.4 cascade-persist .................................................................... 335 11.2.1.5 entity-listeners..................................................................... 335 11.2.2 Other Subelements of the entity-mappings element ......................... 335 11.2.2.1 package ............................................................................... 335 11.2.2.2 schema ................................................................................ 336 11.2.2.3 catalog ................................................................................. 336 11.2.2.4 access .................................................................................. 336 11.2.2.5 sequence-generator ............................................................. 336 11.2.2.6 table-generator .................................................................... 336 11.2.2.7 named-query ....................................................................... 337 11.2.2.8 named-native-query ............................................................ 337 11.2.2.9 sql-result-set-mapping ........................................................ 337 11.2.2.10 entity ................................................................................... 337 11.2.2.11 mapped-superclass .............................................................. 337 11.2.2.12 embeddable ......................................................................... 337 11.2.3 entity Subelements and Attributes..................................................... 338 11.2.3.1 metadata-complete .............................................................. 338 11.2.3.2 access .................................................................................. 338 11.2.3.3 name.................................................................................... 338 11.2.3.4 table..................................................................................... 338 11.2.3.5 secondary-table ................................................................... 338 11.2.3.6 primary-key-join-column.................................................... 338 11.2.3.7 id-class ................................................................................ 339 11.2.3.8 inheritance........................................................................... 339 11.2.3.9 discriminator-value ............................................................. 339 11.2.3.10 discriminator-column .......................................................... 339 11.2.3.11 sequence-generator ............................................................. 339 11.2.3.12 table-generator .................................................................... 339 11.2.3.13 attribute-override ................................................................ 340 11.2.3.14 association-override ............................................................ 340 11.2.3.15 named-query ....................................................................... 340 11.2.3.16 named-native-query ............................................................ 340 11.2.3.17 sql-result-set-mapping ........................................................ 340 11.2.3.18 exclude-default-listeners ..................................................... 341 11.2.3.19 exclude-superclass-listeners................................................ 341 11.2.3.20 entity-listeners..................................................................... 341 11.2.3.21 pre-persist, post-persist, pre-remove, post-remove, pre-update, post-update, post-load341 11.2.3.22 attributes.............................................................................. 341 11.2.3.22.1 id ........................................................................... 341 11.2.3.22.2 embedded-id ......................................................... 341 11.2.3.22.3 basic...................................................................... 341

10/31/08

12

Sun Microsystems, Inc.


Java Persistence 2.0, Public Review Draft

11.2.3.22.4 version .................................................................. 341 11.2.3.22.5 many-to-one ......................................................... 342 11.2.3.22.6 one-to-many ......................................................... 342 11.2.3.22.7 one-to-one............................................................. 342 11.2.3.22.8 many-to-many ...................................................... 342 11.2.3.22.9 element-collection ................................................ 342 11.2.3.22.10 embedded ............................................................. 342 11.2.3.22.11 transient ................................................................ 342 11.2.4 mapped-superclass Subelements and Attributes ............................... 342 11.2.4.1 metadata-complete.............................................................. 342 11.2.4.2 access .................................................................................. 343 11.2.4.3 id-class ................................................................................ 343 11.2.4.4 exclude-default-listeners..................................................... 343 11.2.4.5 exclude-superclass-listeners ............................................... 343 11.2.4.6 entity-listeners .................................................................... 343 11.2.4.7 pre-persist, post-persist, pre-remove, post-remove, pre-update, post-update, post-load343 11.2.4.8 attributes ............................................................................. 343 11.2.4.8.1 id........................................................................... 344 11.2.4.8.2 embedded-id ......................................................... 344 11.2.4.8.3 basic...................................................................... 344 11.2.4.8.4 version .................................................................. 344 11.2.4.8.5 many-to-one ......................................................... 344 11.2.4.8.6 one-to-many ......................................................... 344 11.2.4.8.7 one-to-one............................................................. 344 11.2.4.8.8 many-to-many ...................................................... 344 11.2.4.8.9 element-collection ................................................ 344 11.2.4.8.10 embedded ............................................................. 344 11.2.4.8.11 transient ................................................................ 345 11.2.5 embeddable Subelements and Attributes .......................................... 345 11.2.5.1 metadata-complete.............................................................. 345 11.2.5.2 access .................................................................................. 345 11.2.5.3 attributes ............................................................................. 345 11.2.5.3.1 basic...................................................................... 345 11.2.5.3.2 many-to-one ......................................................... 345 11.2.5.3.3 one-to-many ......................................................... 345 11.2.5.3.4 one-to-one............................................................. 346 11.2.5.3.5 many-to-many ...................................................... 346 11.2.5.3.6 element-collection ................................................ 346 11.2.5.3.7 embedded ............................................................. 346 11.2.5.3.8 transient ................................................................ 346 11.3 XML Schema................................................................................................... 347 Chapter 12 Appendix A Related Documents ........................................................................................................ 375 Revision History ............................................................................................................ 377 A.1 Early Draft 1 .................................................................................................... 377 A.2 Public Review Draft ........................................................................................ 379

13

10/31/08

Sun Microsystems, Inc.


Java Persistence 2.0, Public Review Draft

10/31/08

14

Sun Microsystems, Inc.


Java Persistence 2.0, Public Review Draft

List of Tables
Table 1 Table 2 Table 3 Table 4 Table 5 Table 6 Table 7 Table 8 Table 9 Table 10 Table 11 Table 12 Table 13 Table 14 Table 15 Table 16 Table 17 Table 18 Table 19 Table 20 Table 21 Table 22 Table 23 Table 24 Table 25 Table 26 Table 27 Table 28 Table 29 Table 30 Table 31 Table 32 Table 33 Table 34 Table 35 Table 36 Table 37 Table 38 Table 39 Table 40 Table 41 Definition of the AND Operator ...........................................................................................................139 Definition of the OR Operator ..............................................................................................................139 Definition of the NOT Operator............................................................................................................139 Access Annotation Elements.................................................................................................................262 AssociationOverride Annotation Elements ...........................................................................................263 AssociationOverrides Annotation Elements .........................................................................................265 AttributeOverride Annotation Elements ...............................................................................................266 AtributeOverrides Annotation Elements...............................................................................................268 Basic Annotation Elements ...................................................................................................................270 CollectionTable Annotation Elements ..................................................................................................271 Column Annotation Elements ...............................................................................................................273 DiscriminatorColumn Annotation Elements.........................................................................................275 DiscriminatorValueAnnotation Elements..............................................................................................276 ElementCollection Annotation Elements ..............................................................................................277 Enumerated Annotation Elements.........................................................................................................280 GeneratedValue Annotation Elements ..................................................................................................281 IdClass Annotation Elements ................................................................................................................282 Inheritance Annotation Elements ..........................................................................................................283 JoinColumn Annotation Elements ........................................................................................................285 JoinColumns Annotation Elements.......................................................................................................287 JoinTable Annotation Elements ............................................................................................................288 ManyToMany Annotation Elements .....................................................................................................290 ManyToOne Annotation Elements........................................................................................................292 MapKey Annotation Elements ..............................................................................................................294 MapKeyClass Annotation Elements .....................................................................................................295 MapKeyColumn Annotation Elements .................................................................................................297 MapKeyJoinColumn Annotation Elements ..........................................................................................300 MapKeyJoinColumns Annotation Elements.........................................................................................302 MappedBy IdAnnotation Elements .......................................................................................................302 OneToMany Annotation Elements........................................................................................................305 OneToOne Annotation Elements ..........................................................................................................307 OrderBy Annotation Elements ..............................................................................................................309 OrderColumn Annotation Elements...................................................................................................... 311 PrimaryKeyJoinColumn Annotation Elements.....................................................................................314 PrimaryKeyJoinColumns Annotation Elements ...................................................................................315 SecondaryTable Annotation Elements ..................................................................................................317 SecondaryTables Annotation Elements.................................................................................................318 SequenceGenerator Annotation Elements.............................................................................................319 Table Annotation Elements ...................................................................................................................319 TableGenerator Annotation Elements ...................................................................................................321 Temporal Annotation Elements.............................................................................................................322

15

10/31/08

Sun Microsystems, Inc.


Java Persistence 2.0, Public Review Draft

Table 42 UniqueConstraint Annotation Elements................................................................................................323

10/31/08

16

Sun Microsystems, Inc.


Java Persistence 2.0, Public Review 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/relational 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 manage a relational database. This is the Public Review Draft of the Java Persistence 2.0 specification. This draft addresses improvements in the areas of domain modeling, O/R mapping, EntityManager and Query interfaces, the Java Persistence query language, and an API for criteria queries. We welcome feedback from the community on the features in this draft.

1.1 Expert Group


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 past and present members of the JSR 317 Expert Group: Adobe Systems Inc.: Jeff Vroom; akquinet tech@Spree: Michael Bouschen; BEA Systems: Patrick Linskey; DataDirect: Eric Samson; Ericsson AB: Erik Brakkee; IBM: Kevin Sutter, Pinaki Poddar; 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.

1.2 Document Conventions


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 describing typical use, or notes clarifying the text with prescriptive specification. The Courier font is used for code examples. The Helvetica font is used to specify the BNF of the Java Persistence query language.

17

10/31/08

Sun Microsystems, Inc.


Introduction Java Persistence 2.0, Public Review Draft Document Conventions

This document is written in terms of the use of Java language metadata annotations. An XML descriptor (as specified in Chapter 11) 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 semantics apply when the XML descriptor is used as an alternative.

10/31/08

18

JSR-317 Public Review Draft

Sun Microsystems, Inc.


The Entity Class Java Persistence 2.0, Public Review Draft Entities

C ha p t e r 2

Entities

An entity is a lightweight persistent domain object. 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. This chapter describes requirements on entity classes and instances.

2.1 The Entity Class


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.

JSR-317 Public Review Draft

19

10/31/08

Sun Microsystems, Inc.


Entities Java Persistence 2.0, Public Review 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. Entities support inheritance, polymorphic associations, and polymorphic queries. 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 JavaBeans 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 entitys methodsi.e., accessor methods (getter/setter methods) or other business methods.

2.2 Persistent Fields and Properties


The persistent state of an entity is accessed by the persistence provider runtime[1] either via JavaBeans style property accessors (property access) or via instance variables (field access). Whether persistent properties or persistent fields or a combination of the two is used for the providers 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 accessor 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 property-based access is used. In this case, for every persistent property property of type T of the entity, there is a getter method, getProperty, and setter method setProperty. For boolean properties, isProperty may be used as an alternative name for the getter method.[2] For single-valued persistent properties, these method signatures are:

T getProperty() void setProperty(T t)

[1] [2]

The term "persistence provider runtime" refers to the runtime environment of the persistence implementation. In Java EE environments, this may be the Java EE container or a third-party persistence provider implementation integrated with it. 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).

10/31/08

20

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Persistent Fields and Properties Java Persistence 2.0, Public Review Draft Entities

Collection-valued persistent fields and properties must be defined in terms of one of the following collection-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[3], java.util.Map. The collection 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. Terminology Note: The terms collection and collection-valued are used in this specification 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 when a collection of type java.util.Map needs to be distinguished as such. 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 runtime executes this logic when property-based access is used. Caution should be exercised in adding business logic to the accessor methods when property-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 methods 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.[4] 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 persistent 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.

[3] [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. 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 10.

JSR-317 Public Review Draft

21

10/31/08

Sun Microsystems, Inc.


Entities Java Persistence 2.0, Public Review 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[5], java.sql.Date, java.sql.Time, java.sql.Timestamp, byte[], Byte[], char[], Character[], and user-defined types that implement the Serializable interface); 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 10.

2.2.1 Example
@Entity public class Customer implements Serializable { private Long id; private String name; private Address address; private Collection<Order> orders = new HashSet(); private Set<PhoneNumber> phones = new HashSet(); // No-arg constructor public Customer() {} @Id // property access is used public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; }

[5]

Note that an instance of Calendar must be fully initialized for the type that it is mapped to.

10/31/08

22

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Access Type Java Persistence 2.0, Public Review Draft Entities

@OneToMany public Collection<Order> getOrders() { return orders; } public void setOrders(Collection<Order> orders) { this.orders = orders; } @ManyToMany public Set<PhoneNumber> getPhones() { return phones; } public void setPhones(Set<PhoneNumber> phones) { this.phones = phones; } // Business method to add a phone number to the customer public void addPhone(PhoneNumber phone) { this.getPhones().add(phone); // Update the phone entity instance to refer to this customer phone.addCustomer(this); } }

2.3 Access Type


2.3.1 Default Access Type
By default, a single access type (field or property access) applies to an entity hierarchy. The default access type of an entity hierarchy is determined by the placement of mapping annotations on the attributes of those entity classes and mapped superclasses of the entity hierarchy that do not explicitly specify an access type. An access type is explicitly specified by means of the Access annotation.[6] 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 variables directly. All non-transient instance variables that are not annotated with the Transient annotation are persistent.

When property-based access is used, the object/relational mapping annotations for the entity

class annotate the getter property accessors[7], and the persistence provider runtime accesses

[6] [7]

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 11. These annotations must not be applied to the setter methods.

JSR-317 Public Review Draft

23

10/31/08

Sun Microsystems, Inc.


Entities Java Persistence 2.0, Public Review Draft Access Type

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. It is an error if a default access type cannot be determined and an access type is not explicitly specified by means of annotations or the XML descriptor. The behavior of applications that mix the placement of annotations on fields and properties within an entity hierarchy without explicitly specifying the Access annotation is undefined.

2.3.2 Explicit Access Type


An access type for an individual entity class, mapped superclass, or embeddable class can be specified for that class independent of the default for the entity hierarchy by means of the Access annotation applied to the class. This explicit access type specification does not affect the access type of other entity classes or mapped superclasses in the entity hierarchy. The following rules apply:

When Access(FIELD) is applied to an entity class, mapped superclass, or embeddable


class, mapping annotations may be placed on the instance variables of that class, and the persistence provider runtime accesses persistent state via the instance variables defined by the class. All non-transient instance variables that are not annotated with the Transient annotation are persistent. When Access(FIELD) is applied to such a class, it is possible to selectively designate individual attributes within the class for property access. To specify a persistent property for access by the persistence provider runtime, that property must be designated Access(PROPERTY).[8] The behavior is undefined if mapping annotations are placed on any properties defined by the class for which Access(PROPERTY) is not specified. Persistent state inherited from superclasses is accessed in accordance with the access types of those superclasses.

When Access(PROPERTY) is applied to an entity class, mapped superclass, or embeddable


class, mapping annotations may be placed on the properties of that class, and the persistence provider runtime accesses persistent state via the properties defined by that class. All properties that are not annotated with the Transient annotation are persistent. When Access(PROPERTY) is applied to such a class, it is possible to selectively designate individual attributes within the class for instance variable access. To specify a persistent instance variable for access by the persistence provider runtime, that instance variable must be designated Access(FIELD). The behavior is undefined if mapping annotations are placed on any instance variables defined by the class for which Access(FIELD) is not specified. Persis-

[8]

It is permitted (but redundant) to place Access(FIELD) on a persistent field whose class has field access type or Access(PROPERTY) 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).

10/31/08

24

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Primary Keys and Entity Identity Java Persistence 2.0, Public Review Draft Entities

tent state inherited from superclasses is accessed in accordance with the access types of those superclasses. Note that when access types are combined within a class, the Transient annotation should be used to avoid duplicate persistent mappings.

2.3.3 Access Type of an Embeddable Class


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 collection) 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.

2.4 Primary Keys and Entity Identity


Every entity must have a primary key. 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 Section 10.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 represent 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 or IdClass annotation is used to denote a composite primary key. See Sections 10.1.14 and 10.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.BigInteger.[9] 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 portable. 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.

[9]

In general, however, approximate numeric types (e.g., floating point types) should never be used in primary keys.

JSR-317 Public Review Draft

25

10/31/08

Sun Microsystems, Inc.


Entities Java Persistence 2.0, Public Review Draft Primary Keys and Entity Identity

The following rules apply for composite primary keys:

The primary key class must be public and must have a public no-arg constructor. 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 protected.

The primary key class must be serializable. 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 10.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 10.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[10]. The behavior is undefined if this occurs.[11]

2.4.1 Primary Keys Corresponding to Derived Identities


The identity of an entity may be derived from the identity of another entity (the "parent" entity) when the former entity (the "dependent" entity) is the owner of a many-to-one or one-to-one relationship to the parent entity and a foreign key maps the relationship from dependent to parent. If a many-to-one or one-to-one entity relationship corresponds to a primary key attribute, the entity containing this relationship cannot be persisted without the relationship having been assigned an entity since the identity of the entity containing the relationship is derived from the referenced entity. 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.
[10] This includes not changing the value of a mutable type that is primary key or an attribute of a composite primary key. [11] The implementation may, but is not required to, throw an exception. Portable applications must not rely on any such specific behavior.

10/31/08

26

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Primary Keys and Entity Identity Java Persistence 2.0, Public Review 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 primary key of the dependent entity[12]. 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 composite key. A dependent entity may have more than one parent entity.

2.4.1.1 Specification of Derived Identities


If the dependent entity uses an id class to represent its primary key, the names of the attributes of the id class and the Id attributes of the dependent entity class must correspond as follows:

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 an Id attribute in the entity is a many-to-one or one-to-one reference to a parent entity, the


type of the corresponding attribute in the id class must be the same Java type as the id class or embedded id of the parent entity (if the parent entity has a composite primary key) or the type of the Id attribute of the parent entity (if the parent entity has a simple primary key). If the dependent entity uses an embedded id to represent its primary key, the primary key attribute corresponding 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 relationship attribute is of the same Java type as the dependent's primary key, then the value element is not specified.[13] 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 separate Id attribute is specified and the relationship attribute is annotated MappedById.

[12] 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. [13] 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.

JSR-317 Public Review Draft

27

10/31/08

Sun Microsystems, Inc.


Entities Java Persistence 2.0, Public Review Draft Primary Keys and Entity Identity

2.4.1.2 Examples of Derived Identities


Example 1: The parent entity has a simple primary key: @Entity public class Employee { @Id long empId; String name; ... } Case (a): The dependent entity uses IdClass to represent a composite key: public class DependentId { String name; // matches name of @Id attribute long emp; // matches name of @Id attribute and type of Employee PK } @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' Case(b): The dependent entity uses EmbeddedId to represent a composite key: @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; }

10/31/08

28

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Primary Keys and Entity Identity Java Persistence 2.0, Public Review Draft Entities

Sample query: SELECT d FROM Dependent d WHERE d.id.name = 'Joe' AND d.emp.name = 'Sam' Example 2: The parent entity uses IdClass: public class EmployeeId { String firstName; String lastName; ... } @Entity @IdClass(EmployeeId.class) public class Employee { @Id String firstName @Id String lastName ... } Case (a): The dependent entity uses IdClass: public class DependentId { String name; // matches name of attribute EmployeeId emp; //matches name of attribute and type of Employee PK @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' Case (b): The dependent entity uses EmbeddedId. The type of the empPK attribute is the same as that of the primary key of Employee. @Embeddable public class DependentId { String name; EmployeeId empPK; }

JSR-317 Public Review Draft

29

10/31/08

Sun Microsystems, Inc.


Entities Java Persistence 2.0, Public Review Draft Primary Keys and Entity Identity

@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.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: The parent entity uses EmbeddedId: @Embeddable public class EmployeeId { String firstName; String lastName; ... } @Entity public class Employee { @EmbeddedId EmployeeId empId; ... } Case (a): The dependent entity uses IdClass: public class DependentId { String name; // matches name of @Id attribute EmployeeId emp; // matches name of @Id attribute and type of embedded id of Employee @Entity @IdClass(DependentId.class) public class Dependent { @Id String name; @Id @ManyToOne Employee emp; }

10/31/08

30

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Primary Keys and Entity Identity Java Persistence 2.0, Public Review Draft Entities

Sample query: SELECT d FROM Dependent d WHERE d.name = 'Joe' and d.emp.empId.firstName = 'Sam' Case (b): The dependent entity uses EmbeddedId: @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: The parent entity has a simple primary key: @Entity public class Person { @Id String ssn; ... } Case (a): The dependent entity has a single relationship attribute corresponding to the parents primary key. The primary key of MedicalHistory is of type String. @Entity public class MedicalHistory { @Id @OneToOne Person patient; ... }

JSR-317 Public Review Draft

31

10/31/08

Sun Microsystems, Inc.


Entities Java Persistence 2.0, Public Review Draft Primary Keys and Entity Identity

Sample query: SELECT m FROM MedicalHistory m WHERE m.patient.ssn = '123-45-6789' Case (b): 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 corresponding to the primary key. This attribute is mapped to the primary key by the MappedById annotation applied to the relationship. [14] @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 parent entity. public class PersonId { String firstName; String lastName; } @Entity @IdClass(PersonId.class) public class Person { @Id String firstName; @Id String lastName; ... }

[14] 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.

10/31/08

32

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Primary Keys and Entity Identity Java Persistence 2.0, Public Review Draft Entities

Case (a): The dependent entity uses IdClass: @Entity @IdClass(PersonId.class) public class MedicalHistory { @Id @OneToOne Person patient; ... } Sample query: SELECT m FROM MedicalHistory m WHERE m.patient.firstName = 'Charles' Case (b): 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; }

JSR-317 Public Review Draft

33

10/31/08

Sun Microsystems, Inc.


Entities Java Persistence 2.0, Public Review Draft Embeddable Classes

@Entity public class Person { @EmbeddedId PersonId id; ... } Case (a): The dependent class uses IdClass: @Entity @IdClass(PersonId.class) public class MedicalHistory { @Id @OneToOne Person patient; ... } Case (b): The dependent class uses EmbeddedId: @Entity public class MedicalHistory { @EmbeddedId PersonId id; ... @MappedById @OneToOne Person patient; ... }

2.5 Embeddable Classes


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-valued 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 exception 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 Section 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.[15]

10/31/08

34

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Collections of Embeddable Classes and Basic TypesJava Persistence 2.0, Public Review 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 that contains the embeddable instance(s) and not to the embeddable itself.[16] 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 10.1.12.

2.6 Collections of Embeddable Classes and Basic Types


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 10.1.7. If the ElementCollection 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 such a relationship and the relationship must be mapped by a foreign key mapping. (See Section 2.9.)

2.7 Map Collections


Collections of elements and entity relationships can be represented as java.util.Map collections. 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. When the map value is a basic type or embeddable class, the ElementCollection annotation is used. When the map value is an entity, the OneToMany and ManyToMany annotations are used. Bidirectional relationships represented as java.util.Map collections support the use of the Map datatype on one side of the relationship only.

2.7.1 Map Keys


If the map key type is a basic type, the MapKeyColumn annotation is used to specify the column mapping for the map key. If the MapKeyColumn annotation is not specified, the default values of the MapKeyColumn annotation apply as described in section 10.1.28.
[15] Direct or indirect circular containment dependencies among embeddable classes are not permitted. [16] An entity cannot have a unidirectional relationship to the embeddable class of another entity (or itself).

JSR-317 Public Review Draft

35

10/31/08

Sun Microsystems, Inc.


Entities Java Persistence 2.0, Public Review DraftMapping Defaults for Non-Relationship Fields

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 10.1.8, Column Annotation). The AttributeOverride and AttributeOverrides annotations can be used to override these mappings, as described in sections 10.1.4 and 10.1.5. If an embeddable class is used as a map key, the embeddable class must implement the hashCode and equals methods consistently with the database columns to which the embeddable is mapped[17]. 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 10.1.29. If Java generic types are not used in the declaration of a relationship attribute of type java.util.Map, the MapKeyClass annotation must be used to specify the type of the key of the map. 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. The MapKeyClass annotation is not used when MapKey is specified.

2.7.2 Map Values


When the value type of the map is a basic type or an embeddable class, a collection table is used to map the map. If Java generic types are not used, the ElementCollection annotation must specify the value type for 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 10.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 bidirectional 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. Default mappings are described in Section 2.10.

2.8 Mapping Defaults for Non-Relationship Fields or Properties


If a persistent field or property other than a relationship property is not annotated with one of the mapping annotations defined in Chapter 10 (or equivalent mapping information is not specified in the XML descriptor), the following default mapping rules are applied in order:

[17] Note that when an embeddable instance is used as a map key, these attributes represent its identity. Changes to embeddable instances used as map keys have undefined behaviour and should be avoided.

10/31/08

36

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Entity Relationships Java Persistence 2.0, Public Review Draft Entities

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 Sections 10.1.12 and 10.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 10.1.6, 10.1.15, 10.1.23, and 10.1.44. It is an error if no annotation is present and none of the above rules apply.

2.9 Entity Relationships


Relationships among entities may be one-to-one, one-to-many, many-to-one, or many-to-many. Relationships are polymorphic. 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 target 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.[18] 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 relational database schema to be fully defaulted, to provide an ease-of-development facility. This is described in Section 2.10, Relationship Mapping Defaults. Relationships may be bidirectional or unidirectional. A bidirectional relationship has both an owning side and an inverse (non-owning) side. A unidirectional relationship has only an owning side. The owning side of a relationship determines the updates to the relationship in the database, as described in section 3.2.4. The following rules apply to bidirectional relationships:

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 relationship.

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.

[18] For associations of type java.util.Map, target type refers to the type that is the Map value.

JSR-317 Public Review Draft

37

10/31/08

Sun Microsystems, Inc.


Entities Java Persistence 2.0, Public Review Draft Entity Relationships

For one-to-one bidirectional relationships, the owning side corresponds to the side that contains 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 OneToOne or OneToMany. Applications that apply cascade=REMOVE to other associations are not portable. 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 operation will be applied to the entity being orphaned. 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 reassign an entity that has been orphaned to another relationship or otherwise attempt to persist it. 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 a managed 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)[19]. Section 2.10, Relationship Mapping Defaults, defines relationship mapping defaults for entity relationships. Additional mapping annotations (e.g., column and table mapping annotations) may be specified to override or further refine the default mappings and mapping strategies described in Section 2.10. In addition, 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 10.1.20 and 10.1.22. Schema-level mapping annotations must be specified on the owning side of the relationship. Any overriding of mapping defaults must be consistent with the relationship modeling annotation that is specified. 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).

[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.

10/31/08

38

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Relationship Mapping Defaults Java Persistence 2.0, Public Review Draft Entities

Note that it is the application that bears responsibility for maintaining the consistency of runtime relationshipsfor example, for insuring that the one and the many sides of a bidirectional relationship are consistent with one another when the application updates the relationship at runtime. 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.

2.10 Relationship Mapping Defaults


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.

2.10.1 Bidirectional OneToOne Relationships


Assuming that: Entity A references a single instance of Entity B. Entity B references a single instance of Entity A. Entity A is specified as the owner of the relationship. The following mapping defaults apply: Entity A is mapped to a table named A. Entity B is mapped to a table named B. Table A contains a foreign key to table B. The foreign key column name is formed as the concatenation of the following: the name of the relationship property or field of entity A; "_"; the name of the primary key column in table B. The foreign key column has the same type as the primary key of table B and there is a unique key constraint on it. Example: @Entity public class Employee { private Cubicle assignedCubicle; @OneToOne public Cubicle getAssignedCubicle() { return assignedCubicle; } public void setAssignedCubicle(Cubicle cubicle) { this.assignedCubicle = cubicle; } ... }

JSR-317 Public Review Draft

39

10/31/08

Sun Microsystems, Inc.


Entities Java Persistence 2.0, Public Review Draft Relationship Mapping Defaults

@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: Entity Employee references a single instance of Entity Cubicle. Entity Cubicle references a single instance of Entity Employee. Entity Employee is the owner of the relationship. The following mapping defaults apply: Entity Employee is mapped to a table named EMPLOYEE. Entity Cubicle is mapped to a table named CUBICLE. Table EMPLOYEE contains a foreign key to table CUBICLE. The foreign key column is named ASSIGNEDCUBICLE_<PK of CUBICLE>, where <PK of CUBICLE> denotes the name of the primary key column of table CUBICLE. The foreign key column has the same type as the primary key of CUBICLE, and there is a unique key constraint on it.

2.10.2 Bidirectional ManyToOne / OneToMany Relationships


Assuming that: Entity A references a single instance of Entity B. Entity B references a collection of Entity A[20]. Entity A must be the owner of the relationship. The following mapping defaults apply: Entity A is mapped to a table named A. Entity B is mapped to a table named B. Table A contains a foreign key to table B. The foreign key column name is formed as the concatenation of the following: the name of the relationship property or field of entity A; "_"; the

[20] When the relationship is modeled as a java.util.Map, Entity B references a collection of Entity A means that Entity B references a map collection in which the type of the Map value is Entity A. The map key may be a basic type, embeddable class, or an entity.

10/31/08

40

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Relationship Mapping Defaults Java Persistence 2.0, Public Review Draft Entities

name of the primary key column in table B. The foreign key column has the same type as the primary key of table B. 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; } public void setEmployees(Collection<Employee> employees) { this.employees = employees; } ... }

In this example: Entity Employee references a single instance of Entity Department. Entity Department references a collection of Entity Employee. Entity Employee is the owner of the relationship. The following mapping defaults apply: Entity Employee is mapped to a table named EMPLOYEE. Entity Department is mapped to a table named DEPARTMENT. Table EMPLOYEE contains a foreign key to table DEPARTMENT. The foreign key column is named DEPARTMENT_<PK of DEPARTMENT>, where <PK of DEPARTMENT> denotes the name of the primary key column of table DEPARTMENT. The foreign key column has the same type as the primary key of DEPARTMENT.

JSR-317 Public Review Draft

41

10/31/08

Sun Microsystems, Inc.


Entities Java Persistence 2.0, Public Review Draft Relationship Mapping Defaults

2.10.3 Unidirectional Single-Valued Relationships


Assuming that: Entity A references a single instance of Entity B. Entity B does not reference Entity A. 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.

2.10.3.1 Unidirectional OneToOne Relationships


The following mapping defaults apply: Entity A is mapped to a table named A. Entity B is mapped to a table named B. Table A contains a foreign key to table B. The foreign key column name is formed as the concatenation of the following: the name of the relationship property or field of entity A; "_"; the name of the primary key column in table B. The foreign key column has the same type as the primary key of table B and there is a unique key constraint on it. 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: Entity Employee references a single instance of Entity TravelProfile. Entity TravelProfile does not reference Entity Employee. Entity Employee is the owner of the relationship.

10/31/08

42

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Relationship Mapping Defaults Java Persistence 2.0, Public Review Draft Entities

The following mapping defaults apply: Entity Employee is mapped to a table named EMPLOYEE. Entity TravelProfile is mapped to a table named TRAVELPROFILE. Table EMPLOYEE contains a foreign key to table TRAVELPROFILE. The foreign key column is named PROFILE_<PK of TRAVELPROFILE>, where <PK of TRAVELPROFILE> denotes the name of the primary key column of table TRAVELPROFILE. The foreign key column has the same type as the primary key of TRAVELPROFILE, and there is a unique key constraint on it.

2.10.3.2 Unidirectional ManyToOne Relationships


The following mapping defaults apply: Entity A is mapped to a table named A. Entity B is mapped to a table named B. Table A contains a foreign key to table B. The foreign key column name is formed as the concatenation of the following: the name of the relationship property or field of entity A; "_"; the name of the primary key column in table B. The foreign key column has the same type as the primary key of table B. 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: Entity Employee references a single instance of Entity Address. Entity Address does not reference Entity Employee. Entity Employee is the owner of the relationship.

JSR-317 Public Review Draft

43

10/31/08

Sun Microsystems, Inc.


Entities Java Persistence 2.0, Public Review Draft Relationship Mapping Defaults

The following mapping defaults apply: Entity Employee is mapped to a table named EMPLOYEE. Entity Address is mapped to a table named ADDRESS. Table EMPLOYEE contains a foreign key to table ADDRESS. The foreign key column is named ADDRESS_<PK of ADDRESS>, where <PK of ADDRESS> denotes the name of the primary key column of table ADDRESS. The foreign key column has the same type as the primary key of ADDRESS.

2.10.4 Bidirectional ManyToMany Relationships


Assuming that: Entity A references a collection of Entity B. Entity B references a collection of Entity A. Entity A is the owner of the relationship. The following mapping defaults apply: Entity A is mapped to a table named A. Entity B is mapped to a table named B. There is a join table that is named A_B (owner name first). This join table has two foreign key columns. One foreign key column refers to table A and has the same type as the primary key of table A. The name of this foreign key column is formed as the concatenation of the following: the name of the relationship property or field of entity B; "_"; the name of the primary key column in table A. The other foreign key column refers to table B and has the same type as the primary key of table B. The name of this foreign key column is formed as the concatenation of the following: the name of the relationship property or field of entity A; "_"; the name of the primary key column in table B. Example: @Entity public class Project { private Collection<Employee> employees; @ManyToMany public Collection<Employee> getEmployees() { return employees; } public void setEmployees(Collection<Employee> employees) { this.employees = employees; } ... }

10/31/08

44

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Relationship Mapping Defaults Java Persistence 2.0, Public Review Draft Entities

@Entity public class Employee { private Collection<Project> projects; @ManyToMany(mappedBy="employees") public Collection<Project> getProjects() { return projects; } public void setProjects(Collection<Project> projects) { this.projects = projects; } ... } In this example: Entity Project references a collection of Entity Employee. Entity Employee references a collection of Entity Project. Entity Project is the owner of the relationship. The following mapping defaults apply: Entity Project is mapped to a table named PROJECT. Entity Employee is mapped to a table named EMPLOYEE. There is a join table that is named PROJECT_EMPLOYEE (owner name first). This join table has two foreign key columns. One foreign key column refers to table PROJECT and has the same type as the primary key of PROJECT. The name of this foreign key column is PROJECTS_<PK of PROJECT>, where <PK of PROJECT> denotes the name of the primary key column of table PROJECT. The other foreign key column refers to table EMPLOYEE and has the same type as the primary key of EMPLOYEE. The name of this foreign key column is EMPLOYEES_<PK of EMPLOYEE>, where <PK of EMPLOYEE> denotes the name of the primary key column of table EMPLOYEE.

2.10.5 Unidirectional Multi-Valued Relationships


Assuming that: Entity A references a collection of Entity B. Entity B does not reference Entity A. 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.

JSR-317 Public Review Draft

45

10/31/08

Sun Microsystems, Inc.


Entities Java Persistence 2.0, Public Review Draft Relationship Mapping Defaults

2.10.5.1 Unidirectional OneToMany Relationships


The following mapping defaults apply: Entity A is mapped to a table named A. Entity B is mapped to a table named B. There is a join table that is named A_B (owner name first). This join table has two foreign key columns. One foreign key column refers to table A and has the same type as the primary key of table A. The name of this foreign key column is formed as the concatenation of the following: the name of entity A; "_"; the name of the primary key column in table A. The other foreign key column refers to table B and has the same type as the primary key of table B and there is a unique key constraint on it. The name of this foreign key column is formed as the concatenation of the following: the name of the relationship property or field of entity A; "_"; the name of the primary key column in table B. Example: @Entity public class Employee { private Collection<AnnualReview> annualReviews; @OneToMany public Collection<AnnualReview> getAnnualReviews() { return annualReviews; } public void setAnnualReviews(Collection<AnnualReview> annualReviews) { this.annualReviews = annualReviews; } ... } @Entity public class AnnualReview { ... } In this example: Entity Employee references a collection of Entity AnnualReview. Entity AnnualReview does not reference Entity Employee. Entity Employee is the owner of the relationship. The following mapping defaults apply: Entity Employee is mapped to a table named EMPLOYEE. Entity AnnualReview is mapped to a table named ANNUALREVIEW. There is a join table that is named EMPLOYEE_ANNUALREVIEW (owner name first). This join table has two foreign key columns. One foreign key column refers to table EMPLOYEE
10/31/08

46

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Relationship Mapping Defaults Java Persistence 2.0, Public Review Draft Entities

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 ANNUALREVIEW and has the same type as the primary key of ANNUALREVIEW. This foreign key column is named ANNUALREVIEWS_<PK of ANNUALREVIEW>, where <PK of ANNUALREVIEW> 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.

2.10.5.2 Unidirectional ManyToMany Relationships


The following mapping defaults apply: Entity A is mapped to a table named A. Entity B is mapped to a table named B. There is a join table that is named A_B (owner name first). This join table has two foreign key columns. One foreign key column refers to table A and has the same type as the primary key of table A. The name of this foreign key column is formed as the concatenation of the following: the name of entity A; "_"; the name of the primary key column in table A. The other foreign key column refers to table B and has the same type as the primary key of table B. The name of this foreign key column is formed as the concatenation of the following: the name of the relationship property or field of entity A; "_"; the name of the primary key column in table B. Example: @Entity public class Employee { private Collection<Patent> patents; @ManyToMany public Collection<Patent> getPatents() { return patents; } public void setPatents(Collection<Patent> patents) { this.patents = patents; } ... } @Entity public class Patent { ... } In this example: Entity Employee references a collection of Entity Patent. Entity Patent does not reference Entity Employee. Entity Employee is the owner of the relationship.

JSR-317 Public Review Draft

47

10/31/08

Sun Microsystems, Inc.


Entities Java Persistence 2.0, Public Review Draft Inheritance

The following mapping defaults apply: Entity Employee is mapped to a table named EMPLOYEE. Entity Patent is mapped to a table named PATENT. There is a join table that is named EMPLOYEE_PATENT (owner name first). This join table has two foreign key columns. One foreign key column refers to table EMPLOYEE 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 PATENT and has the same type as the primary key of PATENT. This foreign key column is named PATENTS_<PK of PATENT>, where <PK of PATENT> denotes the name of the primary key column of table PATENT.

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. These concepts are described further in the following sections.

2.11.1 Abstract Entity Classes


An abstract class can be specified as an entity. An abstract entity differs from a concrete entity only in that it cannot be directly instantiated. An abstract entity is mapped as an entity and can be the target of queries (which will operate over and/or retrieve instances of its concrete subclasses). 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. Example: Abstract class as an Entity @Entity @Table(name="EMP") @Inheritance(strategy=JOINED) public abstract class Employee { @Id protected Integer empId; @Version protected Integer version; @ManyToOne protected Address address; ... }

10/31/08

48

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Inheritance Java Persistence 2.0, Public Review Draft Entities

@Entity @Table(name="FT_EMP") @DiscriminatorValue("FT") @PrimaryKeyJoinColumn(name="FT_EMPID") public class FullTimeEmployee extends Employee { // Inherit empId, but mapped in this class to FT_EMP.FT_EMPID // Inherit version mapped to EMP.VERSION // Inherit address mapped to EMP.ADDRESS fk // 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; ... }

2.11.2 Mapped Superclasses


An entity may inherit from a superclass that provides persistent entity state and mapping information, but which is not itself an entity. Typically, the purpose of such a mapped superclass is to define state and mapping information that is common to multiple entity classes. A mapped superclass, unlike an entity, is not queryable and cannot be passed as an argument to EntityManager or Query operations. A mapped superclass cannot be the target of a persistent relationship. Both abstract and concrete classes may be specified as mapped superclasses. The MappedSuperclass 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. Mapping 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.
JSR-317 Public Review Draft

49

10/31/08

Sun Microsystems, Inc.


Entities Java Persistence 2.0, Public Review Draft Inheritance

Example: Concrete class as a mapped superclass @MappedSuperclass public class Employee { @Id protected Integer empId; @Version protected Integer version; @ManyToOne @JoinColumn(name="ADDR") protected Address address; public public public public } // Default table is FTEMPLOYEE table @Entity public class FTEmployee extends Employee { // Inherited empId field mapped to FTEMPLOYEE.EMPID // Inherited version field mapped to FTEMPLOYEE.VERSION // Inherited address field mapped to FTEMPLOYEE.ADDR fk // Defaults to FTEMPLOYEE.SALARY protected Integer salary; public FTEmployee() {} public Integer getSalary() { ... } public void setSalary(Integer salary) { ... } } @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() {} public Float getHourlyWage() { ... } public void setHourlyWage(Float wage) { ... } } Integer getEmpId() { ... } void setEmpId(Integer id) { ... } Address getAddress() { ... } void setAddress(Address addr) { ... }

10/31/08

50

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Inheritance Java Persistence 2.0, Public Review Draft Entities

2.11.3 Non-Entity Classes in the Entity Inheritance Hierarchy


An entity can have a non-entity superclass, which may be either a concrete or abstract class.[21] 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[22]. Any annotations on such superclasses are ignored. Non-entity classes cannot be passed as arguments to methods of the EntityManager or Query interfaces[23] and cannot bear mapping information. The following example illustrates the use of a non-entity class as a superclass of an entity. Open Issue: Should we allow passing non-entity subclasses of entity classes to methods of the EntityManager interface. Example: Non-entity superclass public class Cart { Integer operationCount; // transient state public Cart() { operationCount = 0; } public Integer getOperationCount() { return operationCount; } public void incrementOperationCount() { operationCount++; } } @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(); } }

[21] The superclass may not be an embeddable class or id class. [22] If a transaction-scoped persistence context is used, it is not required to be retained across transactions. [23] This includes instances of a non-entity class that extends an entity class.

JSR-317 Public Review Draft

51

10/31/08

Sun Microsystems, Inc.


Entities Java Persistence 2.0, Public Review Draft Inheritance Mapping Strategies

2.12 Inheritance Mapping Strategies


The mapping of class hierarchies is specified through metadata. There are three basic strategies that are used when mapping a class or class hierarchy to a relational database:

a single table per class hierarchy a table per concrete entity class 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 strategy 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 whether support for this strategy should be required. Support for the combination of inheritance strategies within a single entity inheritance hierarchy is not required by this specification.

2.12.1 Single Table per Class Hierarchy Strategy


In this strategy, all the classes in a hierarchy are mapped to a single table. The table has a column that serves as a discriminator column, that is, a column whose value identifies the specific subclass to which the instance that is represented by the row belongs. 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.

2.12.2 Table per Concrete Class Strategy


In this mapping strategy, each class is mapped to a separate table. All properties of the class, including inherited properties, are mapped to columns of the table for the class. This strategy has the following drawbacks:

It provides poor support for polymorphic relationships. 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.

10/31/08

52

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Naming of Database Objects Java Persistence 2.0, Public Review Draft Entities

2.12.3 Joined Subclass Strategy


In the joined subclass strategy, the root of the class hierarchy is represented by a single table. Each subclass is represented by a separate table that contains those fields that are specific to the subclass (not inherited from its superclass), as well as the column(s) that represent its primary key. The primary key column(s) of the subclass table serves as a foreign key to the primary key of the superclass table. This strategy provides support for polymorphic relationships between entities. 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.

2.13 Naming of Database Objects


Many annotations and annotation elements contain names of database objects or assume default names for database objects. This specification assumes the following with regard to the interpretation of the names of database objects. These names include the names of tables, columns, and other database elements. Such names also include names that result from defaulting (e.g., a table name that is defaulted from an entity name). By default, the names of database objects are to be interpreted as undelimited identifiers. It is possible to specify that all database identifiers in use for a persistence unit be treated as delimited identifiers by specifying the <delimited-identifiers/> element within the persistence-unit element of the persistence.xml file. If the <delimited-identifiers/> element is specified, it cannot be overridden. Open Issue: Should this be in persistence-unit of the persistence.xml file or in the persistence-unit-defaults of the orm.xml file? Alternatively, it is possible to specify on a per-name basis that a name for a database object is to be interpreted as a delimited identifier. Using annotations, a name is specified as a delimited identifier by enclosing the name within double quotes, whereby the inner quotes are escaped, e.g., "\"like this\"". Open Issue: Alternative escape characters. The following annotations contain elements whose values correspond to names of database identifiers and which may be specified in this way, including when their use is nested within that of other annotations: EntityResult (discriminatorColumn element) FieldResult (column element) ColumnResult (name element)

JSR-317 Public Review Draft

53

10/31/08

Sun Microsystems, Inc.


Entities Java Persistence 2.0, Public Review Draft Naming of Database Objects

CollectionTable (name, catalog, schema elements) Column (name, columnDefinition, table elements) DiscriminatorColumn (name, columnDefinition elements) JoinColumn (name, referencedColumnName, columnDefinition, table elements) JoinTable (name, catalog, schema elements) MapKeyColumn (name, columnDefinition, table elements) MapKeyJoinColumn (name, referencedColumnName, columnDefinition elements) OrderColumn (name, columnDefinition, table elements) PrimaryKeyJoinColumn (name, referencedColumnName, columnDefinition elements) SecondaryTable (name, catalog, schema elements) SequenceGenerator (sequenceName, catalog, schema elements) Table (name, catalog, schema elements) TableGenerator (table, catalog, schema, pkColumnName, valueColumnName elements) UniqueConstraint (columnNames element) [Note: We will need to specify similarly for XML OR mapping descriptors.] Open Issue: What happens when <delimited-identifiers> is specified and individual annotations use escaped double quotes. Do the double-quotes appear in the name of the database identifier or not? Open Issue: Do we also need to add annotation elements to specify use of delimited identifiers or is the escaped double quotes mechanism enough?

10/31/08

54

JSR-317 Public Review Draft

Sun Microsystems, Inc.


EntityManager Java Persistence 2.0, Public Review Draft Entity Operations

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
An EntityManager instance is associated with a persistence context. A persistence context is a set of 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. The EntityManager interface defines the methods that are used to interact with the persistence context. The EntityManager API is used to create and remove persistent entity instances, to find persistent entities by primary key, and to query over persistent entities. 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.

JSR-317 Public Review Draft

55

10/31/08

Sun Microsystems, Inc.


Entity Operations Java Persistence 2.0, Public Review Draft EntityManager

Section 3.1 defines the EntityManager interface. The entity instance lifecycle is described in Section 3.2. The relationships between entity managers and persistence contexts are described in section 3.3 and in further detail in Chapter 6. Section 3.5 describes entity listeners and lifecycle callback methods for entities. The Query interface is described in section 3.6. The definition of persistence units is described in chapter 7.

10/31/08

56

JSR-317 Public Review Draft

Sun Microsystems, Inc.


EntityManager Java Persistence 2.0, Public Review Draft Entity Operations

3.1.1 EntityManager Interface


package javax.persistence; /** * Interface used to interact with the persistence context. */ public interface EntityManager { /** * 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);

JSR-317 Public Review Draft

57

10/31/08

Sun Microsystems, Inc.


Entity Operations Java Persistence 2.0, Public Review Draft EntityManager

/** * Find by primary key. * Search for an entity of the specified class and primary key. * If the entity instance is contained in the persistence context * it is returned from there. * @param entityClass * @param primaryKey * @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 * is not a valid type for that entitys primary key or * is null */ public <T> T find(Class<T> entityClass, Object primaryKey); /** * 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, and the effect of this method is * the same as if the lock method had been called on the entity. * 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);

10/31/08

58

JSR-317 Public Review Draft

Sun Microsystems, Inc.


EntityManager Java Persistence 2.0, Public Review Draft Entity Operations

/** * Find by primary key and lock, using specified properties. * 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 * 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 * 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 entityClass * @param primaryKey * @param lockMode * @param properties standard and vendor-specific properties * and hints * @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, Map<String, Object> properties); /** * 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.

JSR-317 Public Review Draft

59

10/31/08

Sun Microsystems, Inc.


Entity Operations Java Persistence 2.0, Public Review Draft EntityManager

* @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 entitys 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

10/31/08

60

JSR-317 Public Review Draft

Sun Microsystems, Inc.


EntityManager Java Persistence 2.0, Public Review Draft Entity Operations

* @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 void lock(Object entity, LockModeType lockMode); /** * Lock an entity instance that is contained in the persistence * context with the specified lock mode type and with specified * properties. * 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 * 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 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 */ public void lock(Object entity, LockModeType lockMode, Map<String, Object> properties); /** * Refresh the state of the instance from the database, * overwriting changes made to the entity, if any. * @param entity * @throws IllegalArgumentException if the instance is not

JSR-317 Public Review Draft

61

10/31/08

Sun Microsystems, Inc.


Entity Operations Java Persistence 2.0, Public Review Draft EntityManager

* an entity or the entity is not managed * @throws TransactionRequiredException if invoked on a * container-managed entity manager of type * PersistenceContextType.TRANSACTION and there is * no transaction. * @throws EntityNotFoundException if the entity no longer * exists in the database */ public void refresh(Object entity); /** * 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 and with * specified properties. * 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

10/31/08

62

JSR-317 Public Review Draft

Sun Microsystems, Inc.


EntityManager Java Persistence 2.0, Public Review Draft Entity Operations

* @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<String, Object> 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);

JSR-317 Public Review Draft

63

10/31/08

Sun Microsystems, Inc.


Entity Operations Java Persistence 2.0, Public Review Draft EntityManager

/** * Get * for * not */ public

the properties and associated values that are in effect the entity manager. Changing the contents of the map does change the configuration in effect. Map<String, Object> 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 the query string is found * to be invalid */ public Query createQuery(String qlString); /** * Create an instance of Query for executing a * criteria query. * @param qdef a Criteria API query definition object * @return the new query instance * @throws IllegalArgumentException if the query definition is * found to be invalid */ public Query createQuery(QueryDefinition qdef); /** * 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 or if the query string is * found to be invalid */ public Query createNamedQuery(String name);

10/31/08

64

JSR-317 Public Review Draft

Sun Microsystems, Inc.


EntityManager Java Persistence 2.0, Public Review Draft Entity Operations

/** * 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 an object of the specified type to allow access to the * provider-specific API. If the provider's EntityManager * implementation does not support the specified class, the * PersistenceException is thrown. * @param cls the class of the object to be returned. This is * normally either the underlying EntityManager implementation * class or an interface that it implements. * @return an instance of the specified class * @throws PersistenceException if the provider does not * support the call. */ public <T> T unwrap(Class<T> cls);

JSR-317 Public Review Draft

65

10/31/08

Sun Microsystems, Inc.


Entity Operations Java Persistence 2.0, Public Review Draft EntityManager

/** * Return the underlying provider object for the EntityManager, * if available. The result of this method is implementation * specific. The unwrap method is to be preferred for new * applications. * / 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 getProperties, getSupportedProperties, 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(); /** * Return an instance of QueryBuilder for the creation of * Criteria API QueryDefinition objects. * @return QueryBuilder instance * @throws IllegalStateException if the entity manager has * been closed. */ public QueryBuilder getQueryBuilder(); }

10/31/08

66

JSR-317 Public Review Draft

Sun Microsystems, Inc.


EntityManager Java Persistence 2.0, Public Review Draft Entity Operations

The persist, merge, remove, and refresh methods must be invoked within a transaction context when an entity manager with a transaction-scoped persistence context is used. If there is no transaction context, the javax.persistence.TransactionRequiredException is thrown. The find method (if invoked without a lock or with LockModeType.NONE) and the getReference 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 manager with an extended persistence context is used, they will be managed. See section 3.3 for entity manager 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 or a valid criteria query QueryDefinition object, the IllegalArgumentException 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 LockTimeoutException 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 6.2.2, Obtaining an Application-managed Entity Manager.

3.1.2 Example of Use of EntityManager API


@Stateless public class OrderEntryBean implements OrderEntry { @PersistenceContext EntityManager em; public void enterOrder(int custID, Order newOrder) { Customer cust = em.find(Customer.class, custID); cust.getOrders().add(newOrder); newOrder.setCustomer(cust); em.persist(newOrder); } }

JSR-317 Public Review Draft

67

10/31/08

Sun Microsystems, Inc.


Entity Operations Java Persistence 2.0, Public Review Draft Entity Instances Life Cycle

3.2 Entity Instances Life Cycle


This section describes the EntityManager operations for managing an entity instances 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 persistence 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 cascade functionality is most typically used in parent-child relationships.

3.2.1 Entity Instance Creation


Entity instances are created by means of the new operation. An entity instance, when first created by new is not yet persistent. An instance becomes persistent by means of the EntityManager API.

3.2.2 Persisting an Entity Instance


A new entity instance becomes both managed and persistent by invoking the persist method on it or by cascading the persist operation. The semantics of the persist operation, applied to an entity X are as follows:

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.

If X is a removed entity, it becomes managed. If X is a detached object, 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.

10/31/08

68

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Entity Instances Life Cycle Java Persistence 2.0, Public Review Draft Entity Operations

For all entities Y referenced by a relationship from X, if the relationship to Y has been annotated 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. The semantics of the remove operation, applied to an entity X are as follows:

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 annotated 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 operation 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.

If X is a detached entity, an IllegalArgumentException will be thrown by the remove


operation (or the transaction commit will fail).

If X is a removed entity, it is ignored by the remove operation. 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.

3.2.4 Synchronization to the Database


The state of persistent entities is synchronized to the database at transaction commit. This synchronization involving writing to the database any updates to persistent entities and their relationships as specified 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 developers 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 developers responsibility to insure that the semantics of the relationships are adhered to.[24]

JSR-317 Public Review Draft

69

10/31/08

Sun Microsystems, Inc.


Entity Operations Java Persistence 2.0, Public Review Draft Entity Instances Life Cycle

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 synchronization. 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 perform to flush at other times. If there is no transaction active, the persistence provider must not flush to the database. The semantics of the flush operation, applied to an entity X are as follows:

If X is a managed entity, it is synchronized to the database. For all entities Y referenced by a relationship from X, if the relationship to Y has been
annotated with the cascade element value cascade=PERSIST or cascade=ALL, the persist operation is applied to Y.

For any entity Y referenced by a relationship from X, where the relationship to Y has
not been annotated with the cascade element value cascade=PERSIST or cascade=ALL:

If Y is new or removed, an IllegalStateException will be thrown


by the flush operation (and the transaction marked for rollback) or the transaction commit will fail.

If Y is detached, the semantics depend upon the ownership of the relationship. If X owns the relationship, any changes to the relationship are synchronized 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.

3.2.5 Refreshing an Entity Instance


The state of a managed entity instance is refreshed from the database by invoking the refresh method on it or by cascading the refresh operation. The semantics of the refresh operation, applied to an entity X are as follows:

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.

If X is a new, detached, or removed entity, the IllegalArgumentException is thrown.


[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.

10/31/08

70

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Entity Instances Life Cycle Java Persistence 2.0, Public Review Draft Entity Operations

3.2.6 Evicting an Entity Instance from the Persistence Context


A entity instance is removed from the persistence context by invoking the clear method on it or cascading the clear operation. Changes made to the entity, if any (including removal of the entity), will not be synchronized to the database after such eviction has taken place. 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 provider 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. The semantics of the clear operation, applied to an entity X are as follows:

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 new or detached entity, it is ignored by the clear operation. If X is a removed entity, 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. 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.

3.2.7 Detached Entities


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 persistence context; from closing an entity manager; and from serializing an entity or otherwise passing an entity by valuee.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 persisted 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 persistence context ends. The available state includes:

Any persistent field or property not marked fetch=LAZY Any persistent field or property that was accessed by the application

JSR-317 Public Review Draft

71

10/31/08

Sun Microsystems, Inc.


Entity Operations Java Persistence 2.0, Public Review Draft Entity Instances Life Cycle

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 instance retrieved using find(). 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 associations marked fetch=EAGER.

3.2.7.1 Merging Detached Entity State


The merge operation allows for the propagation of state from detached entities onto persistent entities managed by the EntityManager. The semantics of the merge operation applied to an entity X are as follows:

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 removed entity instance, an IllegalArgumentException will be thrown by the


merge operation (or the transaction commit will fail).

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 annotated with the cascade element value cascade=MERGE or cascade=ALL annotation.

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 referenced by X, X' is set to reference Y'. (Note that if X is managed then X is the same object as X'.)

If X is an entity merged to X', with a reference to another entity Y, where cascade=MERGE


or cascade=ALL is not specified, then navigation of the same association from X' yields a reference to a managed object Y' with the same persistent identity as Y. 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.

10/31/08

72

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Entity Instances Life Cycle Java Persistence 2.0, Public Review Draft Entity Operations

3.2.7.2 Detached Entities and Lazy Loading


Serializing entities and merging those entities back into a persistence context may not be interoperable across vendors when lazy properties or fields and/or relationships are used. 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.

3.2.8 Managed Instances


It is the responsibility of the application to insure that an instance is managed in only a single persistence context. The behavior is undefined if the same Java instance is made managed in more than one persistence context. The contains() method can be used to determine whether an entity instance is managed in the current persistence context. The contains method returns true:

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 persist operation has been cascaded to it. The contains method returns false:

If the instance is detached. If the remove method has been called on the entity, or the remove operation has been cascaded 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 representation for the entity may be deferred until the end of the transaction.

JSR-317 Public Review Draft

73

10/31/08

Sun Microsystems, Inc.


Entity Operations Java Persistence 2.0, Public Review Draft Persistence Context Lifetime

3.3 Persistence Context Lifetime


The lifetime of a container-managed persistence context may either be scoped to a transaction (transaction-scoped persistence context), or have a lifetime scope that extends beyond that of a single transaction (extended persistence context). The enum PersistenceContextType is used to define the persistence context lifetime scope for container-managed entity managers. The persistence context lifetime scope is defined when the EntityManager instance is created (whether explicitly, or in conjunction with injection or JNDI lookup). See Section 6.6. public enum PersistenceContextType { TRANSACTION, EXTENDED } By default, the lifetime of the persistence context of a container-managed entity manager corresponds to the scope of a transaction (i.e., it is of type PersistenceContextType.TRANSACTION). 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 transactions and non-transactional invocations of the EntityManager. A container-managed extended persistence 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 transaction 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 operations will be committed to the database when the extended persistence context is enlisted in a transaction and the transaction commits. 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 6.6. Persistence contexts managed by the application are described futher in section 6.7.

3.3.1 Transaction Commit


The managed entities of a transaction-scoped persistence context become detached when the transaction commits; the managed entities of an extended persistence context remain managed.

[25] Note that when a new transaction is begun, the managed objects in an extended persistence context are not reloaded from the database.

10/31/08

74

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Locking and Concurrency Java Persistence 2.0, Public Review Draft Entity Operations

3.3.2 Transaction Rollback


For both transaction-scoped and extended persistence contexts, transaction rollback causes all pre-existing managed instances and removed instances[26] to become detached. The instances state will be the state of the instances at the point at which the transaction was rolled back. Transaction rollback typically causes the persistence context to be in an inconsistent state at the point of rollback. In particular, the state of version attributes and generated state (e.g., generated primary keys) may be inconsistent. Instances that were formerly managed by the persistence context (including new instances that were made persistent in that transaction) may therefore not be reusable in the same manner as other detached objectsfor example, they may fail when passed to the merge operation.[27]

3.4 Locking and Concurrency


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 isolation (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 invokedwhether 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 immediately (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 specification. [28] In addition, both pessimistic and optimistic locking are supported for selected entities by means of specified 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.

3.4.1 Optimistic Locking


Optimistic locking is a technique that is used to insure that updates to the database data corresponding to the state of an entity are made only when no intervening transaction has updated that data for the entity state since the entity state was read. This insures that updates or deletes to that data are consistent with the current state of the database and that intervening updates are not lost. Transactions that would cause this constraint to be violated result in an OptimisticLockException being thrown and the transaction marked for rollback.

[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 specification.

JSR-317 Public Review Draft

75

10/31/08

Sun Microsystems, Inc.


Entity Operations Java Persistence 2.0, Public Review Draft Locking and Concurrency

Portable applications that wish to enable optimistic locking for entities must specify Version attributes for those entitiesi.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.

3.4.2 Version Attributes


The Version field or property is used by the persistence provider to perform optimistic locking. It is accessed and/or set by the persistence provider in the course of performing lifecycle operations on the entity instance. An entity is automatically enabled for optimistic locking if it has a property or field mapped with a Version mapping. An entity may access the state of its version field or property or export a method for use by the application 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 entityi.e. that the entity has been updated since the entity became detached. Depending on the implementation strategy used, it is possible that this exception 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 optimistic 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] 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.

3.4.3 Pessimistic Locking


While optimistic locking is typically appropriate in dealing with moderate contention among concurrent transactions, in some applications it may be useful to immediately obtain database locks for selected entities because of the often late failure of optimistic transactions. Such immediately obtained database locks are referred to here as pessimistic locks.

[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.

10/31/08

76

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Locking and Concurrency Java Persistence 2.0, Public Review Draft Entity Operations

Pessimistic locking guarantees that once a transaction has obtained a pessimistic lock on an entity instance:

that same transaction may modify or delete that 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 interaction 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.

3.4.4 Lock Modes


In addition to the semantics described above, lock modes may be further specified by means of the EntityManager lock method, the methods of the EntityManager and Query interfaces that allow lock modes to be specified, and the NamedQuery annotation. 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). Five lock mode types are defined: OPTIMISTIC, OPTIMISTIC_FORCE_INCREMENT, PESSIMISTIC, PESSIMISTIC_FORCE_INCREMENT, NONE. The lock mode type values READ and WRITE are synonyms of OPTIMISTIC and OPTIMISTIC_FORCE_INCREMENT respectively.[32] The latter are to be preferred for new applications. public enum LockModeType { READ, WRITE, OPTIMISTIC, OPTIMISTIC_FORCE_INCREMENT, PESSIMISTIC, PESSIMISTIC_FORCE_INCREMENT, NONE }
[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. [32] The lock mode type NONE may be specified as a value of lock mode arguments and also provides a default value for annotations.

JSR-317 Public Review Draft

77

10/31/08

Sun Microsystems, Inc.


Entity Operations Java Persistence 2.0, Public Review Draft Locking and Concurrency

Open Issue: Names of the lock modes are still under discussion and subject to change.

3.4.4.1 OPTIMISTIC, OPTIMISTIC_FORCE_INCREMENT


Lock modes OPTIMISTIC and OPTIMISTIC_FORCE_INCREMENT are used for optimistic locking. The semantics of requesting locks of type LockModeType.OPTIMISTIC and LockModeType.OPTIMISTIC_FORCE_INCREMENT are the following. If transaction T1 calls lock(entity, LockModeType.OPTIMISTIC) on a versioned object, the entity manager must ensure that neither of the following phenomena can occur:

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.

P2 (Non-repeatable read): Transaction T1 reads a row. Another transaction T2 then modifies or


deletes that row, before T1 has committed. Both transactions eventually commit successfully. This will generally be achieved by the entity manager acquiring a lock on the underlying database row. Any such lock may be obtained immediately (so long as it is retained until commit completes), or the lock may be deferred until commit time (although even then it must be retained until the commit completes). Any implementation that supports repeatable reads in a way that prevents the above phenomena is permissible. The persistence implementation is not required to support calling lock(entity, LockModeType.OPTIMISTIC) on a non-versioned object. When it cannot support such a lock call, it must throw the PersistenceException. When supported, whether for versioned or non-versioned objects, LockModeType.OPTIMISTIC must always prevent the phenomena P1 and P2. Applications that call lock(entity, LockModeType.OPTIMISTIC) on non-versioned objects will not be portable. If transaction T1 calls lock(entity, LockModeType.OPTIMISTIC_FORCE_INCREMENT) on a versioned object, the entity manager must avoid the phenomena P1 and P2 (as with LockModeType.OPTIMISTIC) and must also force an update (increment) to the entity's version column. A forced version update may be performed immediately, or may be deferred until a flush or commit. If an entity is removed before a deferred version update was to have been applied, the forced version update is omitted. The persistence implementation is not required to support calling lock(entity, LockModeType.OPTIMISTIC_FORCE_INCREMENT) on a non-versioned object. When it cannot support such a lock call, it must throw the PersistenceException. When supported, whether for versioned or non-versioned objects, LockModeType.OPTIMISTIC_FORCE_INCREMENT must always prevent the phenomena P1 and P2. For non-versioned objects, whether or not LockModeType.OPTIMISTIC_FORCE_INCREMENT has any additional behavior is vendor-specific. Applications that call lock(entity, LockModeType.OPTIMISTIC_FORCE_INCREMENT) on non-versioned objects will not be portable.

10/31/08

78

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Locking and Concurrency Java Persistence 2.0, Public Review Draft Entity Operations

For versioned objects, it is permissible for an implementation to use LockModeType.OPTIMISTIC_FORCE_INCREMENT where LockModeType.OPTIMISTIC was requested, but not vice versa. 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 version attributes and the EntityManager lock method. However, it should be noted that if an implementation 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.

3.4.4.2 PESSIMISTIC, PESSIMISTIC_FORCE_INCREMENT


Lock modes PESSIMISTIC and PESSIMISTIC_FORCE_INCREMENT are used to obtain database locks pessimistically. The semantics of requesting locks of type LockModeType.PESSIMISTIC and LockModeType.PESSIMISTIC_FORCE_INCREMENT are the following. If transaction T1 calls lock(entity, LockModeType.PESSIMISTIC) on an object, the entity manager must ensure that neither of the following phenomena can occur:

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.

P2 (Non-repeatable read): Transaction T1 reads a row. Another transaction T2 then modifies or


deletes that row, 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. The persistence implementation must support calling lock(entity, LockModeType.PESSIMISTIC) on a non-versioned entity as well as on a versioned entity. 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 rollback, the provider must throw the LockTimeoutException (and not mark the transaction for rollback).

JSR-317 Public Review Draft

79

10/31/08

Sun Microsystems, Inc.


Entity Operations Java Persistence 2.0, Public Review Draft Locking and Concurrency

When lock(entity, LockModeType.PESSIMISTIC) is invoked on a versioned entity that is already in the persistence context, the provider must also perform optimistic version checks when obtaining the lock. An OptimisticLockException must be thrown if the version checks fail. Depending on the implementation strategy used by the provider, it is possible that this exception may not be thrown until flush is called or commit time, whichever occurs first. If transaction T1 calls lock(entity, LockModeType.PESSIMISTIC_FORCE_INCREMENT) on a versioned object, the entity manager must avoid the phenomenon P1 and P2 (as with LockModeType.PESSIMISTIC) and must also force an update (increment) to the entity's version column. The persistence implementation is not required to support calling lock(entity, LockModeType.PESSIMISTIC_FORCE_INCREMENT) on a non-versioned object. When it cannot support such a lock call, it must throw the PersistenceException. When supported, whether for versioned or non-versioned objects, LockModeType.PESSIMISTIC_FORCE_INCREMENT must always prevent the phenomena P1 and P2. For non-versioned objects, whether or not LockModeType.PESSIMISTIC_FORCE_INCREMENT has any additional behavior is vendor-specific. Applications that call lock(entity, LockModeType.PESSIMISTIC_FORCE_INCREMENT) on non-versioned objects will not be portable. Open Issue: What happens when the application calls lock(entity.LockModeType.PESSIMISTIC_FORCE_INCREMENT) on a non-versioned object. For versioned objects, it is permissible Type.PESSIMISTIC_FORCE_INCREMENT requested, but not vice versa. for an implementation to use LockModewhere LockModeType.PESSIMISTIC was

If a versioned object locked with LockModeType.PESSIMISTIC is updated, then the implementation must ensure that the requirements of LockModeType.PESSIMISTIC_FORCE_INCREMENT are met.

3.4.4.3 Lock Mode Hints


The following hint is defined by this specification for use in pessimistic locking. javax.persistence.lock.timeout // time in seconds Open Issue: Whether units should be seconds or milliseconds 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, 7.2.1.7, 8.2.1, and 9.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 selectively overridden by use in the methods of the EntityManager and Query interfaces as specified above. A timeout value of 0 is used to specify no wait locking. Open Issue: Need to define overriding precedences here.

10/31/08

80

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Entity Listeners and Callback Methods Java Persistence 2.0, Public Review Draft Entity Operations

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 consistent 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 application, 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. In some cases an OptimisticLockException will be thrown and wrapped by another exception, such as a RemoteException, when VM boundaries are crossed. Entities that may be referenced in wrapped exceptions should implement Serializable so that marshalling will not fail. An OptimisticLockException always causes the transaction to be marked for rollback. Refreshing objects or reloading objects in a new transaction context and then retrying the transaction is a potential response to an OptimisticLockException.

3.5 Entity Listeners and Callback Methods


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 listenersentity listeners that apply to all entities in the persistence unitcan be specified by means of the XML descriptor.

JSR-317 Public Review Draft

81

10/31/08

Sun Microsystems, Inc.


Entity Operations Java Persistence 2.0, Public Review Draft Entity Listeners and Callback Methods

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 listeners are defined, the order in which they are invoked is determined by the order in which they are specified 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 lifecycle 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. The entity listener class must have a public no-arg constructor. Entity listeners are stateless. The lifecycle of an entity listener is unspecified. The following rules apply to lifecycle callbacks:

Lifecycle callback methods may throw unchecked/runtime exceptions. A runtime exception


thrown by a callback method that executes within a transaction causes that transaction to be marked for rollback.

Lifecycle callbacks can invoke JNDI, JDBC, JMS, and enterprise beans. In general, the lifecycle method of a portable application should not invoke EntityManager or Query operations, access other entity instances, or modify relationships within the same persistence context.[33] A lifecycle callback method may modify the non-relationship state of the entity on which it is invoked. When invoked from within a Java EE environment, the callback listeners for an entity share the enterprise 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]

3.5.1 Lifecycle Callback Methods


Entity lifecycle callback methods can be defined on an entity listener class and/or directly on an entity class or mapped superclass. 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.

[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 transaction attribute RequiresNew, the PostPersist and PostRemove callbacks are executed in the naming context, the transaction context, and the security context of that component.

10/31/08

82

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Entity Listeners and Callback Methods Java Persistence 2.0, Public Review Draft Entity Operations

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 corresponding types.

PrePersist PostPersist PreRemove PostRemove PreUpdate PostUpdate PostLoad

3.5.2 Semantics of the Life Cycle Callback Methods for Entities


The PrePersist and PreRemove callback methods are invoked for a given entity before the respective EntityManager persist and remove operations for that entity are executed. For entities to which the merge operation has been applied and causes the creation of newly managed instances, the PrePersist callback methods will be invoked for the managed instance after the entity state has been copied to it. These PrePersist and PreRemove callbacks will also be invoked on all entities to which these operations are cascaded. The PrePersist and PreRemove methods will always be invoked as part of the synchronous persist, merge, and remove operations.

JSR-317 Public Review Draft

83

10/31/08

Sun Microsystems, Inc.


Entity Operations Java Persistence 2.0, Public Review Draft Entity Listeners and Callback Methods

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). Note that it is implementation-dependent as to whether PreUpdate and PostUpdate callbacks occur when an entity is persisted and subsequently modified in a single transaction or when an entity is modified and subsequently removed within a single transaction. Portable applications should not rely on such behavior. The PostLoad method for an entity is invoked after the entity has been loaded into the current persistence 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 cascading of the lifecycle events to related entities. Applications should not depend on this ordering.

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() { ... } ... public void deposit(Integer amount) { ... } public Integer withdraw(Integer amount) throws NSFException {... } @PrePersist protected void validateCreate() { if (getBalance() < MIN_REQUIRED_BALANCE) throw new AccountException("Insufficient balance to open an account"); }

10/31/08

84

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Entity Listeners and Callback Methods Java Persistence 2.0, Public Review Draft Entity Operations

@PostLoad protected void adjustPreferredStatus() { preferred = (getBalance() >= AccountManager.getPreferredStatusLevel()); } } public class AlertMonitor { @PostPersist public void newAccountAlert(Account acct) { Alerts.sendMarketingInfo(acct.getAccountId(), acct.getBalance()); } }

3.5.4 Multiple Lifecycle Callback Methods for an Entity Lifecycle Event


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 ExcludeDefaultListeners annotation or exclude-default-listeners XML element. The lifecycle callback methods defined on the entity listener classes for an entity class or mapped superclass are invoked in the same order as the specification of the entity listener classes in the EntityListeners annotation. If multiple classes in an inheritance hierarchyentity classes and/or mapped superclassesdefine entity listeners, the listeners defined for a superclass are invoked before the listeners defined for its subclasses in this order. The ExcludeSuperclassListeners annotation or exclude-superclass-listeners XML element may be applied to an entity class or mapped superclass to exclude the invocation of the listeners defined by the entity listener classes for the superclasses of the entity or mapped superclass. The excluded listeners are excluded from the class to which the ExcludeSuperclassListeners annotation or element has been specified and its subclasses.[35] The ExcludeSuperclassListeners annotation (or exclude-superclass-listeners XML element) does not cause default entity listeners to be excluded from invocation. 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 superclasses 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 overridden method is not invoked.[36]

[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.

JSR-317 Public Review Draft

85

10/31/08

Sun Microsystems, Inc.


Entity Operations Java Persistence 2.0, Public Review Draft Entity Listeners and Callback Methods

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.

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 { .... } public class PetListener { @PostPersist protected void postPersistPetListenerMethod(Object pet) { .... } } public class CatListener { @PostPersist protected void postPersistCatListenerMethod(Object cat) { .... } } public class CatListener2 { @PostPersist protected void postPersistCatListener2Method(Object cat) { .... } }

10/31/08

86

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Entity Listeners and Callback Methods Java Persistence 2.0, Public Review Draft Entity Operations

If a PostPersist event occurs on an instance of Cat, the following methods are called in order: postPersistPetListenerMethod postPersistCatListenerMethod postPersistCatListener2Method postPersistAnimal Assume that SiameseCat is defined as a subclass of Cat: @EntityListeners(SiameseCatListener.class) @Entity public class SiameseCat extends Cat { ... @PostPersist protected void postPersistSiameseCat() { ... } } public class SiameseCatListener { @PostPersist protected void postPersistSiameseCatListenerMethod(Object cat) { .... } } If a PostPersist event occurs on an instance of SiameseCat, the following methods are called in order: postPersistPetListenerMethod postPersistCatListenerMethod postPersistCatListener2Method postPersistSiameseCatListenerMethod postPersistAnimal postPersistSiameseCat Assume the definition of SiameseCat were instead: @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
JSR-317 Public Review Draft

87

10/31/08

Sun Microsystems, Inc.


Entity Operations Java Persistence 2.0, Public Review Draft Entity Listeners and Callback Methods

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.

3.5.7.1 Specification of Callback Listeners


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 annotations and XML descriptor elements is used.

3.5.7.2 Specification of the Binding of Entity Listener Classes to Entities


The entity-listeners subelement of the persistence-unit-defaults element is used to specify the default entity listeners for the persistence unit. The entity-listeners subelement of the entity or mapped-superclass element is used to specify the entity listener classes for the respective entity or mapped superclass and its subclasses. 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 superclasses 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.

10/31/08

88

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Query API Java Persistence 2.0, Public Review Draft Entity Operations

3.6 Query API


The Query API is used for both static queries (i.e., named queries) and dynamic queries defined using the Java Persistence query language or the Criteria API. The Query API also supports named parameter binding and pagination control.

3.6.1 Query Interface


package javax.persistence; import java.util.Calendar; import java.util.Date; import java.util.List; /** * Interface used to control query execution. */ public interface Query { /** * 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 the query 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 the query 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();

JSR-317 Public Review Draft

89

10/31/08

Sun Microsystems, Inc.


Entity Operations Java Persistence 2.0, Public Review Draft Query API

/** * 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 or for * a criteria query * @throws TransactionRequiredException if there is * no transaction * @throws QueryTimeoutException if the statement execution exceeds the query 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

10/31/08

90

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Query API Java Persistence 2.0, Public Review Draft Entity Operations

* @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<String, Object> 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);

JSR-317 Public Review Draft

91

10/31/08

Sun Microsystems, Inc.


Entity Operations Java Persistence 2.0, Public Review Draft Query API

/** * 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<String, Object> 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();

10/31/08

92

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Query API Java Persistence 2.0, Public Review Draft Entity Operations

/** * 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 or Criteria API 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 or Criteria API query */ public LockModeType getLockMode(); /** * Return an object of the specified type to allow access to the * provider-specific API. If the provider's Query implementation * does not support the specified class, the PersistenceException * is thrown. * @param cls the class of the object to be returned. This is * normally either the underlying Query implementation class * or an interface that it implements. * @return an instance of the specified class * @throws PersistenceException if the provider does not support * the call. */ public <T> T unwrap(Class<T> cls); } The elements of the result of a Java Persistence query language query or criteria query whose select list consists of more than one select expression are of type Object[]. If the select list 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.

JSR-317 Public Review Draft

93

10/31/08

Sun Microsystems, Inc.


Entity Operations Java Persistence 2.0, Public Review Draft Query API

An IllegalArgumentException is thrown if a parameter name is specified that does not correspond to a named parameter in the query string, if a positional value is specified that does not correspond to a positional parameter in the query string, or if the type of the parameter is not valid for the query. This exception may be thrown when the parameter is bound, or the execution of the query may fail. 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 transaction context, unless a lock mode has been specified for the query. In particular, the getResultList 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 transaction-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. Runtime exceptions other than the NoResultException, NonUniqueResultException, QueryTimeoutException, and LockTimeoutException thrown by the methods of the Query interface cause the current transaction to be marked for rollback. On database platforms on which a query timeout causes transaction rollback, the persistence provider must throw the PersistenceException instead of the QueryTimeoutException.

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

3.6.2 Queries and Flush Mode


The flush mode setting affects the result of a query as follows. 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 FlushModeType.COMMIT is set, the effect of updates made to entities in the persistence context upon queries is unspecified.

[37] A lock mode is specified for a query by means of the setLockMode method or by specifying the lock mode in the NamedQuery annotation.

10/31/08

94

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Query API Java Persistence 2.0, Public Review Draft Entity Operations

public enum FlushModeType { COMMIT, AUTO } If there is no transaction active, the persistence provider must not flush to the database.

3.6.3 Queries and Lock Mode


The setLockMode method of the Query interface or the lockMode element of the NamedQuery annotation may be used to lock the results of a query. A lock is obtained for each entity specified in the query result (including entities passed to constructors in the query SELECT clause). Open Issue: What about related entities, including fetch-join entities? Should we introduce an option to cascade pessimistic locking? If the lock mode type is PESSIMISTIC or PESSIMISTIC_FORCE_INCREMENT, and the query returns scalar data (e.g., the values of entity field or properties, including scalar data passed to constructors in the query SELECT clause), the underlying database rows will be locked[38], but the version columns (if any) for any entities corresponding to such scalar data will not be updated unless the entities themselves are also otherwise retrieved and updated. 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. Locking is supported for Java Persistence query language queries and criteria queries only.

3.6.4 Query Hints


The following hint is defined by this specification for use in query configuration. javax.persistence.query.timeout // time in seconds Open Issue: Whether units should be seconds or milliseconds 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.createEntityManagerFactory method and used in the properties element of the persistence.xml file. See sections 3.6.1, 7.2.1.7, 8.2.1, 9.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.setHint 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.

[38] Note that locking will not occur for data passed to aggregate functions. Further, queries involving aggregates with pessimistic locking may not be supported on all database platforms.

JSR-317 Public Review Draft

95

10/31/08

Sun Microsystems, Inc.


Entity Operations Java Persistence 2.0, Public Review Draft Query API

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.6.5 Named Parameters


Named parameters follow the rules for identifiers defined in Section 4.4.1. The use of named parameters applies to the Java Persistence query language and to queries written using the Criteria API, and is not defined for native queries. Named parameters are case-sensitive. A named parameter of a Java Persistence query language query an identifier that is prefixed by the ":" symbol. Named parameters used in Criteria API query definitions do not use the ":" prefix. 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.

3.6.6 Named Queries


Named queries are static queries expressed in metadata. Named queries can be defined in the Java Persistence query language or in SQL. Query names are scoped to the persistence unit. The following is an example of the definition of a named query: @NamedQuery( name="findAllCustomersWithName", query="SELECT c FROM Customer c WHERE c.name LIKE :custName" ) The following is an example of the use of a named query: @PersistenceContext public EntityManager em; ... customers = em.createNamedQuery("findAllCustomersWithName") .setParameter("custName", "Smith") .getResultList();

3.6.7 Polymorphic Queries


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. For example, the following query returns the average salary of all employees, including subtypes of Employee, such as Manager and Exempt.

10/31/08

96

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Query API Java Persistence 2.0, Public Review Draft Entity Operations

select avg(e.salary) from Employee e where e.salary > 80000 Entity type expressions, described in section 4.4.9, can be used to restrict query polymorphism.

3.6.8 SQL Queries


Queries may be expressed in native SQL. The result of a native SQL query may consist of entities, scalar values, or a combination of the two. The entities returned by a query may be of different entity types. 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 language 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 9.3.3 for the definition of the SqlResultSetMapping metadata 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))

JSR-317 Public Review Draft

97

10/31/08

Sun Microsystems, Inc.


Entity Operations Java Persistence 2.0, Public Review Draft Query API

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 columns 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.

10/31/08

98

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Query API Java Persistence 2.0, Public Review Draft Entity Operations

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 composite 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 section 10.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) })

JSR-317 Public Review Draft

99

10/31/08

Sun Microsystems, Inc.


Entity Operations Java Persistence 2.0, Public Review Draft Summary of Exceptions

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), followed 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. Support for joins is currently limited to single-valued relationships.

3.7 Summary of Exceptions


The following is a summary of the exceptions defined by this specification: PersistenceException The PersistenceException is thrown by the persistence provider when a problem occurs. It may be thrown to report that the invoked operation could not complete because of an unexpected error (e.g., failure of the persistence provider to open a database connection). All other exceptions defined by this specification are subclasses of the PersistenceException. All instances of PersistenceException except for instances of NoRe10/31/08

100

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Summary of Exceptions Java Persistence 2.0, Public Review Draft Entity Operations

sultException, NonUniqueResultException, LockTimeoutException, and QueryTimeoutException will cause the current transaction, if one is active, to be marked for rollback. TransactionRequiredException The TransactionRequiredException is thrown by the persistence provider when a transaction is required but is not active. OptimisticLockException The OptimisticLockException is thrown by the persistence provider when an optimistic locking conflict occurs. This exception may be thrown as part of an API call, at flush, or at commit time. The current transaction, if one is active, will be marked for rollback. PessimisticLockException The PessimisticLockException is thrown by the persistence provider when a pessimistic locking conflict occurs. The current transaction will be marked for rollback. Typically the PessimisticLockException occurs because the database transaction has been rolled back due to deadlock or because the database uses transaction-level rollback when a pessimistic lock cannot be granted. LockTimeoutException The LockTimeoutException is thrown by the persistence provider when a pessimistic locking conflict occurs that does not result in transaction rollback. Typically this occurs 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 transaction to be marked for rollback. RollbackException The RollbackException is thrown by the persistence provider when EntityTransaction.commit fails. EntityExistsException The EntityExistsException may thrown by the persistence provider when the persist 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 The EntityNotFoundException is thrown by the persistence provider when an entity reference obtained by getReference is accessed but the entity does not exist. It is also thrown by the refresh operation when the entity no longer exists in the database. The current transaction, if one is active, will be marked for rollback.

JSR-317 Public Review Draft

101

10/31/08

Sun Microsystems, Inc.


Entity Operations Java Persistence 2.0, Public Review Draft Summary of Exceptions

NoResultException The NoResultException is thrown by the persistence provider when Query.getSingleResult is invoked and there is no result to return. This exception will not cause the current transaction, if one is active, to be marked for rollback. NonUniqueResultException The NonUniqueResultException is thrown by the persistence provider when Query.getSingleResult is invoked and there is more than one result from the query. This exception will not cause the current transaction, if one is active, to be marked for rollback. QueryTimeoutException The QueryTimeoutException is thrown by the persistence provider when a query times out. The QueryTimeoutException does not cause the current transaction, if one is active, to be marked for rollback.

10/31/08

102

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Overview Java Persistence 2.0, Public Review Draft Query Language

C ha p t e r 4

Query Language

The Java Persistence query language is a string-based query language 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 schema in use in an enterprise environment. The full range of the language may be used in both static and dynamic queries. This chapter provides the full definition of the Java Persistence query language.

4.1 Overview
The Java Persistence query language is a query specification language for string-based dynamic queries and 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 facilities 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.

JSR-317 Public Review Draft

103

10/31/08

Sun Microsystems, Inc.


Query Language Java Persistence 2.0, Public Review Draft Statement Types

The query language uses the abstract persistence schema of entities, including their embedded objects and 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 abstract schema types and relationships. 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. 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.

4.2 Statement Types


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. In BNF syntax, a query language statement is defined as: QL_statement :: = select_statement | update_statement | delete_statement Open Issue: Should we support INSERT statements ? Any Java Persistence query language statement may be constructed dynamically or may be statically defined in a metadata annotation or XML descriptor element. All statement types may have parameters.

4.2.1 Select Statements


A select statement is a string which consists of the following clauses:

a SELECT clause, which determines the type of the objects or values to be selected. a FROM clause, which provides declarations that designate the domain to which the expressions specified in the other clauses of the query apply.

10/31/08

104

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Abstract Schema Types and Query Domains Java Persistence 2.0, Public Review Draft Query Language

an optional WHERE clause, which may be used to restrict the results that are returned by the
query.

an optional GROUP BY clause, which allows query results to be aggregated in terms of


groups.

an optional HAVING clause, which allows filtering over aggregated groups. an optional ORDER BY clause, which may be used to order the results that are returned by the
query. In BNF syntax, a select statement is defined as: select_statement :: = select_clause from_clause [where_clause] [groupby_clause] [having_clause] [orderby_clause] A select statement must always have a SELECT and a FROM clause. The square brackets [] indicate that the other clauses are optional.

4.2.2 Update and Delete Statements


Update and delete statements provide bulk operations over sets of entities. In BNF syntax, these operations are defined as: update_statement :: = update_clause [where_clause] delete_statement :: = delete_clause [where_clause] 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. Update and delete statements are described further in Section 4.10.

4.3 Abstract Schema Types and Query Domains


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 identification variable declarations, the types to which the persistent fields and relationships evaluate, and the types of literals. The abstract schema type of an entity or embeddable is derived from its class and the metadata information provided by Java language annotations or in the XML descriptor.

JSR-317 Public Review Draft

105

10/31/08

Sun Microsystems, Inc.


Query Language Java Persistence 2.0, Public Review Draft Abstract Schema Types and Query Domains

Informally, the abstract schema type of an entity or embeddable can be characterized as follows:

For every persistent field or get accessor method (for a persistent property) of the 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 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 and embeddables 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 and associated embeddable classes on which it is based. The association fields of an entitys or embeddables 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, and line items, and an embeddable address class representing shipping addresses and billing addresses. The abstract schema types for the entities are Order, Product, and LineItem respectively. There is a one-to-many relationship between Order and Lineitem. The entity LineItem is related to Product in a many-to-one relationship. The classes are logically in the same persistence unit, as shown in Figure 1. 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 follows: SELECT DISTINCT o FROM Order AS o JOIN o.lineItems AS l WHERE l.shipped = FALSE

10/31/08

106

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Abstract Schema Types and Query Domains Java Persistence 2.0, Public Review Draft Query Language

Figure 1

Abstract Persistence Schema of Several Entities with Defined in the Same Persistence Unit.

Order
1

m LineItem m 1
Product

Shipping Address

Billing Address

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 reserved identifiers, such as DISTINCT, FROM, AS, JOIN, WHERE, and FALSE appear in upper case in this example, reserved identifiers are case insensitive.[39] 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 schema 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 entity name Order, which designates the abstract schema type over which the query ranges. The basis for the navigation is provided by the association fields lineItems and product of the abstract schema types Order and LineItem respectively.

[39] This chapter uses the convention that reserved identifiers appear in upper case in the examples and BNF for the language.

JSR-317 Public Review Draft

107

10/31/08

Sun Microsystems, Inc.


Query Language Java Persistence 2.0, Public Review Draft The FROM Clause and Navigational Declara-

4.4 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 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 ::= entity_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_path_expression join_collection_valued_path_expression::= identification_variable.{single_valued_object_field.}*collection_valued_field join_single_valued_path_expression::= identification_variable.{single_valued_object_field.}*single_valued_object_field 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: ALL, AND, ANY, AS, ASC, AVG, BETWEEN, BIT_LENGTH, BY, CASE, CHAR_LENGTH, CHARACTER_LENGTH, CLASS, COALESCE, COUNT, CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP, DELETE, DESC, DISTINCT, EMPTY, ENTRY, EXISTS, FALSE, FETCH, FROM, GROUP, HAVING, IN, INDEX, INNER, IS, JOIN, KEY, LEFT, LIKE, LOWER, MAX, MEMBER, MIN, MOD, NEW, NOT, NULL, NULLIF, OBJECT, OF, OR, ORDER, OUTER, POSITION, SELECT, SOME, SUM, THEN, TRIM, TRUE, TYPE, UNKNOWN[40], UPDATE, UPPER, VALUE, WHEN, WHERE.

[40] Not currently used; reserved for future use.

10/31/08

108

JSR-317 Public Review Draft

Sun Microsystems, Inc.


The FROM Clause and Navigational DeclarationsJava Persistence 2.0, Public Review Draft Query Language

Reserved identifiers are case insensitive. Reserved identifiers must not be used as identification variables. It is recommended that other SQL key words not be used as identification variables in queries because they may be used as reserved identifiers in future releases of this specification. Open Issue (also in section below and in 4.3.2): impact of locale on case sensitivity.

4.4.2 Identification Variables


An identification variable is a valid identifier declared in the FROM clause of a query. 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. Identification variables are case insensitive. An identification variable evaluates to a value of the type of the expression used in declaring the variable. 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 an entity, embeddable, or basic abstract schema type. An identification variable designates an instance of an abstract schema type or an element of a collection of abstract schema type instances. Note that for identification variables referring to an instance of an association or collection represented as a java.util.Map, the identification variable is of the abstract schema type of the map value. 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 identification 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. All identification variables used in the SELECT, WHERE, ORDER BY, GROUP BY, or HAVING clause of a SELECT or DELETE statement must be declared in the FROM clause. The identification variables used in the WHERE clause of an UPDATE statement must be declared in the UPDATE clause.

JSR-317 Public Review Draft

109

10/31/08

Sun Microsystems, Inc.


Query Language Java Persistence 2.0, Public Review Draft The FROM Clause and Navigational Declara-

Identification variables are existentially quantified in these clauses. This means that an identification variable represents a member of a collection or an instance of an entitys abstract schema type. An identification variable never designates a collection in its entirety. An identification variable is scoped to the query (or subquery) in which it is defined and is also visible to any subqueries within that query scope that do not define an identification variable of the same name.

4.4.3 Range Variable Declarations


The syntax for declaring an identification variable as a range variable is similar to that of SQL; optionally, it uses the AS keyword. A range variable designates an entity abstract schema type.[41] range_variable_declaration ::= entity_name [AS] identification_variable 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. 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 Smiths 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

4.4.4 Path Expressions


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. An identification variable qualified by the KEY, VALUE, or ENTRY operator is a path expression. The KEY, VALUE, and ENTRY operators may be applied to identification variables that correspond to map-valued associations or map-valued element collections. The type of the path expression is the type computed as the result of the operation; that is, the abstract schema type of the field that is the value of the KEY, VALUE, or ENTRY operator (the map key, map value, or map entry respectively).[42] The syntax for qualified identification variables is as follows.

[41] A range variable must not designate an embeddable class abstract schema type. [42] Note that use of VALUE is optional, as an identification variable referring to an association of type java.util.Map is of the abstract schema type of the map value. (See section 4.4.2.)

10/31/08

110

JSR-317 Public Review Draft

Sun Microsystems, Inc.


The FROM Clause and Navigational DeclarationsJava Persistence 2.0, Public Review Draft Query Language

qualified_identification_variable :: = KEY(identification_variable) | VALUE(identification_variable) | ENTRY(identification_variable) A path expression using the KEY or VALUE operator may be further composed. A path expression using the ENTRY operator is terminal. It cannot be further composed and can only appear in the SELECT list of a query. In the following query, photos is a map from photo label to filename. SELECT i.name, VALUE(p) FROM Item i JOIN i.photos p WHERE KEY(p) LIKE egret In the above query the identification variable p designates an abstract schema type corresponding to the map value. The results of VALUE(p) and KEY(p) are the map value and the map key associated with p, respectively. The following query is equivalent: SELECT i.name, p FROM Item i JOIN i.photos p WHERE KEY(p) LIKE egret Depending on navigability, a path expression that leads to an association field or to a field whose type is an embeddable class 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). In the following example, contactInfo denotes an embeddable class consisting of an address and set of phones. Phone is an entity. SELECT p.vendor FROM Employee e JOIN e.contactInfo.phones p WHERE e.contactInfo.address.zipcode = '95054' Path expression navigability is composed using inner join semantics. That is, if the value of a non-terminal 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 ::= qualified_identification_variable | state_field_path_expression | single_valued_object_path_expression state_field_path_expression ::= general_identification_variable.{single_valued_object_field.}*state_field single_valued_object_path_expression ::= general_identification_variable.{single_valued_object_field.}*single_valued_object_field collection_valued_path_expression ::= general_identification_variable.{single_valued_object_field.}*collection_valued_field

JSR-317 Public Review Draft

111

10/31/08

Sun Microsystems, Inc.


Query Language Java Persistence 2.0, Public Review Draft The FROM Clause and Navigational Declara-

A single_valued_object_field is designated by the name of an association field in a one-to-one or many-to-one relationship or a field of embeddable class type. The type of a single_valued_object_field is the abstract schema type of the related entity or embeddable class. A state _field is designated by the name of an entity or embeddable class state field that corresponds to a basic type. A collection_valued_field is designated by the name of an association field in a one-to-many or a many-to-many relationship or by the name of an element collection field. The type of a collection_valued_field is a collection of values of the abstract schema type of the related entity or element type. An identification variable used in a single_valued_object_path_expression or in a collection_valued_path_expression may be an unqualified identification variable or an identification variable to which the KEY or VALUE function has been applied. general_identification_variable ::= identification_variable | KEY(identification_variable) | VALUE(identification_variable) It is syntactically illegal to compose a path expression from a path expression that evaluates to a collection. 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: SELECT DISTINCT l.product FROM Order AS o, IN(o.lineItems) l It is illegal to use a collection_valued_path_expression other than in the FROM clause of a query except in an empty_collection_comparison_expression, in a collection_member_expression, or as an argument to the SIZE operator. See Sections 4.6.12, 4.6.13, and 4.6.17.2.2.

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: SELECT c FROM Customer c, Employee e WHERE c.hatsize = e.shoesize

10/31/08

112

JSR-317 Public Review Draft

Sun Microsystems, Inc.


The FROM Clause and Navigational DeclarationsJava Persistence 2.0, Public Review Draft Query Language

In general, use of this style of inner join (also referred to as theta-join) is less typical than explicitly defined joins over relationships. The syntax for explicit join operations is as follows: 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_path_expression join_collection_valued_path_expression::= identification_variable.{single_valued_embeddable_object_field.}*collection_valued_field join_single_valued_path_expression::= identification_variable.{single_valued_embeddable_object_field.}*single_valued_object_field join_spec::= [ LEFT [OUTER] | INNER ] JOIN The inner and outer join operation types described in sections 4.4.5.1, 4.4.5.2, and 4.4.5.3 are supported.

4.4.5.1 Inner Joins (Relationship Joins)


The syntax for the inner join operation is [ INNER ] JOIN join_association_path_expression [AS] identification_variable 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. SELECT c FROM Customer c JOIN c.orders o WHERE c.status = 1 The keyword INNER may optionally be used: SELECT c FROM Customer c INNER JOIN c.orders o WHERE c.status = 1 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: SELECT OBJECT(c) FROM Customer c, IN(c.orders) o WHERE c.status = 1 The query below joins over Employee, ContactInfo and Phone. ContactInfo is an embeddable class that consists of an address and set of phones. Phone is an entity. SELECT p.vendor FROM Employee e JOIN e.contactInfo c JOIN c.phones p WHERE c.address.zipcode = '95054'

4.4.5.2 Left Outer Joins


LEFT JOIN and LEFT OUTER JOIN are synonymous. They enable the retrieval of a set of entities where matching values in the join condition may be absent. The syntax for a left outer join is

JSR-317 Public Review Draft

113

10/31/08

Sun Microsystems, Inc.


Query Language Java Persistence 2.0, Public Review Draft The FROM Clause and Navigational Declara-

LEFT [OUTER] JOIN join_association_path_expression [AS] identification_variable

For example: SELECT c FROM Customer c LEFT JOIN c.orders o WHERE c.status = 1 The keyword OUTER may optionally be used: SELECT c FROM Customer c LEFT OUTER JOIN c.orders o WHERE c.status = 1 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.

4.4.5.3 Fetch Joins


A FETCH JOIN enables the fetching of an association or element collection as a side effect of the execution of a query. The syntax for a fetch join is fetch_join ::= [ LEFT [OUTER] | INNER ] JOIN FETCH join_association_path_expression The association referenced by the right side of the FETCH JOIN clause must be an association or element collection that is referenced from an entity or embeddable that is returned as a result of the query. It is not permitted to specify an identification variable for the objects referenced by the right side of the FETCH JOIN clause, and hence references to the implicitly fetched entities or elements 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 initialization of the persistent state or relationship fields or properties of the objects that are retrieved as a result of a fetch join is determined by the metadata for that classin this example, the Employee entity class. SELECT d FROM Department d LEFT JOIN FETCH d.employees WHERE d.deptno = 1 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 otherwise referenced in the query. Hence, for example, if department 1 has five employees, the above query returns five references to the department 1 entity. The FETCH JOIN construct must not be used in the FROM clause of a subquery.

4.4.6 Collection Member Declarations


An identification variable declared by a collection_member_declaration ranges over values of a collection obtained by navigation using a path expression.

10/31/08

114

JSR-317 Public Review Draft

Sun Microsystems, Inc.


The FROM Clause and Navigational DeclarationsJava Persistence 2.0, Public Review Draft Query Language

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 association field of an entity or embeddable class abstract schema type. The syntax for declaring a collection member identification variable is as follows: collection_member_declaration ::= IN (collection_valued_path_expression) [AS] identification_variable For example, the query SELECT DISTINCT o FROM Order o JOIN o.lineItems l WHERE l.product.productType = office_supplies may equivalently be expressed as follows, using the IN operator: SELECT DISTINCT o FROM Order o, IN(o.lineItems) l WHERE l.product.productType = office_supplies In this example, lineItems is the name of an association field whose value is a collection of instances of the abstract schema type LineItem. The identification variable l designates a member of this collection, a single LineItem abstract schema type instance. In this example, o is an identification variable of the abstract schema type Order.

4.4.7 FROM Clause and SQL


The Java Persistence query language treats the FROM clause similarly to SQL in that the declared identification variables affect the results of the query even if they are not used in the WHERE clause. Application 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 JOIN o.lineItems l JOIN 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 it explicitly refers but instances of subclasses of those classes as well. The instances returned by a query thus include instances of the subclasses that satisfy the query criteria. Non-polymorphic queries or queries whose polymorphism is restricted may be specified using entity type expressions in the WHERE clause to restrict the domain of the query.
JSR-317 Public Review Draft

115

10/31/08

Sun Microsystems, Inc.


Query Language Java Persistence 2.0, Public Review Draft WHERE Clause

4.4.9 Entity Type Expressions


An entity type expression can be used to restrict query polymorphism. The TYPE operator returns the exact type of the argument. The syntax of an entity type expression is as follows: entity_type_expression ::= type_discriminator | entity_type_literal | input_parameter type_discriminator ::= TYPE(identification_variable | single_valued_object_path_expression | input_parameter ) An entity_type_literal is designated by the entity name. The Java class of the entity is used as an input parameter to specify the entity type. Examples: SELECT e FROM Employee e WHERE TYPE(e) IN (Exempt, Contractor) SELECT e FROM Employee e WHERE TYPE(e) IN (:empType1, :empType2) SELECT e FROM Employee e WHERE TYPE(e) IN :empTypes SELECT TYPE(e) FROM Employee e WHERE TYPE(e) <> Exempt

4.5 WHERE Clause


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. A WHERE clause is defined as follows: where_clause ::= WHERE conditional_expression

10/31/08

116

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Conditional Expressions Java Persistence 2.0, Public Review Draft Query Language

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 syntax of the HAVING clause is as follows: having_clause ::= HAVING conditional_expression The GROUP BY and HAVING constructs are further discussed in Section 4.7.

4.6 Conditional Expressions


The following sections describe language constructs that can be used in a conditional expression of the WHERE clause or HAVING clause of a query. State fields that are mapped in serialized form or as lobs may not be portably used in conditional expressions[43].

4.6.1 Literals
A string literal is enclosed in single quotesfor example: literal. A string literal that includes a single quote is represented by two single quotesfor example: literals. 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. 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. Enum literals support the use of Java enum literal syntax. The fully qualified enum class name must be specified. Date, time, and timestamp literals support the use of SQL syntaxfor example: 2008-06-01 10:00:01.0-09:00. Open Issue: should this be ISO 8601 syntax, e.g., 2008-06-01T10:00:01.0-09:00 ? The boolean literals are TRUE and FALSE.
[43] The implementation is not expected to perform such query operations involving such fields in memory rather than in the database.

JSR-317 Public Review Draft

117

10/31/08

Sun Microsystems, Inc.


Query Language Java Persistence 2.0, Public Review Draft Conditional Expressions

Entity type literals are specified by entity namesfor example: Customer. Although reserved literals appear in upper case, they are case insensitive.

4.6.2 Identification Variables


All identification variables used in the WHERE or HAVING clause of a SELECT or DELETE statement 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 entitys abstract schema type. An identification variable never designates a collection in its entirety.

4.6.3 Path Expressions


It is illegal to use a collection_valued_path_expression within a WHERE or HAVING clause as part of a conditional expression except in an empty_collection_comparison_expression, in a collection_member_expression, or as an argument to the SIZE operator.

4.6.4 Input Parameters


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. All input parameters must be single-valued, except in IN expressions (see section 4.6.9), which support the use of collection-valued input parameters.

4.6.4.1 Positional Parameters


The following rules apply to positional parameters.

Input parameters are designated by the question mark (?) prefix followed by an integer. For
example: ?1.

Input parameters are numbered starting from 1. The same parameter can be used more than once in the query string. The ordering of the use of parameters within the query string need not conform to the order of
the positional parameters.

10/31/08

118

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Conditional Expressions Java Persistence 2.0, Public Review Draft Query Language

4.6.4.2 Named Parameters


A named parameter is denoted by an identifier that is prefixed by the ":" symbol. It follows the rules for identifiers defined in Section 4.4.1. Named parameters are case sensitive. Example: SELECT c FROM Customer c WHERE c.status = :stat The same named parameter can be used more than once in the query string. Section 3.6.1 describes the API for the binding of named query parameters.

4.6.5 Conditional Expression Composition


Conditional expressions are composed of other conditional expressions, comparison operations, logical operations, path expressions that evaluate to boolean values, boolean literals, and boolean input parameters. The scalar expressions described in section 4.6.17 can be used in conditional expressions. Aggregate functions can only be used in conditional expressions in a HAVING clause. See section 4.7. Standard bracketing () for ordering expression evaluation is supported. Conditional expressions are defined as follows: 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 | in_expression | like_expression | null_comparison_expression | empty_collection_comparison_expression | collection_member_expression | exists_expression

4.6.6 Operators and Operator Precedence


The operators are listed below in order of decreasing precedence.

Navigation operator (.)

JSR-317 Public Review Draft

119

10/31/08

Sun Microsystems, Inc.


Query Language Java Persistence 2.0, Public Review Draft Conditional Expressions

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 following sections describe other operators used in specific expressions.

4.6.7 Comparison Expressions


The syntax for the use of comparison expressions in a conditional expression is as follows: 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} | entity_type_expression { = | <>} entity_type_expression} comparison_operator ::= = | > | >= | < | <= | <> Examples are: item.cost * 1.08 <= 100.00 CONCAT(person.lastName, , , person.firstName)) = Jones, Sam TYPE(e) = ExemptEmployee

4.6.8 Between Expressions


The syntax for the use of the comparison operator [NOT] BETWEEN in a conditional expression is as follows: 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

10/31/08

120

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Conditional Expressions Java Persistence 2.0, Public Review Draft Query Language

The BETWEEN expression x BETWEEN y AND z is semantically equivalent to: y <= x AND x <= z The rules for unknown and NULL values in comparison operations apply. See Section 4.11. Examples are: p.age BETWEEN 15 and 19 is equivalent to p.age >= 15 AND p.age <= 19 p.age NOT BETWEEN 15 and 19 is equivalent to p.age < 15 OR p.age > 19 In the following example, transactionHistory is a list of credit card transactions defined using an order column. SELECT t FROM CreditCard c JOIN c.transactionHistory t WHERE c.holder.name = John Doe AND INDEX(t) BETWEEN 0 AND 9

4.6.9 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 | type_discriminator} [NOT] IN { ( in_item {, in_item}* ) | (subquery) | collection_valued_input_parameter } in_item ::= literal | single_valued_input_parameter The state_field_path_expression must have a string, numeric, or enum value. Open Issue: support for date / time / timestamps ? 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 state_field_path_expression in type. Subqueries are discussed in Section 4.6.16. 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). type of the

JSR-317 Public Review Draft

121

10/31/08

Sun Microsystems, Inc.


Query Language Java Persistence 2.0, Public Review Draft Conditional Expressions

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. If the value of a state_field_path_expression or in_item in an IN or NOT IN expression is NULL or unknown, the value of the expression is unknown. Note that use of a collection-valued input parameter will mean that a static query cannot be precompiled.

4.6.10 Like Expressions


The syntax for the use of the comparison operator [NOT] LIKE in a conditional expression is as follows: string_expression [NOT] LIKE pattern_value [ESCAPE escape_character] 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 underscore and percent characters in pattern_value.[44] 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 expression is unknown.

[44] Refer to [4] for a more precise characterization of these rules.

10/31/08

122

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Conditional Expressions Java Persistence 2.0, Public Review Draft Query Language

4.6.11 Null Comparison Expressions


The syntax for the use of the comparison operator IS NULL in a conditional expression is as follows: {single_valued_path_expression | input_parameter } IS [NOT] NULL A null comparison expression tests whether or not the single-valued path expression or input parameter is a NULL value.

4.6.12 Empty Collection Comparison Expressions


The syntax for the use of the comparison empty_collection_comparison_expression is as follows: collection_valued_path_expression IS [NOT] EMPTY 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. operator IS EMPTY in an

4.6.13 Collection Member Expressions


The syntax for the use of the comparison collection_member_expression is as follows: operator MEMBER OF[45] in an

entity_or_value_expression [NOT] MEMBER [OF] collection_valued_path_expression entity_or_value_expression ::= single_valued_object_path_expression | state_field_path_expression | simple_entity_or_value_expression simple_entity_or_value_expression ::= identification_variable | input_parameter | literal This expression tests whether the designated value is a member of the collection specified by the collection-valued path expression.

[45] The use of the reserved word OF is optional in this expression.

JSR-317 Public Review Draft

123

10/31/08

Sun Microsystems, Inc.


Query Language Java Persistence 2.0, Public Review Draft Conditional Expressions

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 entity_or_value_expression in the collection member expression is NULL or unknown, the value of the collection member expression is unknown. Example: SELECT p FROM Person p WHERE 'Joe' MEMBER OF p.nicknames

4.6.14 Exists Expressions


An EXISTS expression is a predicate that is true only if the result of the subquery consists of one or more values and that is false otherwise. The syntax of an exists expression is exists_expression::= [NOT] EXISTS (subquery) Example: SELECT DISTINCT emp FROM Employee emp WHERE EXISTS ( SELECT spouseEmp FROM Employee spouseEmp WHERE spouseEmp = emp.spouse) The result of this query consists of all employees whose spouses are also employees.

4.6.15 All or Any Expressions


An ALL conditional expression is a predicate that is true if the comparison operation is true for all values in the result of the subquery or the result of the subquery is empty. An ALL conditional expression is false if the result of the comparison is false for at least one row, and is unknown if neither true nor false. 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. The syntax of an ALL or ANY expression is specified as follows: all_or_any_expression ::= { ALL | ANY | SOME} (subquery)
10/31/08

124

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Conditional Expressions Java Persistence 2.0, Public Review Draft Query Language

Example: SELECT emp FROM Employee emp WHERE emp.salary > ALL ( SELECT m.salary FROM Manager m WHERE m.department = emp.department) The result of this query consists of all employees whose salaries exceed the salaries of all managers in their department.

4.6.16 Subqueries
Subqueries may be used in the WHERE or HAVING clause.[46] The syntax for subqueries is as follows: subquery ::= simple_select_clause subquery_from_clause [where_clause] [groupby_clause] [having_clause] simple_select_clause ::= SELECT [DISTINCT] simple_select_expression subquery_from_clause ::= FROM subselect_identification_variable_declaration {, subselect_identification_variable_declaration | collection_member_declaration }* subselect_identification_variable_declaration ::= identification_variable_declaration | derived_path_expression [AS] identification_variable {join}* | derived_collection_member_declaration simple_select_expression::= single_valued_path_expression | scalar_expression | aggregate_expression | identification_variable derived_path_expression ::= superquery_identification_variable.{single_valued_object_field.}*collection_valued_field | superquery_identification_variable.{single_valued_object_field.}*single_valued_object_field derived_collection_member_declaration ::= IN superquery_identification_variable.{single_valued_object_field.}*collection_valued_field

[46] 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.

JSR-317 Public Review Draft

125

10/31/08

Sun Microsystems, Inc.


Query Language Java Persistence 2.0, Public Review Draft Conditional Expressions

Examples: SELECT DISTINCT emp FROM Employee emp WHERE EXISTS ( SELECT spouseEmp FROM Employee spouseEmp WHERE spouseEmp = emp.spouse) 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 examples involving numeric comparisons. SELECT c FROM Customer c WHERE (SELECT AVG(o.price) FROM c.orders o) > 100 SELECT goodCustomer FROM Customer goodCustomer WHERE goodCustomer.balanceOwed < ( SELECT AVG(c.balanceOwed)/2.0 FROM Customer c)

4.6.17 Scalar Expressions


Numeric, string, datetime, case, and entity type expressions result in scalar values. Scalar expressions may be used in the SELECT clause of a query as well as in the WHERE[47] and HAVING clauses. scalar_expression::= simple_arithmetic_expression | string_primary | enum_primary | datetime_primary | boolean_primary | case_expression | entity_type_expression

4.6.17.1 Arithmetic Expressions


The arithmetic operators are: +, - unary *, / multiplication and division +, - addition and subtraction Arithmetic operations use numeric promotion.

[47] Note that expressions involving aggregate operators must not be used in the WHERE clause.

10/31/08

126

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Conditional Expressions Java Persistence 2.0, Public Review Draft Query Language

Arithmetic functions are described in section 4.6.17.2.2.

4.6.17.2 String, Arithmetic, and Datetime Functional Expressions


The Java Persistence query language includes the following built-in functions, which may be used in the SELECT, 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. 4.6.17.2.1 String Functions functions_returning_strings ::= CONCAT(string_primary, 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 CONCAT function returns a string that is a concatenation of its arguments. 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 third argument is optional. If it is not specified, the substring from the start position to the end of the string is returned. 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)[48]. 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, with regard to the locale of the database. They return a string. The LOCATE function returns the position of a given string within a string, starting the search at a specified 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.[49]
[48] 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.

JSR-317 Public Review Draft

127

10/31/08

Sun Microsystems, Inc.


Query Language Java Persistence 2.0, Public Review Draft Conditional Expressions

The LENGTH function returns the length of the string in characters as an integer. 4.6.17.2.2 Arithmetic Functions functions_returning_numerics::= ABS(simple_arithmetic_expression) | SQRT(simple_arithmetic_expression) | MOD(simple_arithmetic_expression, simple_arithmetic_expression) | SIZE(collection_valued_path_expression) | INDEX(identification_variable) 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. The SQRT function takes a numeric argument and returns a double. The MOD function takes two integer arguments and returns an integer. Numeric arguments to these functions may correspond to the numeric Java object types as well as the primitive numeric types. 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. The INDEX function returns an integer value corresponding to the position of its argument in an ordered list. The INDEX function can only be applied to identification variables denoting types for which an order column has been specified. In the following example, studentWaitlist is a list of students for which an order column has been specified: SELECT w.name FROM Course c JOIN c.studentWaitlist w WHERE c.name = Calculus AND INDEX(w) = 0 4.6.17.2.3 Datetime Functions 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. Open Issue: Addition of the functional equivalent of EXTRACT on date/time/timestamp types.

[49] 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.

10/31/08

128

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Conditional Expressions Java Persistence 2.0, Public Review Draft Query Language

4.6.17.3 Case Expressions


The following forms of case expressions are supported: general case expressions, simple case expressions, coalesce expressions, and nullif expressions. case_expression::= general_case_expression | simple_case_expression | coalesce_expression | nullif_expression general_case_expression::= CASE when_clause {when_clause}* ELSE scalar_expression END when_clause::= WHEN conditional_expression THEN scalar_expression simple_case_expression::= CASE case_operand simple_when_clause {simple_when_clause}* ELSE scalar_expression
END

case_operand::= state_field_path_expression | type_discriminator simple_when_clause::= WHEN scalar_expression THEN scalar_expression coalesce_expression::= COALESCE(scalar_expression {, scalar_expression}+) nullif_expression::= NULLIF(scalar_expression, scalar_expression) For example: UPDATE Employee e SET e.salary = CASE WHEN e.rating = 1 THEN e.salary * 1.1 WHEN e.rating = 2 THEN e.salary * 1.05 ELSE e.salary * 1.01 END UPDATE Employee e SET e.salary = CASE e.rating WHEN 1 THEN e.salary * 1.1 WHEN 2 THEN e.salary * 1.2 ELSE e.salary * 1.01 END SELECT e.name, CASE TYPE(e) WHEN Exempt THEN 'Exempt' WHEN Contractor THEN 'Contractor' WHEN Intern THEN 'Intern' ELSE 'NonExempt' END FROM Employee e WHERE e.dept.name = 'Engineering'

JSR-317 Public Review Draft

129

10/31/08

Sun Microsystems, Inc.


Query Language Java Persistence 2.0, Public Review Draft GROUP BY, HAVING

SELECT e.name, f.name, CONCAT(CASE WHEN f.annualMiles > 50000 THEN 'Platinum ' WHEN f.annualMiles > 25000 THEN 'Gold ' ELSE '' END, 'Frequent Flyer') FROM Employee e JOIN e.frequentFlierPlan f

4.7 GROUP BY, HAVING


The GROUP BY construct enables the aggregation of result values according to a set of properties. The HAVING construct enables conditions to be specified that further restrict the query result. Such conditions are restrictions upon the groups. The syntax of the GROUP BY and HAVING clauses is as follows: groupby_clause ::= GROUP BY groupby_item {, groupby_item}* groupby_item ::= single_valued_path_expression | identification_variable having_clause ::= HAVING conditional_expression 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 aggregate function or 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 grouping purposes. Grouping by an entity is permitted. In this case, the entity must contain no serialized state fields or lob-valued state fields that are eagerly fetched. Grouping by an entity that contains serialized state fields or lob-valued state fields is not portable, since the implementation is permitted to eagerly fetch fields or properties that have been specified as LAZY. Grouping by embeddables is not supported. The HAVING clause is used to filter over the groups, and can contain aggregate functions over attributes included in the groups and/or functions or other query language operators over the attributes that are used for grouping. It is not required that an aggregate function used in the HAVING clause also be used in the SELECT clause. 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 applications should not rely on HAVING without the use of GROUP BY.

10/31/08

130

JSR-317 Public Review Draft

Sun Microsystems, Inc.


SELECT Clause Java Persistence 2.0, Public Review Draft Query Language

Examples: SELECT c.status, AVG(c.filledOrderCount), COUNT(c) FROM Customer c GROUP BY c.status HAVING c.status IN (1, 2) SELECT c.country, COUNT(c) FROM Customer c GROUP BY c.country HAVING COUNT(c) > 30

4.8 SELECT Clause


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: an identification variable that ranges over an entity abstract schema type, a single-valued path expression, a scalar expression, an aggregate expression, a constructor expression. The SELECT clause has the following syntax: select_clause ::= SELECT [DISTINCT] select_item {, select_item}* select_item ::= select_expression [ [AS] result_variable] select_expression ::= single_valued_path_expression | scalar_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 | scalar_expression | aggregate_expression | identification_variable aggregate_expression ::= { AVG | MAX | MIN | SUM } ([DISTINCT] state_field_path_expression) | COUNT ([DISTINCT] identification_variable | state_field_path_expression | single_valued_object_path_expression)

JSR-317 Public Review Draft

131

10/31/08

Sun Microsystems, Inc.


Query Language Java Persistence 2.0, Public Review Draft SELECT Clause

For example: SELECT c.id, c.status FROM Customer c JOIN c.orders o WHERE o.count > 100 In the following example, videoInventory is a Map from the entity Movie to the number of copies in stock: SELECT v.location.street, KEY(i).title, VALUE(i) FROM VideoStore v JOIN v.videoInventory i WHERE v.location.zipcode = '94301' AND VALUE(i) > 0 Note that the SELECT clause must be specified to return only single-valued expressions. The query below is therefore not valid: SELECT o.lineItems FROM Order AS o 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. The result of DISTINCT over embeddable objects or map entry results is undefined. Standalone identification variables in the SELECT clause may optionally be qualified by the OBJECT operator.[50] The SELECT clause must not use the OBJECT operator to qualify path expressions. A result_variable may be used to name a select_item in the query result.[51] For example, SELECT c, COUNT(l) AS itemCount FROM Customer c JOIN c.Orders o JOIN o.lineItems l WHERE c.address.state = CA ORDER BY itemCount

4.8.1 Result Type of the SELECT Clause


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 a scalar expression, the result of an aggregate function, the result of a construction operation, or some sequence of these.

[50] Note that the keyword OBJECT is not required. It is preferred that it be omitted for new queries. [51] This can be used, for example, to refer to a select expression in the ORDER BY clause.

10/31/08

132

JSR-317 Public Review Draft

Sun Microsystems, Inc.


SELECT Clause Java Persistence 2.0, Public Review Draft Query Language

The result type of the SELECT clause is defined by the the result types of the select expressions contained 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 specification in the SELECT clause and in type to the result types of each of the select expressions. The type of the result of a select_expression is as follows:

The result type of an identification_variable results in an entity object or embeddable object


of the type to which the identification variable corresponds. An identification_variable that refers to an entity abstract schema type is the type of the entity to which that identification variable corresponds or a subtype as determined by the object/relational mapping.

The

result type of a single_valued_path_expression that is a state_field_path_expression is an object of the same type as the corresponding state field of the entity or embeddable class. If the state field of the entity is a primitive type, the corresponding object type is returned. result type of a single_valued_path_expression that is a single_valued_object_path_expression is an entity object or embeddable object of the type to which the path expression corresponds. A single_valued_object_path_expression that results in an entity object will result in an entity 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

The result type of a single_valued_path_expression that is an identification_variable to


which the KEY or VALUE function has been applied is determined by the type of the map key or value respectively, as defined by the above rules.

The result type of a single_valued_path_expression that is an identification_variable to


which the ENTRY function has been applied is java.util.Map.Entry, where the key and value types of the map entry are determined by the above rules as applied to the map key and map value respectively.

The result type of a scalar_expression is the type of the scalar value to which the expression
evaluates. The result type of an entity_type_expression scalar expression is the Java class to which the resulting abstract schema type corresponds.

The result type of aggregate_expression is defined in section 4.8.4. 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.

4.8.2 Constructor Expressions in the SELECT Clause


A constructor may be used in the SELECT list to return an instance of a Java class. The specified class is not required to be an entity or to be mapped to the database. The constructor name must be fully qualified.

JSR-317 Public Review Draft

133

10/31/08

Sun Microsystems, Inc.


Query Language Java Persistence 2.0, Public Review Draft SELECT Clause

If an entity class name is specified as the constructor name in the SELECT NEW clause, the resulting entity instances are in the new state. For example, SELECT NEW com.acme.example.CustomerDetails(c.id, c.status, o.count) FROM Customer c JOIN c.orders o WHERE o.count > 100

4.8.3 Null Values in the Query Result


If the result of a query corresponds to an 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 eliminate 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.

4.8.4 Aggregate Functions in the SELECT Clause


The result of a query may be the result of an aggregate function applied to a path expression. 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:

COUNT returns Long. MAX, MIN return the type of the state field to which they are applied. AVG returns Double. SUM returns Long when applied to state fields of integral types (other than BigInteger); Double 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. Null values are eliminated before the aggregate function is applied, regardless of whether the keyword DISTINCT is specified.

10/31/08

134

JSR-317 Public Review Draft

Sun Microsystems, Inc.


SELECT Clause Java Persistence 2.0, Public Review Draft Query Language

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.[52] The use of DISTINCT with COUNT is not supported for arguments of embeddable types or map entry types.

4.8.4.1 Examples
The following query returns the average order quantity: SELECT AVG(o.quantity) FROM Order o 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 The following query returns the total number of orders. SELECT COUNT(o) FROM Order o The following query counts the number of items in John Smiths order for which prices have been specified. SELECT COUNT(l.price) FROM Order o JOIN o.lineItems l JOIN o.customer c WHERE c.lastname = Smith AND c.firstname = John Note that this is equivalent to: 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

[52] It is legal to specify DISTINCT with MAX or MIN, but it does not affect the result.

JSR-317 Public Review Draft

135

10/31/08

Sun Microsystems, Inc.


Query Language Java Persistence 2.0, Public Review Draft ORDER BY Clause

4.9 ORDER BY Clause


The ORDER BY clause allows the objects or values that are returned by the query to be ordered. The syntax of the ORDER BY clause is orderby_clause ::= ORDER BY orderby_item {, orderby_item}* orderby_item ::= { state_field_path_expression | result_variable } [ASC | DESC] An orderby_item must be one of the following: 1. A state_field_path_expression that evaluates to an orderable state field of an entity or embeddable class abstract schema type designated in the SELECT clause by one of the following: a general_identification_variable

a single_valued_object_path_expression
2. A state_field_path_expression that evaluates to the same state field of the same entity or embeddable abstract schema type as a state_field_path_expression in the SELECT clause A result_variable that refers to an orderable item in the SELECT clause for which the same result_variable has been specified. This may be the result of an aggregate_expression, a scalar_expression, or a state_field_path_expression in the SELECT clause.

3.

For example, the four queries below are legal. SELECT o FROM Customer c JOIN c.orders o JOIN c.address a WHERE a.state = CA ORDER BY o.quantity DESC, o.totalcost SELECT o.quantity, a.zipcode FROM Customer c JOIN c.orders o JOIN c.address a WHERE a.state = CA ORDER BY o.quantity, a.zipcode SELECT o.quantity, o.cost*1.08 AS taxedCost, a.zipcode FROM Customer c JOIN c.orders o JOIN c.address a WHERE a.state = CA AND a.county = Santa Clara ORDER BY o.quantity, taxedCost, a.zipcode SELECT AVG(o.quantity) as q, a.zipcode FROM Customer c JOIN c.orders o JOIN c.address a WHERE a.state = CA GROUP BY a.zipcode ORDER BY q DESC

10/31/08

136

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Bulk Update and Delete Operations Java Persistence 2.0, Public Review Draft Query Language

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 for the associated orderby_item; the keyword DESC specifies that descending 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.

4.10 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. The syntax of these operations is as follows: update_statement ::= update_clause [where_clause] update_clause ::= UPDATE entity_name [[AS] identification_variable] SET update_item {, update_item}* update_item ::= [identification_variable.]{state_field | single_valued_object_field} = new_value new_value ::= scalar_expression | simple_entity_expression | NULL delete_statement ::= delete_clause [where_clause] delete_clause ::= DELETE FROM entity_name [[AS] identification_variable] The syntax of the WHERE clause is described in Section 4.5.

JSR-317 Public Review Draft

137

10/31/08

Sun Microsystems, Inc.


Query Language Java Persistence 2.0, Public Review Draft Null Values

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 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 transaction in a new persistence context or before fetching or accessing entities whose state might be affected by such operations. 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)

4.11 Null Values


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. The following is a brief description of these semantics:

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 object
field value into the respective TRUE or FALSE value.

10/31/08

138

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Equality and Comparison Semantics Java Persistence 2.0, Public Review Draft Query Language

Boolean operators use three valued logic, defined by Table 1, Table 2, and Table 3.
Table 1 Definition of the AND Operator
AND T F U T T F U F F F F U U F U

Table 2

Definition of the OR Operator


OR T F U T T T T F T F U U T U U

Table 3

Definition of the NOT Operator


NOT T F U F T 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 distinguished 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.

4.12 Equality and Comparison Semantics


Only the values of like types are permitted to be compared. A type is like another type if they correspond 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.

JSR-317 Public Review Draft

139

10/31/08

Sun Microsystems, Inc.


Query Language Java Persistence 2.0, Public Review Draft Examples

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. Only equality/inequality comparisons over enums are required to be supported. Comparisons over instances of embeddable class or map entry types are not supported.

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.

4.13.1 Simple Queries


Find all orders: SELECT o FROM Order o Find all orders that need to be shipped to California: SELECT o FROM Order o WHERE o.shippingAddress.state = CA Find all states for which there are orders: SELECT DISTINCT o.shippingAddress.state FROM Order o

4.13.2 Queries with Relationships


Find all orders that have line items: 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

10/31/08

140

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Examples Java Persistence 2.0, Public Review Draft Query Language

Find all orders that have no line items: SELECT o FROM Order o WHERE o.lineItems IS EMPTY Find all pending orders: 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. 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 type 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

4.13.3 Queries Using Input Parameters


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.

JSR-317 Public Review Draft

141

10/31/08

Sun Microsystems, Inc.


Query Language Java Persistence 2.0, Public Review Draft BNF

4.14 BNF
BNF notation summary:

{ ... } grouping [ ... ] optional constructs boldface keywords * zero or more | alternates
The following is the BNF for the Java Persistence query language.

QL_statement ::= select_statement | update_statement | delete_statement select_statement ::= select_clause from_clause [where_clause] [groupby_clause] [having_clause] [orderby_clause] update_statement ::= update_clause [where_clause] delete_statement ::= delete_clause [where_clause] from_clause ::= FROM identification_variable_declaration {, {identification_variable_declaration | collection_member_declaration}}* identification_variable_declaration ::= range_variable_declaration { join | fetch_join }* range_variable_declaration ::= entity_name [AS] identification_variable join ::= join_spec join_association_path_expression [AS] identification_variable fetch_join ::= join_spec FETCH join_association_path_expression association_path_expression ::= collection_valued_path_expression | single_valued_object_path_expression join_spec::= [ LEFT [OUTER] | INNER ] JOIN join_association_path_expression ::= join_collection_valued_path_expression | join_single_valued_path_expression join_collection_valued_path_expression::= identification_variable.{single_valued_embeddable_object_field.}*collection_valued_field join_single_valued_path_expression::= identification_variable.{single_valued_embeddable_object_field.}*single_valued_object_field collection_member_declaration ::= IN (collection_valued_path_expression) [AS] identification_variable qualified_identification_variable ::= KEY(identification_variable) | VALUE(identification_variable) | ENTRY(identification_variable) single_valued_path_expression ::= qualified_identification_variable | state_field_path_expression | single_valued_object_path_expression
10/31/08

142

JSR-317 Public Review Draft

Sun Microsystems, Inc.


BNF Java Persistence 2.0, Public Review Draft Query Language

general_identification_variable ::= identification_variable | KEY(identification_variable) | VALUE(identification_variable) state_field_path_expression ::= general_identification_variable.{single_valued_object_field.}*state_field single_valued_object_path_expression ::= general_identification_variable.{single_valued_object_field.}* single_valued_object_field collection_valued_path_expression ::= general_identification_variable.{single_valued_object_field.}*collection_valued_field update_clause ::= UPDATE entity_name [[AS] identification_variable] SET update_item {, update_item}* update_item ::= [identification_variable.]{state_field | single_valued_object_field} = new_value new_value ::= scalar_expression | simple_entity_expression |
NULL

delete_clause ::= DELETE FROM entity_name [[AS] identification_variable] select_clause ::= SELECT [DISTINCT] select_item {, select_item}* select_item ::= select_expression [[AS] result_variable] select_expression ::= single_valued_path_expression | scalar_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 | scalar_expression | aggregate_expression | identification_variable aggregate_expression ::= { AVG | MAX | MIN | SUM } ([DISTINCT] state_field_path_expression) | COUNT ([DISTINCT] identification_variable | state_field_path_expression | single_valued_object_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 | result_variable [ 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 |
JSR-317 Public Review Draft

143

10/31/08

Sun Microsystems, Inc.


Query Language Java Persistence 2.0, Public Review Draft BNF

collection_member_declaration}* subselect_identification_variable_declaration ::= identification_variable_declaration | derived_path_expression [AS] identification_variable {join}*| derived_collection_member_declaration derived_path_expression ::= superquery_identification_variable.{single_valued_object_field.}*collection_valued_field | superquery_identification_variable.{single_valued_object_field.}*single_valued_object_field derived_collection_member_declaration ::= IN superquery_identification_variable.{single_valued_object_field.}*collection_valued_field simple_select_clause ::= SELECT [DISTINCT] simple_select_expression simple_select_expression::= single_valued_path_expression | scalar_expression | aggregate_expression | identification_variable scalar_expression ::= simple_arithmetic_expression | string_primary | enum_primary | datetime_primary | boolean_primary | case_expression | entity_type_expression 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 | in_expression | like_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 | type_discriminator} [NOT] IN { ( in_item {, in_item}* ) | (subquery) | collection_valued_input_parameter } in_item ::= literal | single_valued_input_parameter like_expression ::= string_expression [NOT] LIKE pattern_value [ESCAPE escape_character]

10/31/08

144

JSR-317 Public Review Draft

Sun Microsystems, Inc.


BNF Java Persistence 2.0, Public Review Draft Query Language

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_or_value_expression [NOT] MEMBER [OF] collection_valued_path_expression entity_or_value_expression ::= single_valued_assocation_path_expression | state_field_path_expression | simple_entity_or_value_expression simple_entity_or_value_expression ::= identification_variable | input_parameter | literal 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} | entity_type_expression { =|<>} entity_type_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 | case_expression string_expression ::= string_primary | (subquery) string_primary ::= state_field_path_expression | string_literal | input_parameter | functions_returning_strings | aggregate_expression | case_expression datetime_expression ::= datetime_primary | (subquery)

JSR-317 Public Review Draft

145

10/31/08

Sun Microsystems, Inc.


Query Language Java Persistence 2.0, Public Review Draft BNF

datetime_primary ::= state_field_path_expression | input_parameter | functions_returning_datetime | aggregate_expression | case_expression boolean_expression ::= boolean_primary | (subquery) boolean_primary ::= state_field_path_expression | boolean_literal | input_parameter | case_expression enum_expression ::= enum_primary | (subquery) enum_primary ::= state_field_path_expression | enum_literal | input_parameter | case_expression entity_expression ::= single_valued_object_path_expression | simple_entity_expression simple_entity_expression ::= identification_variable | input_parameter entity_type_expression ::= type_discriminator | entity_type_literal | input_parameter type_discriminator ::= TYPE(identification_variable | single_valued_object_path_expression | input_parameter) functions_returning_numerics::= LENGTH(string_primary) | LOCATE(string_primary, string_primary[, simple_arithmetic_expression]) | ABS(simple_arithmetic_expression) | SQRT(simple_arithmetic_expression) | MOD(simple_arithmetic_expression, simple_arithmetic_expression) | SIZE(collection_valued_path_expression) | INDEX(identification_variable) functions_returning_datetime ::= CURRENT_DATE | CURRENT_TIME |
CURRENT_TIMESTAMP

functions_returning_strings ::= CONCAT(string_primary, 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)
10/31/08

146

JSR-317 Public Review Draft

Sun Microsystems, Inc.


BNF Java Persistence 2.0, Public Review Draft Query Language

trim_specification ::= LEADING | TRAILING | BOTH case_expression ::= general_case_expression | simple_case_expression | coalesce_expression | nullif_expression general_case_expression::= CASE when_clause {when_clause}* ELSE scalar_expression END when_clause::= WHEN conditional_expression THEN scalar_expression simple_case_expression::= CASE case_operand simple_when_clause {simple_when_clause}* ELSE scalar_expression END case_operand::= state_field_path_expression | type_discriminator simple_when_clause::= WHEN scalar_expression THEN scalar_expression coalesce_expression::= COALESCE(scalar_expression {, scalar_expression}+) nullif_expression::= NULLIF(scalar_expression, scalar_expression)

JSR-317 Public Review Draft

147

10/31/08

Sun Microsystems, Inc.


Query Language Java Persistence 2.0, Public Review Draft BNF

10/31/08

148

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Overview Java Persistence 2.0, Public Review Draft Criteria API

C ha p t e r 5

Criteria API

The Java Persistence Criteria API is used to define dynamic queries via construction of an object-based query definition object, rather than use of the string-based approach used by the Java Persistence query language as described in Chapter 4. This chapter provides the full definition of the Criteria API.

5.1 Overview
The Criteria API, like the Java Persistence query language is based on the abstract persistence schema of entities, their embedded objects, and their relationships as its data model. Its syntax is designed to allow the construction of an object-based graph, whose nodes correspond to the semantic query elements. The semantics of criteria queries are designed to mirror those of Java Persistence query language queries, and elements of query definition objects correspond to the semantic constructs of the Java Persistence query language. Java language variables can be used to reference individual nodes in a query definition object as it is constructed and/or modified. Such variables, when used to refer to the entities and embeddable types that constitute the query domain, play a role analogous to that of the identification variables of the string-based Java Persistence query language.

JSR-317 Public Review Draft

149

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Criteria API Interfaces

These concepts are further described in the sections that follow. The Criteria API interfaces are presented in Section 5.2. Sections 5.3 through 5.14 of this chapter describe the construction and modification of criteria query definitions. Additional requirements on the persistence provider as described in Section 5.15.

5.2 Criteria API Interfaces


5.2.1 QueryBuilder Interface
package javax.persistence; /** * Factory interface for query definition objects */ public interface QueryBuilder { /** * Create an uninitialized query definition object. * @return query definition instance */ QueryDefinition createQueryDefinition(); /** * Create a query definition object with the given root. * The root must be an entity class. * @param cls - an entity class * @return root domain object */ DomainObject createQueryDefinition(Class root); /** * Create a query definition object whose root is derived from * a domain object of the containing query. * Provides support for correlated subqueries. Joins against the * resulting domain object do not affect the query domain of the * containing query. * The path expression must correspond to an entity class. * The path expression must not be a domain object of the * containing query. * @param path - path expression corresponding to the domain * object used to derive the subquery root. * @return the subquery DomainObject */ DomainObject createSubqueryDefinition(PathExpression path); }

10/31/08

150

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Criteria API Interfaces Java Persistence 2.0, Public Review Draft Criteria API

5.2.2 QueryDefinition Interface


package javax.persistence; import java.util.List; import java.util.Date; import java.util.Calendar; /** * Interface for construction of query definitions */ public interface QueryDefinition extends Subquery { /** * Add a query root corresponding to the * a cartesian product with any existing * The domain object that is returned is * the given query. * The argument must be an entity class. * @param cls - an entity class * @return DomainObject corresponding to * entity class. */ DomainObject addRoot(Class cls); given entity, forming roots. bound as a component of

the specified

/** Add a root derived from a domain object of the containing * query definition to a query definition used as a subquery. * Provides support for correlated subqueries. Joins against the * resulting domain object do not affect the query domain of the * containing query. * The path expression must correspond to an entity class. * The path expression must not be a domain object of the * containing query. * @param path - path expression corresponding to the domain * object used to derive the subquery root. * @return the subquery DomainObject */ DomainObject addSubqueryRoot(PathExpression path); /** * Specify the objects / values to be returned. * Replaces the previous select list, if any. * If no select items are specified and there is only one * query root, the root entity is assumed to be the result. * @param selectItems - one or more SelectItem instances * @return the modified query definition instance */ QueryDefinition select(SelectItem... selectItems); /** * Specify the objects / values to be returned. * Replaces the previous select list, if any. * If no select items are specified and there is only one * query root, the root entity is assumed to be the result. * @param selectItemList - a list containing one or more * SelectItem instances * @return the modified query definition instance */ QueryDefinition select(List<SelectItem> selectItemList);
JSR-317 Public Review Draft

151

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Criteria API Interfaces

/** * Specify the objects / values to be returned. * Duplicate results will be eliminated. * Replaces the previous select list, if any. * If no select items are specified and there is only one * query root, the root entity is assumed to be the result. * @param selectItems - one or more SelectItem instances * @return the modified query definition instance */ QueryDefinition selectDistinct(SelectItem... selectItems); /** * Specify the objects / values to be returned. * Duplicate results will be eliminated. * Replaces the previous select list, if any. * If no select items are specified, and there is only one * query root, the root entity is assumed to be the result. * is assumed to be the result. * @param selectItemList - a list containing one or more * SelectItem instances * @return the modified query definition instance */ QueryDefinition selectDistinct(List<SelectItem> selectItemList); /** * Modifies the query definition to restrict the * result of the query according to the specified predicate. * Replaces the previously added restriction(s), if any. * @param predicate - a simple or compound conditional predicate * @return the modified QueryDefinition instance */ QueryDefinition where(Predicate predicate); /** * Specify the items of the select list that are used * in ordering the query results. * Replaces the previous order-by list, if any. * @param orderByItems - one or more OrderByItem instances * @return the modified QueryDefinition instance */ QueryDefinition orderBy(OrderByItem... orderByItems); /** * Specify the items of the select list that are used * in ordering the query results. * Replaces the previous order-by list, if any. * @param orderByItemList - a list containing one or more * OrderByItem instances * @return the modified QueryDefinition instance */ QueryDefinition orderBy(List<OrderByItem> orderByItemList); /** * * * * * Specify the items that are used to form groups over the query results. Replaces the previous group-by list, if any. @param pathExprs @return the modified QueryDefinition instance

10/31/08

152

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Criteria API Interfaces Java Persistence 2.0, Public Review Draft Criteria API

*/ QueryDefinition groupBy(PathExpression... pathExprs); /** * Specify the items that are used to form groups over * the query results. * Replaces the previous group-by list, if any. * @param pathExprList * @return the modified QueryDefinition instance */ QueryDefinition groupBy(List<PathExpression> pathExprList); /** * Specify the restrictions over the groups of a query. * Replaces the previous having restriction(s), if any. * @param predicate * @return the modified QueryDefinition Instance */ QueryDefinition having(Predicate predicate); /** * Specify that a constructor for the given class is to * be applied to the corresponding query results after * the query is executed. * The class must have a constructor that accepts the Java * argument types corresponding to the given select items. * @param cls - a class with the correponding constructor * @param args - select items that correspond to result * types that are valid as arguments to * the constructor * @result SelectItem instance representing the constructor */ SelectItem newInstance(Class cls, SelectItem... args); /** * Use the query definition instance as a subquery in an * exists predicate. * @return the resulting predicate */ Predicate exists(); /** * Use the query definition object in a subquery in * an all expression. * @return the resulting Subquery */ Subquery all(); /** * Use the query definition object in a subquery in * an any expression. * @return the resulting Subquery */ Subquery any();

JSR-317 Public Review Draft

153

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Criteria API Interfaces

/** * Use the query definition object in a subquery in * a some expression. * @return the resulting Subquery */ Subquery some(); /** * Create an empty general case expression. * A general case expression is of the form: * * generalCase() * .when(conditional-predicate).then(scalar-expression) * .when(conditional-predicate).then(scalar-expression) * ... * .elseCase(scalar-expression) * * @return empty general case expression */ CaseExpression generalCase(); /** * Create a simple case expression with * the given case operand. * A simple case expression is of the form: * * simpleCase(case-operand) * .when(scalar-expression).then(scalar-expression) * .when(scalar-expression).then(scalar-expression) * ... * .elseCase(scalar-expression) * * @param caseOperand - expression used for testing * against the when scalar expressions * @return case expression with the given case operand */ CaseExpression simpleCase(Expression caseOperand); /** * Create a simple case expression with * the given case operand. * A simple case expression is of the form: * * simpleCase(case-operand) * .when(scalar-expression).then(scalar-expression) * .when(scalar-expression).then(scalar-expression) * ... * .elseCase(scalar-expression) * * @param caseOperand - numeric value used for testing * against the when scalar expressions * @return case expression with the given case operand */ CaseExpression simpleCase(Number caseOperand);

10/31/08

154

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Criteria API Interfaces Java Persistence 2.0, Public Review Draft Criteria API

/** * Create a simple case expression with * the given case operand. * A simple case expression is of the form: * * simpleCase(case-operand) * .when(scalar-expression).then(scalar-expression) * .when(scalar-expression).then(scalar-expression) * ... * .elseCase(scalar-expression) * * @param caseOperand - value used for testing against * the when scalar expressions * @return case expression with the given case operand */ CaseExpression simpleCase(String caseOperand); /** * Create a simple case expression with * the given case operand. * A simple case expression is of the form: * * simpleCase(case-operand) * .when(scalar-expression).then(scalar-expression) * .when(scalar-expression).then(scalar-expression) * ... * .elseCase(scalar-expression) * * @param caseOperand - value used for testing against * the when scalar expressions * @return case expression with the given case operand */ CaseExpression simpleCase(Date caseOperand); /** * Create a simple case expression with * the given case operand. * A simple case expression is of the form: * * simpleCase(case-operand) * .when(scalar-expression).then(scalar-expression) * .when(scalar-expression).then(scalar-expression) * ... * .elseCase(scalar-expression) * * @param caseOperand - value used for testing against * the when scalar expressions * @return case expression with the given case operand */ CaseExpression simpleCase(Calendar caseOperand);

JSR-317 Public Review Draft

155

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Criteria API Interfaces

/** * Create a simple case expression with * the given case operand. * A simple case expression is of the form: * * simpleCase(case-operand) * .when(scalar-expression).then(scalar-expression) * .when(scalar-expression).then(scalar-expression) * ... * .elseCase(scalar-expression) * * @param caseOperand - value used for testing against * the when scalar expressions * @return case expression with the given case operand */ CaseExpression simpleCase(Class caseOperand); /** * Create a simple case expression with * the given case operand. * A simple case expression is of the form: * * simpleCase(case-operand) * .when(scalar-expression).then(scalar-expression) * .when(scalar-expression).then(scalar-expression) * ... * .elseCase(scalar-expression) * * @param caseOperand - value used for testing against * the when scalar expressions * @return case expression with the given case operand */ CaseExpression simpleCase(Enum<?> caseOperand); /** * coalesce * This is equivalent to a case expression that returns * null if all its arguments evaluate to null, and the * value of its first non-null argument otherwise. * @param exp - expressions to be used for testing * against null * @return Expression corresponding to the given * coalesce expression */ Expression coalesce(Expression... exp); /** * coalesce * This is equivalent to a case expression that returns * null if all its arguments evaluate to null, and the * value of its first non-null argument otherwise. * @param exp - expressions to be used for testing * against null * @return Expression corresponding to the given * coalesce expression */ Expression coalesce(String... exp);

10/31/08

156

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Criteria API Interfaces Java Persistence 2.0, Public Review Draft Criteria API

/** * coalesce * This is equivalent to a case expression that returns * null if all its arguments evaluate to null, and the * value of its first non-null argument otherwise. * @param exp - expressions to be used for testing * against null * @return Expression corresponding to the given * coalesce expression */ Expression coalesce(Date... exp); /** * coalesce * This is equivalent to a case expression that returns * null if all its arguments evaluate to null, and the * value of its first non-null argument otherwise. * @param exp - expressions to be used for testing * against null * @return Expression corresponding to the given * coalesce expression */ Expression coalesce(Calendar... exp); /** * nullif * This is equivalent to a case expression that tests * whether its arguments are equal, returning null * if they are and the value of the first expression * if they are not. * @param exp1 * @param exp2 * @return Expression corresponding to the given * nullif expression */ Expression nullif(Expression exp1, Expression exp2); /** * nullif * This is equivalent to a case expression that tests * whether its arguments are equal, returning null * if they are and the value of the first expression * if they are not. * @param arg1 * @param arg2 * @return Expression corresponding to the given * nullif expression */ Expression nullif(Number arg1, Number arg2); /** * nullif * This is equivalent to a case expression that tests * whether its arguments are equal, returning null * if they are and the value of the first expression * if they are not. * @param arg1 * @param arg2

JSR-317 Public Review Draft

157

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Criteria API Interfaces

* @return Expression corresponding to the given * nullif expression */ Expression nullif(String arg1, String arg2); /** * nullif * This is equivalent to a case expression that tests * whether its arguments are equal, returning null * if they are and the value of the first expression * if they are not. * @param arg1 * @param arg2 * @return Expression corresponding to the given * nullif expression */ Expression nullif(Date arg1, Date arg2); /** * nullif * This is equivalent to a case expression that tests * whether its arguments are equal, returning null * if they are and the value of the first expression * if they are not. * @param arg1 * @param arg2 * @return Expression corresponding to the given * nullif expression */ Expression nullif(Calendar arg1, Calendar arg2); /** * nullif * This is equivalent to a case expression that tests * whether its arguments are equal, returning null * if they are and the value of the first expression * if they are not. * @param arg1 * @param arg2 * @return Expression corresponding to the given * nullif expression */ Expression nullif(Class arg1, Class arg2); /** * nullif * This is equivalent to a case expression that tests * whether its arguments are equal, returning null * if they are and the value of the first expression * if they are not. * @param arg1 * @param arg2 * @return Expression corresponding to the given * nullif expression */ Expression nullif(Enum<?> arg1, Enum<?> arg2);

10/31/08

158

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Criteria API Interfaces Java Persistence 2.0, Public Review Draft Criteria API

/** * Create a predicate value from the given boolean. * @param b boolean value * @return a true or false predicate */ Predicate predicate(boolean b); /** * Create an Expression corresponding to the current time * on the database server at the time of query execution. * @return the corresponding Expression */ Expression currentTime(); /** * Create an Expression corresponding to the current date * on the database server at the time of query execution. * @return the corresponding Expression */ Expression currentDate(); /** * Create an Expression corresponding to the current timestamp * on the database server at the time of query execution. * @return the corresponding Expression */ Expression currentTimestamp(); /** * Create an Expression corresponding to a String value. * @param s - string value * @return the corresponding Expression literal */ Expression literal(String s); /** * Create an Expression corresponding to a numeric value. * @param n - numeric value * @return the corresponding Expression literal */ Expression literal(Number n); /** * Create an Expression corresponding to a boolean value. * @param b - boolean value * @return the corresponding Expression literal */ Expression literal(boolean b); /** * Create an Expression corresponding to a Calendar value. * @param c - Calendar value * @return the corresponding Expression literal */ Expression literal(Calendar c);

JSR-317 Public Review Draft

159

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Criteria API Interfaces

/** * Create an Expression corresponding to a Date value. * @param d - Date value * @return the corresponding Expression literal */ Expression literal(Date d); /** * Create an Expression corresponding to a character value. * @param character value * @return the corresponding Expression literal */ Expression literal(char c); /** * Create an Expression corresponding to an entity class. * @param cls - entity class * @return the corresponding Expression literal */ Expression literal(Class cls); /** * Create an Expression corresponding to an enum. * @param e - enum * @return the corresponding Expression literal */ Expression literal(Enum<?> e); /** * Create an Expression corresponding to a null value. * @return the corresponding Expression literal */ Expression nullLiteral(); /** * Specify use of a parameter of the given name. * @param parameter name * @return an Expression corresponding to a named parameter */ Expression param(String name); }

5.2.3 Subquery Interface


package javax.persistence; /** * Instances of this interface can be used as subqueries. */ public interface Subquery extends PredicateOperand {}

10/31/08

160

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Criteria API Interfaces Java Persistence 2.0, Public Review Draft Criteria API

5.2.4 DomainObject Interface


package javax.persistence; /** * Domain objects define the domain over which a query operates. * A domain object plays a role analogous to that of a Java * Persistence query language identification variable. */ public interface DomainObject extends PathExpression, QueryDefinition { /** * Extend the query domain by joining with a class that can be * navigated to or that is embedded in the class corresponding * to the domain object on which the method is invoked. * This method is permitted to be invoked only when defining the * domain of the query. It must not be invoked within the * context of the select, where, groupBy, or having operations. * The domain object must correspond to a class that contains * the referenced attribute. * The query definition is modified to include the newly joined * domain object. * @param attribute - name of the attribute that references * the target of the join * @return the new DomainObject that is added for the target * of the join */ DomainObject join(String attribute); /** * Extend the query domain by left outer joining with a class * that can be navigated to or that is embedded in the class * corresponding to the domain object on which the method is * invoked. * This method is permitted to be invoked only when defining the * domain of the query. It must not be invoked within the * context of the select, where, groupBy, or having operations. * The domain object must correspond to a class that contains * the referenced attribute. * The query definition is modified to include the newly joined * domain object. * @param attribute - name of the attribute that references * the target of the join * @return the new DomainObject that is added for the target of the join */ DomainObject leftJoin(String attribute);

JSR-317 Public Review Draft

161

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Criteria API Interfaces

/** * Specify that the association or element collection that is * referenced by the attribute be eagerly fetched through use of * an inner join. * The domain object must correspond to a class that contains * the referenced attribute. * The query is modified to include the joined domain object. * @param attribute - name of the attribute that references * the target of the join * @return the FetchJoinObject that is added for the target * of the join */ FetchJoinObject joinFetch(String attribute); /** * Specify that the association or element collection that is * referenced by the attribute be eagerly fetched through use * of a left outer join. * The domain object must correspond to a class that contains * the referenced attribute. * The query is modified to include the joined domain object. * @param attribute - name of the attribute that references * the target of the join * @return the FetchJoinObject that is added for the target * of the join */ FetchJoinObject leftJoinFetch(String attribute); /** * Return a path expression corresponding to the value of * a map-valued association or element collection. * This method is only permitted to be invoked upon a domain * object that corresponds to a map-valued association or * element collection. * @return PathExpression corresponding to the map value */ PathExpression value(); /** * Return a path expression corresponding to the key of * a map-valued association or element collection. * This method is only permitted to be invoked upon a domain * object that corresponds to a map-valued association or * element collection. * @return PathExpression corresponding to the map key */ PathExpression key(); /** * Return a select item corresponding to the map entry of a * map-valued association or element collection. * This method is only permitted to be invoked upon a domain * object that corresponds to a map-valued association or * element collection. * @return SelectItem corresponding to the map entry */ SelectItem entry();

10/31/08

162

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Criteria API Interfaces Java Persistence 2.0, Public Review Draft Criteria API

/** * Return an expression that corresponds to the index. * of the domain object in the referenced association or * element collection. * This method is only permitted to be invoked upon a domain * object that corresponds to a multi-valued association or * element collection for which an order column has been * defined. * @return Expression denoting the index */ Expression index(); }

5.2.5 FetchJoinObject Interface


package javax.persistence; /** * Interface used for the result of a fetch join. */ public interface FetchJoinObject { } Open Issue: Should methods be added to this interface to support multiple levels of fetch joins?

5.2.6 PathExpression Interface


package javax.persistence; /** * Interface for operations over objects reached via paths */ public interface PathExpression extends Expression { /** * Return a path expression corresponding to the referenced * attribute. * It is not permitted to invoke this method on a path * expression that corresponds to a multi-valued association * or element collection. * The path expression on which this method is invoked must * correspond to a class containing the referenced attribute. * @param attributeName - name of the referenced attribute * @return path expression */ PathExpression get(String attributeName);

JSR-317 Public Review Draft

163

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Criteria API Interfaces

/** * Return an expression that corresponds to the type * of the entity. * This method can only be invoked on a path expression * corresponding to an entity. * It is not permitted to invoke this method on a path * expression that corresponds to a multi-valued association. * @return expression denoting the entity's type */ Expression type(); /** * Return an expression that corresponds to the number * of elements association or element collection corresponding * to the path expression. * This method can only be invoked on a path expression that * corresponds to a multi-valued association or to an element * collection. * @return expression denoting the size */ Expression size(); /** * Add a restriction that the path expression must correspond * to an association or element collection that is empty (has * no elements). * This method can only be invoked on a path expression that * corresponds to a multi-valued association or to an element * collection. * @return predicate corresponding to the restriction */ Predicate isEmpty(); /** * Specify that the avg operation is to be applied. * The path expression must correspond to an attribute of a * numeric type. * It is not permitted to invoke this method on a path * expression that corresponds to a multi-valued association * or element collection. * @return the resulting aggregate */ Aggregate avg(); /** * Specify that the max operation is to be applied. * The path expression must correspond to an attribute of * an orderable type. * It is not permitted to invoke this method on a path * expression that corresponds to a multi-valued association * or element collection. * @return the resulting aggregate */ Aggregate max();

10/31/08

164

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Criteria API Interfaces Java Persistence 2.0, Public Review Draft Criteria API

/** * Specify that the min operation is to be applied. * The path expression must correspond to an attribute of * an orderable type. * It is not permitted to invoke this method on a path * expression that corresponds to a multi-valued association * or element collection. * @return the resulting aggregate */ Aggregate min(); /** * Specify that the count operation is to be applied. * It is not permitted to invoke this method on a path * expression that corresponds to a multi-valued association * or element collection. * @return the resulting aggregate */ Aggregate count(); /** * Specify that the sum operation is to be applied. * The path expression must correspond to an attribute of * a numeric type. * It is not permitted to invoke this method on a path * expression that corresponds to a multi-valued association * or element collection. * @return the resulting aggregate */ Aggregate sum(); }

5.2.7 PredicateOperand Interface


package javax.persistence; import java.util.Date; import java.util.Calendar; /** * Interface for constructing where-clause and having-clause * conditions. * Instances of PredicateOperand are used in constructing predicates * passed to the where or having methods. */ public interface PredicateOperand {

/** * Create a predicate for testing equality with the * specified argument. * @param arg - PredicateOperand instance or parameter * @return conditional predicate */ Predicate equal(PredicateOperand arg);

JSR-317 Public Review Draft

165

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Criteria API Interfaces

/** * Create a predicate for testing equality with the * specified argument. * @param cls - entity class * @return conditional predicate */ Predicate equal(Class cls); /** * Create a predicate for testing equality with the * specified argument. * @param arg - numeric * @return conditional predicate */ Predicate equal(Number arg); /** * Create a predicate for testing equality with the * specified argument. * @param arg - string value * @return conditional predicate */ Predicate equal(String arg); /** * Create a predicate for testing equality with the * specified argument. * @param arg - boolean value * @return conditional predicate */ Predicate equal(boolean arg); /** * Create a predicate for testing equality with the * specified argument. * @param arg - date * @return conditional predicate */ Predicate equal(Date arg); /** * Create a predicate for testing equality with the * specified argument. * @param arg - calendar * @return conditional predicate */ Predicate equal(Calendar arg); /** * Create a predicate for testing equality with the * specified argument. * @param e - enum * @return conditional predicate */ Predicate equal(Enum<?> e);

10/31/08

166

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Criteria API Interfaces Java Persistence 2.0, Public Review Draft Criteria API

/** * Create a predicate for testing inequality with the * specified argument. * @param arg - PredicateOperand instance or parameter * @return conditional predicate */ Predicate notEqual(PredicateOperand arg); /** * Create a predicate for testing inequality with the * specified argument. * @param cls - entity class * @return conditional predicate */ Predicate notEqual(Class cls); /** * Create a predicate for testing inequality with the * specified argument. * @param arg - numberic value * @return conditional predicate */ Predicate notEqual(Number arg); /** * Create a predicate for testing inequality with the * specified argument. * @param arg - string value * @return conditional predicate */ Predicate notEqual(String arg); /** * Create a predicate for testing inequality with the * specified argument. * @param arg - boolean value * @return conditional predicate */ Predicate notEqual(boolean arg); /** * Create a predicate for testing inequality with the * specified argument. * @param arg - date * @return conditional predicate */ Predicate notEqual(Date arg); /** * Create a predicate for testing inequality with the * specified argument. * @param arg - calendar * @return conditional predicate */ Predicate notEqual(Calendar arg);

JSR-317 Public Review Draft

167

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Criteria API Interfaces

/** * Create a predicate for testing inequality with the * specified argument. * @param e - enum * @return conditional predicate */ Predicate notEqual(Enum<?> e); /** * Create a predicate for testing whether the PredicateOperand * is greater than the argument. * @param arg - PredicateOperand instance or parameter * @return conditional predicate */ Predicate greaterThan(PredicateOperand arg); /** * Create a predicate for testing whether the PredicateOperand * is greater than the argument. * @param arg - numeric * @return conditional predicate */ Predicate greaterThan(Number arg); /** * Create a predicate for testing whether the PredicateOperand * is greater than the argument. * @param arg - string * @return conditional predicate */ Predicate greaterThan(String arg); /** * Create a predicate for testing whether the PredicateOperand * is greater than the argument. * @param arg - date * @return conditional predicate */ Predicate greaterThan(Date arg); /** * Create a predicate for testing whether the PredicateOperand * is greater than the argument. * @param arg - calendar * @return conditional predicate */ Predicate greaterThan(Calendar arg); /** * Create a predicate for testing whether the PredicateOperand * is greater than or equal to the argument. * @param arg - PredicateOperand instance or parameter * @return conditional predicate */ Predicate greaterEqual(PredicateOperand arg);

10/31/08

168

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Criteria API Interfaces Java Persistence 2.0, Public Review Draft Criteria API

/** * Create a predicate for testing whether the PredicateOperand * is greater than or equal to the argument. * @param arg - numeric * @return conditional predicate */ Predicate greaterEqual(Number arg); /** * Create a predicate for testing whether the PredicateOperand * is greater than or equal to the argument. * @param arg - string * @return conditional predicate */ Predicate greaterEqual(String arg); /** * Create a predicate for testing whether the PredicateOperand * is greater than or equal to the argument. * @param arg - date * @return conditional predicate */ Predicate greaterEqual(Date arg); /** * Create a predicate for testing whether the PredicateOperand * is greater than or equal to the argument. * @param arg - calendar * @return conditional predicate */ Predicate greaterEqual(Calendar arg); /** * Create a predicate for testing whether the PredicateOperand * is less than the argument. * @param arg - PredicateOperand instance or parameter * @return conditional predicate */ Predicate lessThan(PredicateOperand arg); /** * Create a predicate for testing whether the PredicateOperand * is less than the argument. * @param arg - numeric * @return conditional predicate */ Predicate lessThan(Number arg); /** * Create a predicate for testing whether the PredicateOperand * is less than the argument. * @param arg - string * @return conditional predicate */ Predicate lessThan(String arg);

JSR-317 Public Review Draft

169

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Criteria API Interfaces

/** * Create a predicate for testing whether the PredicateOperand * is less than the argument. * @param arg - date * @return conditional predicate */ Predicate lessThan(Date arg); /** * Create a predicate for testing whether the PredicateOperand * is less than the argument. * @param arg - calendar * @return conditional predicate */ Predicate lessThan(Calendar arg); /** * Create a predicate for testing whether the PredicateOperand * is less than or equal to the argument. * @param arg - PredicateOperand instance or parameter * @return conditional predicate */ Predicate lessEqual(PredicateOperand arg); /** * Create a predicate for testing whether the PredicateOperand * is less than or equal to the argument. * @param arg - numeric * @return conditional predicate */ Predicate lessEqual(Number arg); /** * Create a predicate for testing whether the PredicateOperand * is less than or equal to the argument. * @param arg - string * @return conditional predicate */ Predicate lessEqual(String arg); /** * Create a predicate for testing whether the PredicateOperand * is less than or equal to the argument. * @param arg - date * @return conditional predicate */ Predicate lessEqual(Date arg); /** * Create a predicate for testing whether the PredicateOperand * is less than or equal to the argument. * @param arg - calendar * @return conditional predicate */ Predicate lessEqual(Calendar arg);

10/31/08

170

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Criteria API Interfaces Java Persistence 2.0, Public Review Draft Criteria API

/** * Create a predicate for testing whether the PredicateOperand * lies between (inclusive) the two arguments. * @param arg1 - PredicateOperand instance or parameter * @param arg2 - PredicateOperand instance or parameter * @return conditional predicate */ Predicate between(PredicateOperand arg1, PredicateOperand arg2); /** * Create a predicate for testing whether the PredicateOperand * lies between (inclusive) the two arguments. * @param arg1 - PredicateOperand instance or parameter * @param arg2 - numeric * @return conditional predicate */ Predicate between(PredicateOperand arg1, Number arg2); /** * Create a predicate for testing whether the PredicateOperand * lies between (inclusive) the two arguments. * @param arg1 - numeric * @param arg2 - PredicateOperand instance or parameter * @return conditional predicate */ Predicate between(Number arg1, PredicateOperand arg2); /** * Create a predicate for testing whether the PredicateOperand * lies between (inclusive) the two arguments. * @param arg1 - numeric * @param arg2 - numeric * @return conditional predicate */ Predicate between(Number arg1, Number arg2); /** * Create a predicate for testing whether the PredicateOperand * lies between (inclusive) the two arguments. * @param arg1 - PredicateOperand instance or parameter * @param arg2 - string * @return conditional predicate */ Predicate between(PredicateOperand arg1, String arg2); /** * Create a predicate for testing whether the PredicateOperand * lies between (inclusive) the two arguments. * @param arg1 - string * @param arg2 - PredicateOperand instance or parameter * @return conditional predicate */ Predicate between(String arg1, PredicateOperand arg2);

JSR-317 Public Review Draft

171

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Criteria API Interfaces

/** * Create a predicate for testing whether the PredicateOperand * lies between (inclusive) the two arguments. * @param arg1 - string * @param arg2 - string * @return conditional predicate */ Predicate between(String arg1, String arg2); /** * Create a predicate for testing whether the PredicateOperand * lies between (inclusive) the two arguments. * @param arg1 - PredicateOperand instance or parameter * @param arg2 - date * @return conditional predicate */ Predicate between(PredicateOperand arg1, Date arg2); /** * Create a predicate for testing whether the PredicateOperand * lies between (inclusive) the two arguments. * @param arg1 - date * @param arg2 - PredicateOperand instance or parameter * @return conditional predicate */ Predicate between(Date arg1, PredicateOperand arg2); /** * Create a predicate for testing whether the PredicateOperand * lies between (inclusive) the two arguments. * @param arg1 - date * @param arg2 - date * @return conditional predicate */ Predicate between(Date arg1, Date arg2); /** * Create a predicate for testing whether the PredicateOperand * lies between (inclusive) the two arguments. * @param arg1 - PredicateOperand instance or parameter * @param arg2 - calendar * @return conditional predicate */ Predicate between(PredicateOperand arg1, Calendar arg2); /** * Create a predicate for testing whether the PredicateOperand * lies between (inclusive) the two arguments. * @param arg1 - calendar * @param arg2 - PredicateOperand instance or parameter * @return conditional predicate */ Predicate between(Calendar arg1, PredicateOperand arg2);

10/31/08

172

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Criteria API Interfaces Java Persistence 2.0, Public Review Draft Criteria API

/** * Create a predicate for testing whether the PredicateOperand * lies between (inclusive) the two arguments. * @param arg1 - calendar * @param arg2 - calendar * @return conditional predicate */ Predicate between(Calendar arg1, Calendar arg2); /** * Create a predicate for testing whether the PredicateOperand * satisfies the given pattern. * @param pattern * @return conditional predicate */ Predicate like(PredicateOperand pattern); /** * Create a predicate for testing whether the PredicateOperand * satisfies the given pattern. * @param pattern * @param escapeChar * @return conditional predicate */ Predicate like(PredicateOperand pattern, PredicateOperand escapeChar); /** * Create a predicate for testing whether the PredicateOperand * satisfies the given pattern. * @param pattern * @param escapeChar * @return conditional predicate */ Predicate like(PredicateOperand pattern, char escapeChar); /** * Create a predicate for testing whether the PredicateOperand * satisfies the given pattern. * @param pattern * @return conditional predicate */ Predicate like(String pattern); /** * Create a predicate for testing whether the PredicateOperand * satisfies the given pattern. * @param pattern * @param escapeChar * @return conditional predicate */ Predicate like(String pattern, PredicateOperand escapeChar);

JSR-317 Public Review Draft

173

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Criteria API Interfaces

/** * Create a predicate for testing whether the PredicateOperand * satisfies the given pattern. * @param pattern * @param escapeChar * @return conditional predicate */ Predicate like(String pattern, char escapeChar); }

5.2.8 Predicate Interface


package javax.persistence; /** * Interface used to define compound predicates. */ public interface Predicate { /** * Creates an AND of the predicate with the argument. * @param predicate - A simple or compound predicate * @return the predicate that is the AND of the original * simple or compound predicate and the argument. */ Predicate and(Predicate predicate); /** * Creates an OR of the predicate with the * @param predicate - A simple or compound * @return the predicate that is the OR of * simple or compound predicate and */ Predicate or(Predicate predicate); argument. predicate the original the argument.

/** * Creates a negation of the predicate with the argument. * @return the predicate that is the negation of the * original simple or compound predicate. */ Predicate not(); }

10/31/08

174

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Criteria API Interfaces Java Persistence 2.0, Public Review Draft Criteria API

5.2.9 Expression Interface


package javax.persistence; /** * Instances of this interface can be used either as select list * items or as predicate operands. */ public interface Expression extends SelectItem, PredicateOperand { /* * Conditional predicates over expression items */ /** * Create a predicate for testing whether the expression * is a member of the association or element collection * denoted by the path expression. * The argument must correspond to a collection-valued * association or element collection of like type. * @param arg - a path expression that specifies a * collection-valued association or an element * collection * @return conditional predicate */ Predicate member(PathExpression arg); /** * Create a predicate for testing whether the value of * the expression is null. * @return conditional predicate */ Predicate isNull(); /** * Create a predicate for testing whether the expression * value is a member of the argument list. * @param strings * @return conditional predicate */ Predicate in(String... strings); /** * Create a predicate for testing whether the expression * value is a member of the argument list. * @param nums * @return conditional predicate */ Predicate in(Number... nums); /** * Create a predicate for testing whether the expression * value is a member of the argument list. * @param enums * @return conditional predicate */ Predicate in(Enum<?>... enums);

JSR-317 Public Review Draft

175

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Criteria API Interfaces

/** * Create a predicate for testing whether the expression * value is a member of the argument list. * @param classes * @return conditional predicate */ Predicate in(Class... classes); /** * Create a predicate for testing whether the expression * value is a member of the argument list. * @param params * @return conditional predicate */ Predicate in(Expression... params); /** * Create a predicate for testing whether the expression * value is a member of a subquery result. * @param subquery * @return conditional predicate */ Predicate in(Subquery subquery); /* * Operations on strings */ /** * String length * This method must be invoked on an expression corresponding * to a string. * @return expression denoting the length of the string. */ Expression length(); /** * Concatenate a string with other string(s). * This method must be invoked on an expression corresponding * to a string. * @param str - string(s) * @return expression denoting the concatenation of the strings, * starting with the string corresponding to the * expression on which the method was invoked. */ Expression concat(String... str); /** * Concatenate a string with other string(s). * This method must be invoked on an expression corresponding * to a string. * @param str - expression(s) corresponding to string(s) * @return expression denoting the concatenation of the * strings, starting with the string corresponding * to the expression on which the method was invoked. */ Expression concat(Expression... str);

10/31/08

176

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Criteria API Interfaces Java Persistence 2.0, Public Review Draft Criteria API

/** * Extract a substring starting at specified position through * to the end of the string. * This method must be invoked on an expression corresponding * to a string. * @param start - start position (1 indicates first position) * @return expression denoting the extracted substring */ Expression substring(int start); /** * Extract a substring starting at specified position through * to the end of the string. * This method must be invoked on an expression corresponding * to a string. * @param start - expression denoting start position * (1 indicates first position) * @return expression denoting the extracted substring */ Expression substring(Expression start); /** * Extract a substring. * This method must be invoked on an expression corresponding * to a string. * @param start - start position (1 indicates first position) * @param len - length of the substring to be returned * @return expression denoting the extracted substring */ Expression substring(int start, int len); /** * Extract a substring. * This method must be invoked on an expression corresponding * to a string. * @param start - start position (1 indicates first position) * @param len - expression denoting length of the substring * to return * @return expression denoting the extracted substring */ Expression substring(int start, Expression len); /** * Extract a substring. * This method must be invoked on an expression corresponding * to a string. * @param start - expression denoting start position * (1 indicates first position) * @param len - length of the substring to return * @return expression denoting the extracted substring */ Expression substring(Expression start, int len);

JSR-317 Public Review Draft

177

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Criteria API Interfaces

/** * Extract a substring. * This method must be invoked on an expression corresponding * to a string. * @param start - expression denoting start position * (1 indicates first position) * @param len - expression denoting length of the substring * to return * @return expression denoting the extracted substring */ Expression substring(Expression start, Expression len); /** * Convert string to lowercase. * This method must be invoked on an expression corresponding * to a string. * @return expression denoting the string in lowercase */ Expression lower(); /** * Convert string to uppercase. * This method must be invoked on an expression corresponding * to a string. * @return expression denoting the string in uppercase */ Expression upper(); /** * Trim leading and trailing blanks. * This method must be invoked on an expression corresponding * to a string. * @return expression denoting trimmed string */ Expression trim(); /** * Trim leading, trailing blanks (or both) as specified * by trim spec. * This method must be invoked on an expression corresponding * to a string. * @param spec - trim specification * @return expression denoting trimmed string */ Expression trim(TrimSpec spec); /** * Trim leading and trailing occurrences of character from the * string. * This method must be invoked on an expression corresponding * to a string. * @param c - character to be trimmed * @return expression denoting trimmed string */ Expression trim(char c);

10/31/08

178

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Criteria API Interfaces Java Persistence 2.0, Public Review Draft Criteria API

/** * Trim occurrences of the character from leading or trailing * (or both) positions of the string, as specified by trim spec. * This method must be invoked on an expression corresponding * to a string. * @param c - character to be trimmed * @param spec - trim specification * @return expression denoting trimmed string */ Expression trim(char c, TrimSpec spec); /** * Trim leading and trailing occurrences of character specified * by the expression argument from the string. * This method must be invoked on an expression corresponding * to a string. * @param expr - expression corresponding to the character * to be trimmed * @return expression denoting trimmed string */ Expression trim(Expression expr); /** * Trim occurrences of the character specified by the * expression argument from leading or trailing (or both) * positions of the string, as specified by trim spec. * This method must be invoked on an expression corresponding * to a string. * @param expr - expression corresponding to the character * to be trimmed * @param spec - trim specification * @return expression denoting trimmed string */ Expression trim(Expression expr, TrimSpec spec); /** * Locate a string contained within the string corresponding * to the expression on which the method was invoked. * The search is started at position 1 (first string position). * This method must be invoked on an expression corresponding * to a string. * @param str - string to be located * @return expression denoting the first position at which * the string was found or expression denoting 0 if * the string was not found */ Expression locate(String str);

JSR-317 Public Review Draft

179

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Criteria API Interfaces

/** * Locate a string contained within the string corresponding * to the expression on which the method was invoked. * The search is started at position 1 (first string position). * This method must be invoked on an expression corresponding * to a string. * @param str - expression corresponding to the string to be * located * @return expression denoting the first position at which * the string was found or expression denoting 0 if * the string was not found */ Expression locate(Expression str); /** * Locate a string contained within the string corresponding * to the expression on which the method was invoked, * starting at a specified search position. * This method must be invoked on an expression corresponding * to a string. * @param str - string to be located * @param position - position at which to start the search * @return expression denoting the first position at which * the string was found or expression denoting 0 if * the string was not found */ Expression locate(String str, int position); /** * Locate a string contained within the string corresponding * to the expression on which the method was invoked, * starting at a specified search position. * This method must be invoked on an expression corresponding * to a string. * @param str - string to be located * @param position - expression corresponding to position at * which to start the search * @return expression denoting the first position at which * the string was found or expression denoting 0 if * the string was not found */ Expression locate(String str, Expression position); /** * Locate a string contained within the string corresponding * to the expression on which the method was invoked, * starting at a specified search position. * This method must be invoked on an expression corresponding * to a string. * @param str - expression corresponding to the string to be * located * @param position - position at which to start the search * @return expression denoting the first position at which * the string was found or expression denoting 0 if * the string was not found */ Expression locate(Expression str, int position);

10/31/08

180

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Criteria API Interfaces Java Persistence 2.0, Public Review Draft Criteria API

/** * Locate a string contained within the string corresponding * to the expression on which the method was invoked, * starting at a specified search position. * This method must be invoked on an expression corresponding * to a string. * @param str - expression corresponding to the string to be * located * @param position - expression corresponding to position at * which to start the search * @return expression denoting the first position at which * the string was found or expression denoting 0 if * the string was not found */ Expression locate(Expression str, Expression position); /* * Arithmetic operations */ /** * Addition. * This method must be invoked on an expression corresponding * to a number. * @param num - number to be added * @return expression denoting the sum */ Expression plus(Number num); /** * Addition. * This method must be invoked on an expression corresponding * to a number. * @param expr - expression corresponding to number to be added * @return expression denoting the sum */ Expression plus(Expression expr); /** * Unary minus. * This method must be invoked on an expression corresponding * to a number. * @return expression denoting the unary minus of the expression */ Expression minus(); /** * Subtraction. * This method must be invoked on an expression corresponding * to a number. * @param num - subtrahend * @return expression denoting the result of subtracting the * argument from the number corresponding to the * expression on which the method was invoked. */ Expression minus(Number num);

JSR-317 Public Review Draft

181

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Criteria API Interfaces

/** * Subtraction. * This method must be invoked on an expression corresponding * to a number. * @param expr - expression corresponding to subtrahend * @return expression denoting the result of subtracting the * number denoted by the argument from the number * corresponding to the expression on which the * method was invoked. */ Expression minus(Expression expr); /** * Division. * This method must be invoked on an expression corresponding * to a number. * @param num - divisor * @return expression denoting the result of dividing * the number corresponding to the expression on * which the method was invoked by the argument */ Expression dividedBy(Number num); /** * Division. * This method must be invoked on an expression corresponding * to a number. * @param expr - expression corresponding to the divisor * @return expression denoting the result of dividing * the number corresponding to the expression on * which the method was invoked by the number denoted * by the argument */ Expression dividedBy(Expression expr); /** * Multiplication. * This method must be invoked on an expression corresponding * to a number. * @param num - multiplier * @return expression denoting the result of multiplying the * argument with the number corresponding to the * expression on which the method was invoked. */ Expression times(Number num); /** * Multiplication. * This method must be invoked on an expression corresponding * to a number. * @param expr - expression corresponding to the multiplier * @return expression denoting the result of multiplying the * number denoted by the argument with the number * corresponding to the expression on which the * method was invoked. */ Expression times(Expression expr);

10/31/08

182

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Criteria API Interfaces Java Persistence 2.0, Public Review Draft Criteria API

/** * Absolute value. * This method must be invoked on an expression corresponding * to a number. * @return expression corresponding to the absolute value */ Expression abs(); /** * Square root. * This method must be invoked on an expression corresponding * to a number. * @return expression corresponding to the square root */ Expression sqrt(); /** * Modulo operation. * This must be invoked on an expression corresponding to * an integer value * @param num - integer divisor * @return expression corresponding to the integer remainder * of the division of the integer corresponding to * the expression on which the method was invoked * by the argument. */ Expression mod(int num); /** * Modulo operation. * This must be invoked on an expression corresponding to * an integer value * @param expr - expression corresponding to integer divisor * @return expression corresponding to the integer remainder * of the division of the integer corresponding to * the expression on which the method was invoked * by the argument. */ Expression mod(Expression expr); }

5.2.10 TrimSpec Enum


package javax.persistence; /** * Used to specify the trimming of strings */ public enum TrimSpec { LEADING, TRAILING, BOTH }

JSR-317 Public Review Draft

183

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Criteria API Interfaces

5.2.11 CaseExpression Interface


package javax.persistence; import java.util.Date; import java.util.Calendar; /** * Interface for the construction of case expressions */ public interface CaseExpression { /** * Add a when predicate clause to a general case expression. * The when predicate must be followed by the corresponding * then case expression that specifies the result of the * specific case. * Clauses are evaluated in the order added. * @param pred - corresponds to the evaluation condition * for the specific case * @return CaseExpression corresponding to the case * with the added when clause */ CaseExpression when(Predicate pred); /** * Add a when clause to a simple case expression. * The when case expression must be followed by the * corresponding then case expression that specifies the * result of the specific case. * Clauses are evaluated in the order added * @param when - corresponds to the value against which * the case operand of the simple case is tested * @return CaseExpression corresponding to the case * with the added clause */ CaseExpression when(Expression when); /** * Add a when clause to a simple case expression. * The when case expression must be followed by the * corresponding then case expression that specifies the * result of the specific case. * Clauses are evaluated in the order added * @param when - corresponds to the value against which * the case operand of the simple case is tested * @return CaseExpression corresponding to the case * with the added clause */ CaseExpression when(Number when); /** * Add a when clause to a simple case expression. * The when case expression must be followed by the * corresponding then case expression that specifies the * result of the specific case. * Clauses are evaluated in the order added * @param when - corresponds to the value against which
10/31/08

184

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Criteria API Interfaces Java Persistence 2.0, Public Review Draft Criteria API

* the case operand of the simple case is tested * @return CaseExpression corresponding to the case * with the added clause */ CaseExpression when(String when); /** * Add a when clause to a simple case expression. * The when case expression must be followed by the * corresponding then case expression that specifies the * result of the specific case. * Clauses are evaluated in the order added * @param when - corresponds to the value against which * the case operand of the simple case is tested * @return CaseExpression corresponding to the case * with the added clause */ CaseExpression when(Date when); /** * Add a when clause to a simple case expression. * The when case expression must be followed by the * corresponding then case expression that specifies the * result of the specific case. * Clauses are evaluated in the order added * @param when - corresponds to the value against which * the case operand of the simple case is tested * @return CaseExpression corresponding to the case * with the added clause */ CaseExpression when(Calendar when); /** * Add a when clause to a simple case expression. * The when case expression must be followed by the * corresponding then case expression that specifies the * result of the specific case. * Clauses are evaluated in the order added * @param when - corresponds to the value against which * the case operand of the simple case is tested * @return CaseExpression corresponding to the case * with the added clause */ CaseExpression when(Class when); /** * Add a when clause to a simple case expression. * The when case expression must be followed by the * corresponding then case expression that specifies the * result of the specific case. * Clauses are evaluated in the order added * @param when - corresponds to the value against which * the case operand of the simple case is tested * @return CaseExpression corresponding to the case * with the added clause */ CaseExpression when(Enum<?> when);

JSR-317 Public Review Draft

185

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Criteria API Interfaces

/** * Add a then clause to a general or simple case expression. * The then clause specifies the result corresponding to * the immediately preceding when. * Clauses are evaluated in the order added. * @param then - corresponds to the result of the case * expression if the when is satisfied * @return CaseExpression corresponding to the case * with the added then clause */ CaseExpression then(Expression then); /** * Add a then clause to a general or simple case expression. * The then clause specifies the result corresponding to * the immediately preceding when. * Clauses are evaluated in the order added. * @param then - corresponds to the result of the case * expression if the when is satisfied * @return CaseExpression corresponding to the case * with the added then clause */ CaseExpression then(Number then); /** * Add a then clause to a general or simple case expression. * The then clause specifies the result corresponding to * the immediately preceding when. * Clauses are evaluated in the order added. * @param then - corresponds to the result of the case * expression if the when is satisfied * @return CaseExpression corresponding to the case * with the added then clause */ CaseExpression then(String then); /** * Add a then clause to a general or simple case expression. * The then clause specifies the result corresponding to * the immediately preceding when. * Clauses are evaluated in the order added. * @param then - corresponds to the result of the case * expression if the when is satisfied * @return CaseExpression corresponding to the case * with the added then clause */ CaseExpression then(Date then); /** * Add a then clause to a general or simple case expression. * The then clause specifies the result corresponding to * the immediately preceding when. * Clauses are evaluated in the order added. * @param then - corresponds to the result of the case * expression if the when is satisfied * @return CaseExpression corresponding to the case * with the added then clause */ CaseExpression then(Calendar then);

10/31/08

186

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Criteria API Interfaces Java Persistence 2.0, Public Review Draft Criteria API

/** * Add a then clause to a general or simple case expression. * The then clause specifies the result corresponding to * the immediately preceding when. * Clauses are evaluated in the order added. * @param then - corresponds to the result of the case * expression if the when is satisfied * @return CaseExpression corresponding to the case * with the added then clause */ CaseExpression then(Class then); /** * Add a then clause to a general or simple case expression. * The then clause specifies the result corresponding to * the immediately preceding when. * Clauses are evaluated in the order added. * @param then - corresponds to the result of the case * expression if the when is satisfied * @return CaseExpression corresponding to the case * with the added then clause */ CaseExpression then(Enum<?> then); /** * Add else to a case expression. * A case expression must have an else clause. * @param arg - corresponds to the result of the case * expression if the when condition is * not satisfied * @return Expression corresponding to the case expression * with the added clause */ Expression elseCase(Expression arg); /** * Add else to a case expression. * A case expression must have an else clause. * @param arg - corresponds to the result of the case * expression if the when condition is * not satisfied * @return Expression corresponding to the case expression * with the added clause */ Expression elseCase(String arg); /** * Add else to a case expression. * A case expression must have an else clause. * @param arg - corresponds to the result of the case * expression if the when condition is * not satisfied * @return Expression corresponding to the case expression * with the added clause */ Expression elseCase(Number arg);

JSR-317 Public Review Draft

187

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Criteria API Interfaces

/** * Add else to a case expression. * A case expression must have an else clause. * @param arg - corresponds to the result of the case * expression if the when condition is * not satisfied * @return Expression corresponding to the case expression * with the added clause */ Expression elseCase(Date arg); /** * Add else to a case expression. * A case expression must have an else clause. * @param arg - corresponds to the result of the case * expression if the when condition is * not satisfied * @return Expression corresponding to the case expression * with the added clause */ Expression elseCase(Calendar arg); /** * Add else to a case expression. * A case expression must have an else clause. * @param arg - corresponds to the result of the case * expression if the when condition is * not satisfied * @return Expression corresponding to the case expression * with the added clause */ Expression elseCase(Class arg); /** * Add else to a case expression. * A case expression must have an else clause. * @param arg - corresponds to the result of the case * expression if the when condition is * not satisfied * @return Expression corresponding to the case expression * with the added clause */ Expression elseCase(Enum<?> arg); }

10/31/08

188

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Criteria API Interfaces Java Persistence 2.0, Public Review Draft Criteria API

5.2.12 Aggregate Interface


package javax.persistence; /** * Type of the result of an aggregate operation */ public interface Aggregate extends Expression { /** * Specify that duplicates are to be removed before * the aggregate operation is invoked. */ Expression distinct(); }

5.2.13 SelectItem Interface


package javax.persistence; /** * * * * * * */ SelectItem instances are used in specifying the query's select list. The methods of this interface are used to define arguments that can be passed to the orderBy method for use in ordering selected items of the query result.

public interface SelectItem extends OrderByItem { /** * Return an OrderByItem referencing the SelectItem and * specifying ascending ordering. * The SelectItem must correspond to an orderable value. * @return order-by item */ OrderByItem asc(); /** * Return an OrderByItem referencing the SelectItem and * specifying descending ordering. * The SelectItem must correspond to an orderable value. * @return order-by item */ OrderByItem desc(); }

JSR-317 Public Review Draft

189

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Query Construction

5.2.14 OrderByItem Interface


package javax.persistence; /** * Instances of this interface can be used as orderBy arguments. */ public interface OrderByItem { }

5.3 Query Construction


Criteria queries are constructed through the creation and modification of a QueryDefinition object. The QueryBuilder interface is the factory for QueryDefinition objects. The QueryDefinition interface contains methods to construct instances of the DomainObject interface corresponding to the domain of the query, as well as select, where, order-by, group-by, and having components and to add them to the query definition object.

5.4 Query Roots


A criteria query definition defines a query over one or more entity, embeddable, or basic abstract schema types. The root domain objects of the query are entities, from which the other types are reached by navigation. A query root fills a role analogous to that of a range variable in the Java Persistence query language. A query root may be specified when a criteria query definition object is created from the QueryBuilder object. Alternatively, a root may be introduced into the query by means of the addRoot method of the QueryDefinition interface. A query may have more than one root. The addition of a query root has the semantic effect of creating a cartesian product between the entity type referenced by the added root and those of the other roots.

5.5 Domain Objects


Query roots are instances of the DomainObject type, as are the elements which are joined to query roots. Instances of the DomainObject type are said to constitute the query domain. A DomainObject instance fills a role analogous to that of an identification variable in the Java Persistence query language. Like an identification variable, it represents a single instance of the abstract schema type to which it corresponds. In the case of multi-value relationships, a domain object represents a member of a collection or an instance of an entitys abstract schema type, and never a collection in its entirety. (See section 4.4.2.) When referencing an instance of an association or collection of type java.util.Map, the domain object is of the abstract schema type of the map value.

10/31/08

190

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Domain Objects Java Persistence 2.0, Public Review Draft Criteria API

The DomainObject interface extends the QueryDefinition interface. When a QueryDefinition instance is created by means of the QueryBuilder.createQueryDefinition(Class cls) method, the returned DomainObject constitutes a well-formed, unqualified query definition instance[53] with that DomainObject instance as its root. For example, the following query definition specifies a query that selects all instances of the Order entity class. QueryBuilder qb = ...; DomainObject o = qb.createQueryDefinition(Order.class); In order to select values by comparing more than one instance of an entity abstract schema type, more than one DomainObject instance corresponding to that type must be defined for the QueryDefinition instance. The addRoot method of the QueryDefinition interface is used to add roots to the query definition object. For example, DomainObject o1 = qb.createQueryDefinition(Order.class); DomainObject o2= o1.addRoot(Order.class); ... // code to compare the orders to one another: ... o1.select(o1) .where(o1.get("quantity").greaterThan(o2.get("quantity")) .and(o2.get("customer").get("lastName").equal("Smith")) .and(o2.get("customer").get("firstName").equal("John"))); This query is equivalent to the following Java Persistence query language query. SELECT o1 FROM Order o1, Order o2 WHERE o1.quantity > o2.quantity AND o2.customer.lastName = Smith AND o2.customer.firstName = John Methods of the QueryDefinition interface, when applied to a DomainObject instance, apply to the query as a whole. Thus, in the example above, the addRoot method applied to the domain object o1, causes a second root to be defined for the query. The select, where, orderBy, groupBy, methods when applied to a DomainObject instance thus likewise apply to the QueryDefinition instance as a whole.

[53] If the select method is not used to define a select list for a query and the query has a single root entity, the query root entity is treated as the selected item. See section 5.11.

JSR-317 Public Review Draft

191

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Joins

5.6 Joins
The join and leftJoin methods of the DomainObject interface extend the query domain by specifying a join with a related class that can be navigated to or that is an element of the given domain class. The target of the join is specified by its attribute name in the corresponding abstract schema type. The DomainObject instance that is the result of the join and leftJoin methods corresponds to the abstract schema type that is the target of the join. The join and leftJoin methods have the same semantics as the corresponding Java Persistence query language operations. See section 4.4.7. Example: DomainObject o = qb.createQueryDefinition(Order.class); DomainObject p = o.join("lineItems").join("product"); p.where(p.get("productType").equal("office_supplies")) .selectDistinct(o); The join and leftJoin methods can only be invoked in defining the query domain. They cannot be used for navigation in the other query definition constructs. In this example, the DomainObject p corresponds to an instance of the abstract schema type Product. This query has a single root, which corresponds to the Order entity. This query is equivalent to the following Java Persistence query language query: SELECT DISTINCT o FROM Order o JOIN o.lineItems l JOIN l.product p WHERE p.productType = office_supplies

5.6.1 Fetch Joins


The joinFetch and leftJoinFetch methods of the DomainObject interface specify that the referenced association or element collection is to be fetched as a side effect of the execution of the query. An association or collection referenced by the joinFetch or leftJoinFetch method must be referenced from an entity or embeddable that is returned as the result of the query. A fetch join has the same join semantics as the corresponding inner or outer join, except that the related objects are not top-level objects in the query result. See Section 4.4.5.3. Example: DomainObject d = qb.createQueryDefinition(Department.class); d.leftJoinFetch("employees"); d.where(d.get("deptno").equal(1)); This query is equivalent to the following Java Persistence query language query: SELECT d FROM Department d LEFT JOIN FETCH d.employees WHERE d.deptno = 1

10/31/08

192

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Path Expressions Java Persistence 2.0, Public Review Draft Criteria API

5.7 Path Expressions


A path expression is either a DomainObject instance, a path expression derived from another path expression by means of the get navigation method, or a path expression derived from a DomainObject instance corresponding to a map-valued association or map-valued element collection by use of the key or value method. The get method must only be invoked on a PathExpression instance that corresponds to a single value. The argument to the get method must be the name of a state field or association field of the abstract schema type corresponding to the PathExpression instance on which the method is invoked. It is not permitted to invoke the get method on a PathExpression instance that corresponds to a collection. Only the isEmpty and size methods can be invoked on a PathExpression instance that corresponds to a collection. A PathExpression instance that corresponds to a collection can only be passed as an argument to the in method or member method of the Expression interface. See Section 5.8. When a criteria query is executed, path expression evaluation, like path expression navigability using the Java Persistence query language, is obtained using inner join semantics. That is, if the value of a non-terminal PathExpression instance is null, the path is considered to have no value, and does not participate in the determination of the query result. See Section 4.4.4. Example 1: In the following example, contactInfo denotes an embeddable class consisting of an address and set of phones. Phone is an entity. DomainObject e = qb.createQueryDefinition(Employee.class); DomainObject p = e.join("contactInfo").join("phones"); e.where(e.get("contactInfo").get("address").get("zipcode") .equal("95054")) .select(p.get("vendor")); The following Java Persistence query language query is equivalent: SELECT p.vendor FROM Employee e JOIN e.contactInfo.phones p WHERE e.contactInfo.address.zipcode = '95054' Example 2: In this example, photos corresponds to a map from photo label to filename: QueryDefinition qdef = qb.createQueryDefinition; DomainObject item = qdef.addRoot(Item.class); DomainObject photo = item.join("photos"); qdef.select(item.get("name"), photo.value()) .where(photo.key().like("egret"));

JSR-317 Public Review Draft

193

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Expressions

The following query is equivalent: DomainObject item = qb.createQueryDefinition(Item.class); DomainObject photo = item.join("photos"); item.select(item.get("name"), photo) .where(photo.key().like("egret")); These queries are equivalent to the following Java Persistence query language query: SELECT i.name, p FROM Item i JOIN i.photos p WHERE KEY(p) LIKE egret

5.8 Expressions
An Expression or one of its subtypes can be used in the construction of the querys select list or in the construction of where or having method conditions. Domain objects and path expressions are expressions. Expressions corresponding to the build-in arthmetic, string, and datetime operators and functions of the Java Persistence query language are created by means of the methods of the Expression interface, and the currentDate, currentTime, and currentTimestamp methods of the QueryDefinition interface. Case expressions are created by the generalCase, simpleCase, coalesce, and nullif methods of the QueryDefinition interface and associated methods of the CaseExpression interface. Expression instances also result from the invocation of one of the following methods on a PathExpression instance: type, size, avg, max, min, sum, count; from the invocation of the distinct method on an Aggregate instance; or from the invocation of the index method on a DomainObject instance for whose corresponding type an order column has been defined. A Criteria API literal or parameter is also an Expression instance. Example 1: DomainObject c = qb.createQueryDefinition(Customer.class); DomainObject o = c.join("orders"); DomainObject a = o.join("address"); o.where(a.get("state").equal("CA") .and(a.get("county").equal("Santa Clara"))); o.select(o.get("quantity"), o.get("cost").times(1.08), a.get("zipcode"));

10/31/08

194

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Expressions Java Persistence 2.0, Public Review Draft Criteria API

The following Java Persistence query language query is equivalent: SELECT o.quantity, o.cost*1.08 AS taxedCost, a.zipcode FROM Customer c JOIN c.orders o JOIN c.address a WHERE a.state = 'CA AND a.county = 'Santa Clara Example 2: DomainObject e = qb.createQueryDefinition(Employee.class); e.select(e.type()) .where(e.type().equal(Exempt.class).not()); The type method can only be applied to a path expression that corresponds to an entity. Its result denotes the type of the entity. The following Java Persistence query language query is equivalent: SELECT TYPE(e) FROM Employee e WHERE TYPE(e) <> Exempt Example 3: DomainObject c = qb.createQueryDefinition(Course.class); DomainObject w = c.join("studentWaitlist"); c.where(c.get("name").equal("Calculus") .and(w.index().equal(0))) .select(w.get("name")); The index method can only be applied to a domain object that corresponds to a ordered list. Its result denotes the position of the item in the list. The following Java Persistence query language query is equivalent: SELECT w.name FROM Course c JOIN c.studentWaitlist w WHERE c.name = 'Calculus AND INDEX(w) = 0 Example 4: DomainObject o = qb.createQueryDefinition(Order.class); DomainObject l = o.join("lineItems"); DomainObject c = o.join("customer"); c.where(c.get("lastname").equal("Smith") .and(c.get("firstname").equal("John"))) .select(l.get("price").sum()); The aggregation methods avg, max, min, sum, count can only be used in the construction of the select list or in having method conditions.

JSR-317 Public Review Draft

195

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Expressions

The following Java Persistence query language query is equivalent: SELECT SUM(l.price) FROM Order o JOIN o.lineItems l JOIN o.customer c WHERE c.lastname = 'Smith AND c.firstname = 'John Example 5: DomainObject d = qb.createQueryDefinition(Department.class); d.where(d.get("name").equal("Sales")) .select(d.get("employees").size()); The size method can only be applied to a path expression that corresponds to an association or element collection. Its result denotes the number of elements in the association or element collection. The following Java Persistence query language query is equivalent: SELECT SIZE(d.employees) FROM Department d WHERE d.name = Sales Example 6: DomainObject e = qb.createQueryDefinition(Employee.class); e.where(e.get("department").get("name").equal("Engineering")); e.select(e.get("name"), e.generalCase() .when(e.get("rating").equal(1)) .then(e.get("salary").times(1.1)) .when(e.get("rating").equal(2)) .then(e.get("salary").times(1.2)) .elseCase(e.get("salary").times(1.01))); The following Java Persistence query language query is equivalent: SELECT e.name, CASE WHEN e.rating WHEN e.rating ELSE e.salary END FROM EMPLOYEE e WHERE e.department.name =

= 1 THEN e.salary * 1.1 = 2 THEN e.salary * 1.2 * 1.01 Engineering

5.8.1 Literals
A literal instance is obtained by passing a value of one of the following Java types to the literal method of the QueryDefinition interface: a Java numeric type, string, enum, boolean, java.util.Calendar, java.util.Date, character, or an entity class object.

10/31/08

196

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Restricting the Query Result Java Persistence 2.0, Public Review Draft Criteria API

Example: DomainObject p = qb.createQueryDefinition(Person.class); p.where(p.literal("joe").member(p.get("nicknames"))); The following Java Persistence query language query is equivalent: SELECT p FROM PERSON p WHERE Joe MEMBER OF p.nicknames

5.8.2 Parameters
Named parameters may be used as expression items. The use of a named parameter is specified by passing the parameter name as the argument to the param method of the QueryDefinition interface. The parameter name is not prefixed by the ":" character. Parameters can only be used in the construction of conditional predicates used in the where and .having methods. Example: QueryDefinition qdef = qb.createQueryDefinition(); DomainObject customer = qdef.addRoot(Customer.class); qdef.where(customer.get("status").equal(qdef.param("stat"))); This is equivalent to the following query in the Java Persistence query language: SELECT c FROM Customer c WHERE c.status = :stat Input arguments bound to the query at runtime must be single-valued, except for arguments to the in method, which supports the use of collection-valued input arguments.

5.9 Restricting the Query Result


The query result can be restricted by specifying one or more predicate conditions. Restriction predicates are applied to the QueryDefinition object by means of the where method of the QueryDefinition interface. Invocation of the where method results in the modification of the QueryDefinition object with the specified restrictions. The argument to the where method is a Predicate instance. A predicate may be simple or compound. Compound predicates are constructed by means of the and, or, and not methods of the Predicate interface.

JSR-317 Public Review Draft

197

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Subqueries

A simple predicate is created by invoking a conditional method on a PredicateOperand instance. A PredicateOperand instance may be either an Expression or Subquery instance. Expressions are described in section 5.8, subqueries in section 5.10. Conditional method arguments are instances of the PredicateOperand interface or Java language literals. The semantics of the methods of the PredicateOperand interfaceequal, notEqual, greaterThan, greaterEqual, lessThan, lessEqual, between, and like mirror those of the corresponding Java Persistence query language operators as described in Chapter 4. The restrictions upon the types to which predicate operands are permitted to correspond are the same as the respective operators of the Java Persistence query language as described in subsections 4.6.8 through 4.6.17. The same null value semantics as described in section 4.11 and the subsections of section 4.6 apply. The equality and comparison semantics described in section 4.12 likewise apply. Example 1: DomainObject c = qb.createQueryDefinition(CreditCard.class); DomainObject t = c.join("transactionHistory"); c.select(t) .where(c.get("holder").get("name").equal("John Doe") .and(t.index().between(0, 9))); This query is equivalent to the following Java Persistence query language query: SELECT t FROM CreditCard c JOIN c.transactionHistory t WHERE c.holder.name = 'John Doe AND INDEX(t) BETWEEN 0 AND 9 Example 2: DomainObject o = qb.createQueryDefinition(Order.class); o.where(o.get("lineItems").isEmpty()); This query is equivalent to the following Java Persistence query language query: SELECT o FROM Order o WHERE o.lineItems IS EMPTY

5.10 Subqueries
Both correlated and non-correlated subqueries can be used in restriction predicates. Like a top-level query, a subquery is constructed through the creation and modification of a QueryDefinition object. A non-correlated subquery does not reference instances of query objects of the query of which it is a subquery. In particular, DomainObject and PathExpression instances are not shared between the subquery and the query instance of which it is a subquery.

10/31/08

198

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Subqueries Java Persistence 2.0, Public Review Draft Criteria API

A correlated subquery results from use of one or more DomainObject or PathExpression instances that are common to both the subquery and the query instance of which it is a part. A subquery may be qualified by the invocation of the all, any, or some method on the QueryDefinition instance that is used to express the subquery. The exists method may be applied to a subquery to create a conditional predicate. Example: Non-correlated subquery The query below contains a non-correlated subquery. // create query instance, with root Customer QueryDefinition q1 = qb.createQueryDefinition(); DomainObject goodCustomer = q1.addRoot(Customer.class); // create second query instance, with root Customer QueryDefinition q2 = qb.createQueryDefinition(); DomainObject customer = q2.addRoot(Customer.class); // the result of query q1 depends on subquery q2 // the result of subquery q2 is independent of q1 q1.where(goodCustomer.get("balanceOwed") .lessThan(q2.select(customer.get("balanceOwed").avg()))); Note that this query can be more concisely expressed as follows: DomainObject goodCustomer = qb.createQueryDefinition(Customer.class); DomainObject customer= qb.createQueryDefinition(Customer.class); goodCustomer.where(goodCustomer.get("balanceOwed") .lessThan(customer.select(customer.get("balanceOwed") .avg()))); These queries correspond to the following Java Persistence query language query. SELECT goodCustomer FROM Customer goodCustomer WHERE goodCustomer.balanceOwed < ( SELECT AVG(c.balanceOwed) FROM Customer c)

JSR-317 Public Review Draft

199

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Subqueries

Example: Correlated subquery // create QueryDefinition instance, with root Employee QueryDefinition q1 = qb.createQueryDefinition(); DomainObject emp = q1.addRoot(Employee.class); // create second Criteria query instance, with root Employee QueryDefinition q2 = qb.createQueryDefinition(); DomainObject spouseEmp = q2.addRoot(Employee.class); // the subquery references the domain object of the containing query q2.where(spouseEmp.equal(emp.get("spouseEmp"))) .select(spouseEmp); q1.selectDistinct(emp).where(q2.exists()); This query can be more concisely expressed as follows: DomainObject emp = qb.createQueryDefinition(Employee.class); DomainObject spouseEmp = qb.createQueryDefinition(Employee.class); spouseEmp.where(spouseEmp.equal(emp.get("spouseEmp"))); emp.selectDistinct(emp) .where(spouseEmp.exists()); The above queries correspond to the following Java Persistence query language query. SELECT DISTINCT emp FROM Employee emp WHERE EXISTS ( SELECT spouseEmp FROM Employee spouseEmp WHERE spouseEmp = emp.spouse) Example: Subquery qualified by all() // create QueryDefinition query instance, with root Employee QueryDefinition c1 = qb.createQueryDefinition(); DomainObject e = c1.addRoot(Employee.class); // create second QueryDefinition query instance, with root Manager QueryDefinition c2 = qb.createQueryDefinition(); DomainObject m = c2.addRoot(Manager.class); // the subquery references the domain object for Employee m.select(m.get("salary")) .where(m.get("department").equal(e.get("department"))); e.select(e) .where(e.get("salary").greaterThan(m.all()));

10/31/08

200

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Subqueries Java Persistence 2.0, Public Review Draft Criteria API

This query corresponds to the following Java Persistence query language query: SELECT emp FROM Employee emp WHERE emp.salary > ALL ( SELECT m.salary FROM Manager m WHERE m.department = emp.department) Example: A Special case In order to express some correlated subqueries involving unidirectional relationships, it may be useful to create a domain object derived from a domain object of the containing query as a root of the subquery. This can be performed by passing a PathExpression corresponding to the abstract schema type for which the domain object is to be created to the createSubqueryDefinition method of the QueryBuilder interface or the addSubqueryRoot method of the QueryDefinition interface. A root of the containing query must not be passed to a subquery definition method. For example: DomainObject customer = qb.createQueryDefinition(Customer.class); DomainObject order = qb.createSubqueryDefinition(customer.get("orders")); customer.where(order.select(order.get("price").avg()) .greaterThan(100)); This query corresponds to the following Java Persistence query language query: SELECT c FROM Customer c WHERE (SELECT AVG(o.price) FROM c.orders o) > 100 Note that joins involving the derived subquery root do not affect the join conditions of the containing query. The following two query definitions thus differ in semantics: DomainObject o = qb.createQueryDefinition(Order.class); DomainObject a = qb.createSubqueryDefinition(o.get("customer").get("accounts")); o.select(o) .where(o.literal(10000) .lessThan(a.select(a.get("balance")).all())); and DomainObject o = qb.createQueryDefinition(Order.class); DomainObject c = o.join("customer"); DomainObject a = qb.createSubqueryDefinition(c.get("accounts")); o.select(o) .where(o.literal(10000) .lessThan(a.select(a.get("balance")).all()));

JSR-317 Public Review Draft

201

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Specifying the Select List

The first of these queries will return orders that are not associated with customers, whereas the second will not. The corresponding Java Persistence query language queries are the following: SELECT o FROM Order o WHERE 10000 < ALL ( SELECT a.balance FROM o.customer c JOIN c.accounts a) and SELECT o FROM Order o JOIN o.customer c WHERE 10000 < ALL ( SELECT a.balance FROM c.accounts a)

5.11 Specifying the Select List


The select list of a query is specified by use of one of the select or selectDistinct methods of the QueryDefinition interface. The arguments to these methods are either one or more SelectItem instances or a List<SelectItem> instance. A SelectItem instance may be one of the following:

Any Expression instance. A SelectItem instance obtained as the result of the invocation of the entry method on a
DomainObject instance that corresponds to a map-valued association or map-valued element collection. The result of this method denotes a map entry.

A SelectItem instance obtained as the result of the invocation of the newInstance


method of the QueryDefinition interface. This method is used to specify a constructor that will be applied to the results of the query execution. See section 4.8.2. If the newInstance method specifies an entity class, the resulting entities will be in the new state after the query is executed. If no select method is specified for a query, or if no select items are specified, the query root entity is assumed to be the query result. The construction of the query will fail or the IllegalStateException will be thrown at runtime if more than one root has been defined for the query. Example 1: The following example illustrates the specification of a constructor.

10/31/08

202

JSR-317 Public Review Draft

Sun Microsystems, Inc.


GroupBy and Having Java Persistence 2.0, Public Review Draft Criteria API

QueryDefinition q = qb.createQueryDefinition(); DomainObject customer = q.addRoot(Customer.class); DomainObject order = customer.join("orders"); q.where(order.get("count").greaterThan(100)) .select(q.newInstance(com.acme.CustomerDetails.class, customer.get("id"), customer.get("status"), order.get("count"))); The following Java Persistence query language query is equivalent: SELECT NEW com.acme.example.CustomerDetails(c.id, c.status, o.count) FROM Customer c JOIN c.orders o WHERE o.count > 100 Example 2: In the following example, videoInventory is a Map from the entity Movie to the number of copies in stock. QueryDefinition q = qb.createQueryDefinition(); DomainObject v = q.addRoot(VideoStore.class); DomainObject i = v.join("videoInventory"); q.where(v.get("location").get("zipcode").equal("94301") .and(i.value().greaterThan(0))); q.select(v.get("location").get("street"), i.key().get("title"), i.value()); This is equivalent to the following Java Persistence query language query: SELECT v.location.street, KEY(i).title, VALUE(i) FROM VideoStore v JOIN v.videoInventory i WHERE v.location.zipcode = '94301' AND VALUE(i) > 0 The selectDistinct methods are used to specify that duplicate values must be eliminated from the query result. If the select method is used, duplicate values are not eliminated. When selectDistinct is used, and the select items include embeddable objects or map entry results, the elimination of duplicates is undefined. The mapping of the abstract schema types to which the select items correspond to the result types of the query is as described in sections 4.8.1 through 4.8.4.

5.12 GroupBy and Having


The groupBy method of the QueryDefinition interface is used to define a partitioning of the query results into groups. The having method of the QueryDefinition interface can be used to filter over the groups. The arguments to the groupBy method are PathExpression instances.

JSR-317 Public Review Draft

203

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Ordering the Query Results

When groupBy is specified, each argument to the select or selectDistinct method of the query that is not the result of applying an aggregate method must correspond to a path expression that is used for defining the grouping. Requirements on the types that correspond to the elements of the grouping and having constructs and their relationship to the select items are as specified in Section 4.7. Examples: QueryDefinition q = qb.createQueryDefinition(); DomainObject customer = q.addRoot(Customer.class); q.select(customer.get("status"), customer.get("filledOrderCount").avg(), customer.count()) .groupBy(customer.get("status")) .having(q.get("status").in(1, 2)); QueryDefinition q = qb.createQueryDefinition(); DomainObject customer = q.addRoot(Customer.class); q.select(customer.get("country"), customer.count()) .groupBy(customer.get("country")) .having(customer.count().greaterThan(30)); These queries are equivalent to the following Java Persistence query language queries: SELECT c.status, AVG(c.filledOrderCount), COUNT(c) FROM Customer c GROUP BY c.status HAVING c.status IN (1, 2) SELECT c.country, COUNT(c) FROM Customer c GROUP BY c.country HAVING COUNT(c) > 30

5.13 Ordering the Query Results


The ordering of the results of a query may be defined by invoking the orderBy method on the QueryDefinition instance. The arguments to the orderBy method are OrderByItem instances. An OrderByItem instance must be one of the following:

Any PathExpression instance that corresponds to an orderable state field of an entity or


embeddable class abstract schema type that is specified by an argument of the select or selectDistinct method.

Any PathExpression instance that corresponds to the same state field of the same entity
or embeddable abstract schema type as a PathExpression instance that is specified by an argument of the select or selectDistinct method.

10/31/08

204

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Ordering the Query Results Java Persistence 2.0, Public Review Draft Criteria API

A SelectItem instance that is used as an argument of the select or selectDistinct


method invoked for the query. The asc and desc methods may be applied to SelectItem instances to specify ascending or descending ordering. In the absence of such specification, ascending ordering is used. SQL rules for the ordering of null values apply, as described in Section 4.9. If more than one OrderByItem is specified, the order in which they appear in the argument list determines the precedence, whereby the first item has highest precedence. Example 1: QueryDefinition q = qb.createQueryDefinition(); DomainObject customer = q.addRoot(Customer.class); DomainObject order = customer.join("orders"); DomainObject address = customer.join("address"); q.where(address.get("state").equal("CA")) .select(order) .orderBy(order.get("quantity").desc(), order.get("totalcost")); This query corresponds to the following Java Persistence query language query: SELECT o FROM Customer c JOIN c.orders o JOIN c.address a WHERE a.state = 'CA ORDER BY o.quantity DESC, o.totalcost Example 2: QueryDefinition q = qb.createQueryDefinition(); DomainObject customer = q.addRoot(Customer.class); DomainObject order = customer.join("orders"); DomainObject address = customer.join("address"); q.where(address.get("state").equal("CA")) .select(order.get("quantity"), address.get("zipcode")) .orderBy(order.get("quantity"), address.get("zipcode")); This query corresponds to the following Java Persistence query language query: SELECT o.quantity, a.zipcode FROM Customer c JOIN c.orders o JOIN c.address a WHERE a.state = 'CA ORDER BY o.quantity, a.zipcode Example 3: DomainObject o = qb.createQueryDefinition(Order.class); DomainObject a = o.join("customer").join("address"); SelectItem taxedCost = o.get("cost").times(1.08); o.select(o.get("quantity"), taxedCost, a.get("zipcode")) .where(a.get("state").equal("CA") .and(a.get("county").equal("Santa Clara"))) .orderBy(o.get("quantity"), taxedCost, a.get("zipcode"));

JSR-317 Public Review Draft

205

10/31/08

Sun Microsystems, Inc.


Criteria API Java Persistence 2.0, Public Review Draft Query Definition Modification

This query corresponds to the following Java Persistence query language query: SELECT o.quantity, o.cost * 1.08 AS taxedCost, a.zipcode FROM Customer c JOIN c.orders o JOIN c.address a WHERE a.state = 'CA' AND a.county = 'Santa Clara' ORDER BY o.quantity, taxedCost, a.zipcode

5.14 Query Definition Modification


A query definition may be modified, either before or after queries have been created and executed from it. For example, such modification may entail replacement of the where predicate or the select list. Query modifications may thus result in the same query base being reused for several query definitions. For example, the user might create and execute a query from the following query definition: DomainObject c = qb.createQueryDefinition(Customer.class); Predicate p1 = c.get("address").get("city").equal("Chicago"); c.where(p1); The query definition object might then be modified as follows to reflect a different predicate condition, for example. Predicate p2 = c.get("balanceOwed").greaterThan(1000); c.where(p2); Note, however, that query definition components-in this example, predicate conditionsare dependent on DomainObject and QueryDefinition instances, and are thus not portably reusable with different QueryDefinition objects.

5.15 Query Execution


A criteria query is executed by passing the QueryDefinition object to the createQuery method of the EntityManager interface to create a Query object, which can then be passed to the getResultList or getSingleResult method of the Query interface. A QueryDefinition object may be further modified after a Query object has been created from it. The modification of the QueryDefinition object does not have any impact on the already created Query object. If the modified QueryDefinition object is passed to the createQuery method, the persistence provider must insure that a new Query object is created that reflects the semantics of the changed query definition. QueryDefinition objects must be serializable. A persistence vendor is required to support the subsequent deserialization of a QueryDefinition object into a separate JVM instance of that vendors runtime, where both runtime instances have access to any required vendor implementation classes. QueryDefinition objects are not required to be interoperable across vendors.

10/31/08

206

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Persistence Contexts Java Persistence 2.0, Public Review Draft Entity Managers and Persistence Contexts

C ha p t e r 6

Entity Managers and Persistence Contexts

6.1 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 facilitate 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 transaction. This propagation of persistence context by the Java EE container avoids the need for the application 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 managers lifecycle is managed by the Java EE container.

JSR-317 Public Review Draft

207

10/31/08

Sun Microsystems, Inc.


Entity Managers and Persistence Contexts Java Persistence 2.0, Public Review Draft Obtaining an EntityManager

In less common use cases within Java EE environments, applications may need to access a persistence context that is stand-alonei.e. not propagated along with the JTA transaction across the EntityManager 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 EntityManager references within the same transaction. These use cases are supported through the createEntityManager 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-managed entity manager. An application-managed entity managers lifecycle is managed by the application. Both container-managed entity managers and application-managed entity managers and their persistence 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[54].

6.2 Obtaining an EntityManager


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 transparently to the application. When application-managed entity managers are used, the application must use the entity manager factory 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.

6.2.1 Obtaining an Entity Manager in the Java EE Environment


A container-managed entity manager is obtained by the application through dependency injection, or direct lookup of the entity manager in the JNDI namespace. The container manages the persistence context lifecycle and the creation and the closing of the entity manager instance transparently to the application. 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 section 6.6. The unitName element may optionally be specified to designate the persistence unit whose factory is used by the container. (See section 9.4.2).

[54] Note that the use of JTA is not required to be supported in application client containers.

10/31/08

208

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Obtaining an Entity Manager Factory Java Persistence 2.0, Public Review Draft Entity Managers and Persistence Contexts

For example, @PersistenceContext EntityManager em; @PersistenceContext(type=PersistenceContextType.EXTENDED) EntityManager orderEM; The JNDI lookup of an entity manager is illustrated below: @Stateless @PersistenceContext(name="OrderEM") public class MySessionBean implements MyInterface { @Resource SessionContext ctx; public void doSomething() { EntityManager em = (EntityManager)ctx.lookup("OrderEM"); ... }

6.2.2 Obtaining an Application-managed Entity Manager


An application-managed entity manager is obtained by the application from an entity manager factory. The EntityManagerFactory API used to obtain an application-managed entity manager is the same independent of whether this API is used in Java EE or Java SE environments.

6.3 Obtaining an Entity Manager Factory


The EntityManagerFactory interface is used by the application to create an application-managed entity manager[55]. Each entity manager factory provides entity manager instances that are all configured in the same manner (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.[56] Methods of the EntityManagerFactory interface are threadsafe.

[55] It may also be used internally by the Java EE container. See section 6.9. [56] 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.

JSR-317 Public Review Draft

209

10/31/08

Sun Microsystems, Inc.


Entity Managers and Persistence Contexts Java Persistence 2.0, Public Review Draft EntityManagerFactory Interface

6.3.1 Obtaining an Entity Manager Factory in a Java EE Container


Within a Java EE environment, an entity manager factory may be injected using the PersistenceUnit annotation or obtained through JNDI lookup. The unitName element may optionally be specified to designate the persistence unit whose factory is used. (See section 9.4.2). For example @PersistenceUnit EntityManagerFactory emf;

6.3.2 Obtaining an Entity Manager Factory in a Java SE Environment


Outside a Java EE container environment, the javax.persistence.Persistence class is the bootstrap class that provides access to an entity manager factory. The application creates an entity manager factory by calling the createEntityManagerFactory method of the javax.persistence.Persistence class, described in section 8.2.1. For example, EntityManagerFactory emf = javax.persistence.Persistence.createEntityManagerFactory("Order"); EntityManager em = emf.createEntityManager();

6.4 EntityManagerFactory Interface


The EntityManagerFactory interface is used by the application to obtain an application-managed entity manager. When the application has finished using the entity manager factory, and/or at application shutdown, the application should close the entity manager factory. Once an EntityManagerFactory has been closed, all its entity managers are considered to be in the closed state.

10/31/08

210

JSR-317 Public Review Draft

Sun Microsystems, Inc.


EntityManagerFactory Interface Java Persistence 2.0, Public Review 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); /** * Return an instance of QueryBuilder for the creation of * Criteria API QueryDefinition objects. * @return QueryBuilder instance * @throws IllegalStateException if the entity manager factory * has been closed. */ public QueryBuilder getQueryBuilder(); /** * 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();

JSR-317 Public Review Draft

211

10/31/08

Sun Microsystems, Inc.


Entity Managers and Persistence Contexts Java Persistence 2.0, Public Review Draft Controlling Transactions

/** * 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 * with the entity manager factory. These correspond to * properties that may be passed to the methods of the * EntityManagerFactory interface that take a properties * argument. These include all standard properties as well as * vendor-specific properties supported by the provider. These * properties may or may not currently be in effect. * @return properties and hints */ public Set<String> getSupportedProperties(); /** * 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 createEntityManager. Properties that are not recognized by a vendor must be ignored. Vendors should use vendor namespaces for properties (e.g., com.acme.persistence.logging). Entries that make use of the namespace javax.persistence and its subnamespaces must not be used for vendor-specific information. The namespace javax.persistence is reserved for use by this specification.

6.5 Controlling Transactions


Depending on the transactional type of the entity manager, transactions involving EntityManager operations may be controlled either through JTA or through use of the resource-local EntityTransaction 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 EntityTransaction API is termed a resource-local entity manager.

10/31/08

212

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Controlling Transactions Java Persistence 2.0, Public Review Draft Entity Managers and Persistence Contexts

A container-managed entity manager must be a JTA entity manager. JTA entity managers are only specified for use in Java EE containers. An application-managed entity manager may be either a JTA entity manager or a resource-local entity manager. An entity manager is defined to be of a given transactional typeeither JTA or resource-localat the time its underlying entity manager factory is configured and created. See sections 7.2.1.2 and 8.1.1. 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.

6.5.1 JTA EntityManagers


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.

6.5.2 Resource-local EntityManagers


An entity manager whose transactions are controlled by the application through the EntityTransaction API is a resource-local entity manager. A resource-local entity manager transaction is mapped to a resource transaction over the resource by the persistence provider. Resource-local entity managers may use server or local resources to connect to the database and are unaware of the presence of JTA transactions that may or may not be active.

6.5.2.1 The EntityTransaction Interface


The EntityTransaction interface is used to control resource transactions on resource-local entity managers. The EntityManager.getTransaction() method returns the EntityTransaction interface. 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.

JSR-317 Public Review Draft

213

10/31/08

Sun Microsystems, Inc.


Entity Managers and Persistence Contexts Java Persistence 2.0, Public Review Draft Controlling Transactions

If the EntityTransaction.commit operation fails, the persistence provider must roll back the transaction. public interface EntityTransaction { /** * Start a resource transaction. * @throws IllegalStateException if isActive() is true. */ public void begin(); /** * 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(); }

10/31/08

214

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Container-managed Persistence Contexts Java Persistence 2.0, Public Review Draft Entity Managers and Persistence Contexts

6.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(); } }

6.6 Container-managed Persistence Contexts


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 single transaction or an extended lifetime that spans multiple transactions, depending on the PersistenceContextType 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 6.6.1 and 6.6.2 describe transaction-scoped and extended persistence contexts in the absence of persistence context propagation. Persistence context propagation is described in section 6.6.3.

JSR-317 Public Review Draft

215

10/31/08

Sun Microsystems, Inc.


Entity Managers and Persistence Contexts Java Persistence 2.0, Public Review 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 associated with a particular entity manager factory".

6.6.1 Container-managed Transaction-scoped Persistence Context


The application may obtain a container-managed entity manager with transaction-scoped persistence context bound to the JTA transaction by injection or direct lookup in the JNDI namespace. The persistence context type for the entity manager is defaulted or defined as PersistenceContextType.TRANSACTION. A new persistence context begins when the container-managed entity manager is invoked[57] 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.

6.6.2 Container-managed Extended Persistence Context


A container-managed extended persistence context can only be initiated within the scope of a stateful session bean. It exists from the point at which the stateful session bean that declares a dependency on an entity manager of type PersistenceContextType.EXTENDED is created, and is said to be bound to the stateful session bean. The dependency on the extended persistence context is declared by means of the PersistenceContext annotation or persistence-context-ref deployment descriptor element. 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).

6.6.2.1 Inheritance of Extended Persistence Context


If a stateful session bean instantiates a stateful session bean (executing in the same EJB container instance) which also has such an extended persistence context, the extended persistence context of the first stateful session bean is inherited by the second stateful session bean and bound to it, and this rule recursively appliesindependently of whether transactions are active or not at the point of the creation of the stateful session beans. 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.

[57] Specifically, when one of the methods of the EntityManager interface is invoked.

10/31/08

216

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Container-managed Persistence Contexts Java Persistence 2.0, Public Review Draft Entity Managers and Persistence Contexts

6.6.3 Persistence Context Propagation


As described in section 6.1, a single persistence context may correspond to one or more JTA entity manager instances (all associated with the same entity manager factory[58]). 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.

6.6.3.1 Requirements for Persistence Context Propagation


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 an entity manager is then invoked from within the component: Invocation of an entity manager defined with PersistenceContextType.TRANSACTION will result in use of a new persistence context (as described in section 6.6.1).

Invocation of an entity manager defined with PersistenceContextType.EXTENDED will result in the use of the existing extended persistence context bound to that component.

If the entity manager is invoked within a JTA transaction, the persistence context will
be bound to the JTA transaction. 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 EJBException is thrown by the container.

Otherwise, if there is a persistence context bound to the JTA transaction, that persistence context is propagated and used.

[58] Entity manager instances obtained from different entity manager factories never share the same persistence context.

JSR-317 Public Review Draft

217

10/31/08

Sun Microsystems, Inc.


Entity Managers and Persistence Contexts Java Persistence 2.0, Public Review Draft Container-managed Persistence Contexts

6.6.4 Examples 6.6.4.1 Container-managed Transaction-scoped Persistence Context


@Stateless public class ShoppingCartImpl implements ShoppingCart { @PersistenceContext EntityManager em; public Order getOrder(Long id) { return em.find(Order.class, id); } public Product getProduct(String name) { return (Product) em.createQuery("select p from Product p where p.name = :name") .setParameter("name", name) .getSingleResult(); } public LineItem createLineItem(Order order, Product product, int quantity) { LineItem li = new LineItem(order, product, quantity); order.getLineItems().add(li); em.persist(li); return li; } }

10/31/08

218

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Application-managed Persistence Contexts Java Persistence 2.0, Public Review Draft Entity Managers and Persistence Contexts

6.6.4.2 Container-managed Extended Persistence Context


@Stateful @Transaction(REQUIRES_NEW) public class ShoppingCartImpl implements ShoppingCart { @PersistenceContext(type=EXTENDED) EntityManager em; private Order order; private Product product; public void initOrder(Long id) { order = em.find(Order.class, id); } public void initProduct(String name) { product = (Product) em.createQuery("select p from Product p where p.name = :name") .setParameter("name", name) .getSingleResult(); } public LineItem createLineItem(int quantity) { LineItem li = new LineItem(order, product, quantity); order.getLineItems().add(li); return li; } }

6.7 Application-managed Persistence Contexts


When an application-managed entity manager is used, the application interacts directly with the persistence 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 transactions. The EntityManagerFactory.createEntityManager method and the EntityManager close and isOpen methods are used to manage the lifecycle of an application-managed entity manager and its associated persistence context. 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 application-managed entity manager is a stand-alone persistence contextit is not propagated with the transaction.

JSR-317 Public Review Draft

219

10/31/08

Sun Microsystems, Inc.


Entity Managers and Persistence Contexts Java Persistence 2.0, Public Review 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 IllegalStateException will be thrown. If the close method is invoked when a transaction is active, the persistence 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.

10/31/08

220

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Application-managed Persistence Contexts Java Persistence 2.0, Public Review Draft Entity Managers and Persistence Contexts

6.7.1 Examples 6.7.1.1 Application-managed Persistence Context used in Stateless Session Bean
/* * Container-managed transaction demarcation is used. * Session bean creates and closes an entity manager in * each business method. */ @Stateless public class ShoppingCartImpl implements ShoppingCart { @PersistenceUnit private EntityManagerFactory emf; public Order getOrder(Long id) { EntityManager em = emf.createEntityManager(); Order order = em.find(Order.class, id); em.close(); return order; } public Product getProduct() { EntityManager em = emf.createEntityManager(); Product product = (Product) em.createQuery("select p from Product p where p.name = :name") .setParameter("name", name) .getSingleResult(); em.close(); return product; } public LineItem createLineItem(Order order, Product product, int quantity) { EntityManager em = emf.createEntityManager(); LineItem li = new LineItem(order, product, quantity); order.getLineItems().add(li); em.persist(li); em.close(); return li; // remains managed until JTA transaction ends } }

JSR-317 Public Review Draft

221

10/31/08

Sun Microsystems, Inc.


Entity Managers and Persistence Contexts Java Persistence 2.0, Public Review Draft Application-managed Persistence Contexts

6.7.1.2 Application-managed Persistence Context used in Stateless Session Bean


/* * Container-managed transaction demarcation is used. * Session bean creates entity manager in PostConstruct * method and clears persistence context at the end of each * business method. */ @Stateless public class ShoppingCartImpl implements ShoppingCart { @PersistenceUnit private EntityManagerFactory emf; private EntityManager em; @PostConstruct public void init() em = emf.createEntityManager(); } public Order getOrder(Long id) { Order order = em.find(Order.class, id); em.clear(); // entities are detached return order; } public Product getProduct() { Product product = (Product) em.createQuery("select p from Product p where p.name = :name") .setParameter("name", name) .getSingleResult(); em.clear(); return product; } public LineItem createLineItem(Order order, Product product, int quantity) { em.joinTransaction(); LineItem li = new LineItem(order, product, quantity); order.getLineItems().add(li); em.persist(li); // persistence context is flushed to database; // all updates will be committed to database on tx commit em.flush(); // entities in persistence context are detached em.clear(); return li; } @PreDestroy public void destroy() em.close(); } }

10/31/08

222

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Application-managed Persistence Contexts Java Persistence 2.0, Public Review Draft Entity Managers and Persistence Contexts

6.7.1.3 Application-managed Persistence Context used in Stateful Session Bean


//Container-managed transaction demarcation is used @Stateful public class ShoppingCartImpl implements ShoppingCart { @PersistenceUnit private EntityManagerFactory emf; private EntityManager em; private Order order; private Product product; @PostConstruct public void init() { em = emf.createEntityManager(); } public void initOrder(Long id) { order = em.find(Order.class, id); } public void initProduct(String name) { product = (Product) em.createQuery("select p from Product p where p.name = :name") .setParameter("name", name) .getSingleResult(); } public LineItem createLineItem(int quantity) { em.joinTransaction(); LineItem li = new LineItem(order, product, quantity); order.getLineItems().add(li); return li; } @Remove public void destroy() { em.close(); } }

JSR-317 Public Review Draft

223

10/31/08

Sun Microsystems, Inc.


Entity Managers and Persistence Contexts Java Persistence 2.0, Public Review Draft Application-managed Persistence Contexts

6.7.1.4 Application-managed Persistence Context with Resource Transaction


// Usage in an ordinary Java class public class ShoppingImpl { private EntityManager em; private EntityManagerFactory emf; public ShoppingCart() { emf = Persistence.createEntityManagerFactory("orderMgt"); em = emf.createEntityManager(); } private Order order; private Product product; public void initOrder(Long id) { order = em.find(Order.class, id); } public void initProduct(String name) { product = (Product) em.createQuery("select p from Product p where p.name = :name") .setParameter("name", name) .getSingleResult(); } public LineItem createLineItem(int quantity) { em.getTransaction().begin(); LineItem li = new LineItem(order, product, quantity); order.getLineItems().add(li); em.getTransaction().commit(); return li; } public void destroy() { em.close(); emf.close(); } }

10/31/08

224

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Requirements on the Container Java Persistence 2.0, Public Review Draft Entity Managers and Persistence Contexts

6.8 Requirements on the Container


6.8.1 Application-managed Persistence Contexts
When application-managed persistence contexts are used, the container must instantiate the entity manager 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.createContainerEntityManagerFactory method. However, the container is required to support third-party persistence 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).

6.8.2 Container Managed Persistence Contexts


The container is responsible for managing the lifecycle of container-managed persistence contexts, for injecting EntityManager references into web components and session bean and message-driven bean components, and for making EntityManager references available to direct lookups in JNDI. When operating with a third-party persistence provider, the container uses the contracts defined in section 6.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 6.6.3.

6.9 Runtime Contracts between the Container and Persistence Provider


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.[59]

6.9.1 Container Responsibilities


For the management of a transaction-scoped persistence context, if there is no EntityManager already associated with the JTA transaction:

[59] 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.

JSR-317 Public Review Draft

225

10/31/08

Sun Microsystems, Inc.


Entity Managers and Persistence Contexts Java Persistence 2.0, Public Review Draft Runtime Contracts between the Container and

The container creates a new entity manager by calling EntityManagerFactory.createEntityManager when the first invocation of an entity manager with PersistenceContextType.TRANSACTION occurs within the scope of a business method executing in the JTA transaction.

After the JTA transaction has completed (either by transaction commit or rollback), The container closes the entity manager by calling EntityManager.close. [60] The container must throw the TransactionRequiredException if a transaction-scoped persistence context is used, and the EntityManager persist, remove, merge, or refresh method is invoked when no transaction is active. For stateful session beans with extended persistence contexts:

The container creates an entity manager by calling EntityManagerFactory.createEntityManager when a stateful session bean is created that declares a dependency on an entity manager with PersistenceContextType.EXTENDED. (See section 6.6.2).

The container closes the entity manager by calling EntityManager.close after the stateful 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 associated with the current JTA transaction, the container associates the entity manager with the current 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. If the application invokes EntityManager.unwrap(Class<T> cls), and the container cannot staisfy the request, the container must delegate the unwrap invocation to the providers entity manager instance. The container must throw the IllegalStateException if the application calls EntityManager.close on a container-managed entity manager. When the container creates an entity manager, it may pass a map of properties to the persistence provider by using the EntityManagerFactory.createEntityManager(Map map) method. If properties have been specified in the PersistenceContext annotation or the persistence-context-ref deployment descriptor element, this method must be used and the map must include the specified properties.

[60] 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.

10/31/08

226

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Runtime Contracts between the Container and Persistence ProviderJava Persistence 2.0, Public Review Draft Entity Managers and Per-

6.9.2 Provider Responsibilities


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 EntityManagerFactory.createEntityManager is invoked, the provider


must create and return a new entity manager. If a JTA transaction is active, the provider must register for synchronization notifications against the JTA transaction.

When EntityManager.joinTransaction is invoked, the provider must register for


synchronization notifications against the current JTA transaction if a previous joinTransaction invocation for the transaction has not already been processed.

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 completed. If the entity manager was already in a closed state, the provider must throw the IllegalStateException.

When EntityManager.clear is invoked, the provider must detach all managed entities.

JSR-317 Public Review Draft

227

10/31/08

Sun Microsystems, Inc.


Entity Managers and Persistence Contexts Java Persistence 2.0, Public Review Draft Cache Interface

6.10 Cache Interface


The Cache interface provides basic functionality over the persistence providers 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(); }

10/31/08

228

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Persistence Unit Java Persistence 2.0, Public Review Draft Entity Packaging

C ha p t e r 7

Entity Packaging

This chapter describes the packaging of persistence units.

7.1 Persistence Unit


A persistence unit is a logical grouping that includes:

An entity manager factory and its entity managers, together with their configuration information.

The set of managed classes included in the persistence unit and managed by the entity managers 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.

JSR-317 Public Review Draft

229

10/31/08

Sun Microsystems, Inc.


Entity Packaging Java Persistence 2.0, Public Review Draft Persistence Unit Packaging

7.2 Persistence Unit Packaging


Within Java EE environments, an EJB-JAR, WAR, EAR, or application client JAR can define a persistence 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 environments, the root of a persistence unit may be one of the following:

an EJB-JAR file the WEB-INF/classes directory of a WAR file[61] a jar file in the WEB-INF/lib directory of a WAR file a jar file in the root of the EAR a jar file in the EAR library directory an application client jar file
It is not required that an EJB-JAR or WAR file containing a persistence unit be packaged in an EAR unless the persistence unit contains persistence classes in addition to those contained within the EJB-JAR or WAR. See Section 7.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 7.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 other Java EE components in the applicationi.e. loaded by the application classloadersuch 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 using the class element of the persistence.xml file. See Section 7.2.1.6.

[61] 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.

10/31/08

230

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Persistence Unit Packaging Java Persistence 2.0, Public Review Draft Entity Packaging

7.2.1 persistence.xml file


A persistence.xml file defines a persistence unit. The persistence.xml file is located in the META-INF directory of the root of the persistence unit. It may be used to specify managed persistence classes included in the persistence unit, object/relational mapping information for those classes, and other configuration information for the persistence unit and for the entity manager(s) and entity manager factory for the persistence unit. This information may be defined by containment or by reference, as described below. The object/relational mapping information may take the form of annotations on the managed persistence classes included in the persistence unit, an orm.xml file contained in the root of the persistence unit, one or more XML files on the classpath and referenced from the persistence.xml file, 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 referencei.e., by naming the classes, class archives, or XML mapping files (which in turn reference classes) that are accessible on the application classpath; or they may be specified by some combination of these means. See Section 7.2.1.6. The root element of the persistence.xml file is the persistence element. The persistence element consists of one or more persistence-unit elements. 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>

JSR-317 Public Review Draft

231

10/31/08

Sun Microsystems, Inc.


Entity Packaging Java Persistence 2.0, Public Review 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>

7.2.1.1 name
The name attribute defines the name for the persistence unit. This name may be used to identify a persistence unit referred to by the PersistenceContext and PersistenceUnit annotations and in the programmatic API for creating an entity manager factory.

7.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 providedeither as specified by the jta-data-source element 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 specified, the default is RESOURCE_LOCAL.

7.2.1.3 description
The description element provides optional descriptive information about the persistence unit.

7.2.1.4 provider
The provider element specifies the name of the persistence provider's javax.persistence.spi.PersistenceProvider class. The provider element is optional, but must be specified if the application is dependent upon a particular persistence provider being used.

7.2.1.5 jta-data-source, non-jta-data-source


In Java EE environments, the jta-data-source and non-jta-data-source elements are used to specify the global JNDI name of the JTA and/or non-JTA data source to be used by the persistence provider. If neither is specified, the deployer must specify a JTA data source at deployment or a JTA data source must be provided by the container, and a JTA EntityManagerFactory will be created to correspond to it.

10/31/08

232

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Persistence Unit Packaging Java Persistence 2.0, Public Review Draft Entity Packaging

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. In Java SE environments, these elements may be used or the data source information may be specified by other meansdepending upon the requirements of the provider.

7.2.1.6 mapping-file, jar-file, class, exclude-unlisted-classes


The following classes must be implicitly or explicitly denoted as managed persistence classes to be included within a persistence unit: entity classes; embeddable classes; mapped superclasses. The set of managed persistence classes that are managed by a persistence unit is defined by using one or more of the following:[62]

Annotated managed persistence classes contained in the root of the persistence unit (unless the
exclude-unlisted-classes element is specified)

One or more object/relational mapping XML files One or more jar files that will be searched for classes An explicit list of classes
The set of entities managed by the persistence unit is the union of these sources, with the mapping 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 minimum 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. 7.2.1.6.1 Annotated Classes in the Root of the Persistence Unit All classes contained in the root of the persistence unit are searched for annotated managed persistence classesclasses with the Entity, Embeddable, or MappedSuperclass annotationand 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 must be used. The exclude-unlisted-classes element is not intended for use in Java SE environments. 7.2.1.6.2 Object/relational Mapping Files An object/relational mapping XML file contains mapping information for the classes listed in it.

[62] Note that an individual class may be used in more than one persistence unit.

JSR-317 Public Review Draft

233

10/31/08

Sun Microsystems, Inc.


Entity Packaging Java Persistence 2.0, Public Review Draft Persistence Unit Packaging

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 persistence.xml. Alternatively, or in addition, one or more mapping files may be referenced by the mapping-file elements of the persistence-unit element. These mapping files may be present anywhere on the class path. An orm.xml mapping 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 as described in Chapter 11. 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 undefined 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 information 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. 7.2.1.6.3 Jar Files 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 processed, 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). 7.2.1.6.4 List of Managed Classes 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 managed 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 mechanisms described here to specify the managed persistence classes of a persistence unit. Persistence providers 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.

7.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:

javax.persistence.lock.timeout value in seconds for pessimistic lock timeout javax.persistence.query.timeout value in seconds for query timeout

10/31/08

234

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Persistence Unit Packaging Java Persistence 2.0, Public Review Draft Entity Packaging

The following properties defined by this specification are intended for use in Java SE environments.

javax.persistence.jdbc.driver fully qualified name of the driver class javax.persistence.jdbc.url driver-specific URL javax.persistence.jdbc.user username used by database connection javax.persistence.jdbc.password password for database connection validation If a persistence provider does not recognize a property (other than a property defined by this specification), the provider must ignore it. Vendors should use vendor namespaces for properties (e.g., com.acme.persistence.logging). Entries that make use of the namespace javax.persistence and its subnamespaces must not be used for vendor-specific information. The namespace javax.persistence is reserved for use by this specification.

7.2.1.8 Examples
The following are sample contents of a persistence.xml file. Example 1: <persistence-unit name="OrderManagement"/> A persistence unit named OrderManagement is created. 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 specified, 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 other means and a transaction type of RESOURCE_LOCAL is assumed. Example 2: <persistence-unit name="OrderManagement2"> <mapping-file>mappings.xml</mapping-file> </persistence-unit> A persistence unit named OrderManagement2 is created. Any annotated managed persistence classes found in the root of the persistence unit are added to the list of managed persistence classes. The mappings.xml resource exists on the classpath and any classes and mapping information contained in it are used as specified above. If a META-INF/orm.xml file exists, any classes and mapping information contained in it are used as well. The transaction type, data source, and provider are as described above.

JSR-317 Public Review Draft

235

10/31/08

Sun Microsystems, Inc.


Entity Packaging Java Persistence 2.0, Public Review Draft Persistence Unit Packaging

Example 3: <persistence-unit name="OrderManagement3"> <jar-file>order.jar</jar-file> <jar-file>order-supplemental.jar</jar-file> </persistence-unit> A persistence unit named OrderManagement3 is created. 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 and mapping information contained in it are used as specified above. The order.jar and order-supplemental.jar files are searched for managed persistence classes and any annotated managed persistence classes found in them and/or any classes specified in the orm.xml files of these jar files are added. The transaction-type, data source and provider are as described above. 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 file order-mappings.xml is read as a resource and any classes referenced by it and mapping information contained in it are used. The annotated 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 assumed to be 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> A persistence unit named OrderManagement5 is created. Any annotated managed persistence classes found in the root of the persistence unit are added to the list of managed classes. The order1.xml and order2.xml files are read as resources and any classes referenced by them and mapping information contained in them are also used as specified above. The order.jar is a jar file on the classpath containing another persistence unit, while order-supplemental.jar is just a library of classes. Both of these jar files are searched for annotated managed persistence classes and any annotated managed persistence classes found in them and any classes specified in the orm.xml files (if any) of these jar files are added. The provider com.acme.AcmePersistence must be used.
10/31/08

236

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Persistence Unit Packaging Java Persistence 2.0, Public Review Draft Entity Packaging

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.

7.2.2 Persistence Unit Scope


An EJB-JAR, WAR, application client jar, or EAR can define a persistence unit. When referencing a persistence unit using the unitName annotation element or persistence-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 components 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 persistence unit whose name, as specified in the name element of the persistence.xml file, is myPersistenceUnit 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.

JSR-317 Public Review Draft

237

10/31/08

Sun Microsystems, Inc.


Entity Packaging Java Persistence 2.0, Public Review Draft persistence.xml Schema

7.3 persistence.xml Schema


This section provides the XML schema for the persistence.xml file.
<?xml version="1.0" encoding="UTF-8"?> <!-- persistence.xml schema --> <xsd:schema targetNamespace="http://java.sun.com/xml/ns/persistence" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:persistence="http://java.sun.com/xml/ns/persistence" elementFormDefault="qualified" attributeFormDefault="unqualified" version="2.0"> <xsd:annotation> <xsd:documentation> @(#)persistence_2_0.xsd 1.0 </xsd:documentation> </xsd:annotation> <xsd:annotation> <xsd:documentation><![CDATA[

August 27 2008

This is the XML Schema for the persistence configuration file. The file must be named "META-INF/persistence.xml" in the persistence archive. Persistence configuration files must indicate the persistence schema by using the persistence namespace: http://java.sun.com/xml/ns/persistence and indicate the version of the schema by using the version element as shown below: <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_2_0.xsd" version="2.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="1" maxOccurs="unbounded"> <xsd:complexType> <xsd:annotation> <xsd:documentation>

10/31/08

238

JSR-317 Public Review Draft

Sun Microsystems, Inc.


persistence.xml Schema Java Persistence 2.0, Public Review Draft Entity Packaging

Configuration of a persistence unit. </xsd:documentation> </xsd:annotation> <xsd:sequence> <!-- **************************************************** --> <xsd:element name="description" type="xsd:string" minOccurs="0"> <xsd:annotation> <xsd:documentation> Description of this persistence unit. </xsd:documentation> </xsd:annotation> </xsd:element> <!-- **************************************************** --> <xsd:element name="provider" type="xsd:string" minOccurs="0"> <xsd:annotation> <xsd:documentation> Provider class that supplies EntityManagers for this persistence unit. </xsd:documentation> </xsd:annotation> </xsd:element> <!-- **************************************************** --> <xsd:element name="jta-data-source" type="xsd:string" minOccurs="0"> <xsd:annotation> <xsd:documentation> The container-specific name of the JTA datasource to use. </xsd:documentation> </xsd:annotation> </xsd:element> <!-- **************************************************** --> <xsd:element name="non-jta-data-source" type="xsd:string" minOccurs="0"> <xsd:annotation> <xsd:documentation> The container-specific name of a non-JTA datasource to use. </xsd:documentation> </xsd:annotation> </xsd:element> <!-- **************************************************** --> <xsd:element name="mapping-file" type="xsd:string" minOccurs="0" maxOccurs="unbounded"> <xsd:annotation> <xsd:documentation>

JSR-317 Public Review Draft

239

10/31/08

Sun Microsystems, Inc.


Entity Packaging Java Persistence 2.0, Public Review Draft persistence.xml Schema

File containing mapping information. Loaded as a resource by the persistence provider. </xsd:documentation> </xsd:annotation> </xsd:element> <!-- **************************************************** --> <xsd:element name="jar-file" type="xsd:string" minOccurs="0" maxOccurs="unbounded"> <xsd:annotation> <xsd:documentation> Jar file that should be scanned for entities. Not applicable to Java SE persistence units. </xsd:documentation> </xsd:annotation> </xsd:element> <!-- **************************************************** --> <xsd:element name="class" type="xsd:string" minOccurs="0" maxOccurs="unbounded"> <xsd:annotation> <xsd:documentation> Class to scan for annotations. It should be annotated with either @Entity, @Embeddable or @MappedSuperclass. </xsd:documentation> </xsd:annotation> </xsd:element> <!-- **************************************************** --> <xsd:element name="exclude-unlisted-classes" type="xsd:boolean" default="false" minOccurs="0"> <xsd:annotation> <xsd:documentation> 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:element name="properties" minOccurs="0"> <xsd:annotation> <xsd:documentation> A list of vendor-specific properties. </xsd:documentation> </xsd:annotation> <xsd:complexType> <xsd:sequence> <xsd:element name="property" minOccurs="0" maxOccurs="unbounded">

10/31/08

240

JSR-317 Public Review Draft

Sun Microsystems, Inc.


persistence.xml Schema Java Persistence 2.0, Public Review Draft Entity Packaging

<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:attribute name="name" type="xsd:string" use="required"> <xsd:annotation> <xsd:documentation> Name used in code to reference this persistence unit. </xsd:documentation> </xsd:annotation> </xsd:attribute> <!-- **************************************************** --> <xsd:attribute name="transaction-type" type="persistence:persistence-unit-transaction-type"> <xsd:annotation> <xsd:documentation> Type of transactions used by EntityManagers from this persistence unit. </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> public enum TransactionType { JTA, RESOURCE_LOCAL }; </xsd:documentation> </xsd:annotation> <xsd:restriction base="xsd:token"> <xsd:enumeration value="JTA"/> <xsd:enumeration value="RESOURCE_LOCAL"/>

JSR-317 Public Review Draft

241

10/31/08

Sun Microsystems, Inc.


Entity Packaging Java Persistence 2.0, Public Review Draft persistence.xml Schema

</xsd:restriction> </xsd:simpleType> </xsd:schema>

10/31/08

242

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Java EE Deployment Java Persistence 2.0, Public Review Draft Container and Provider Contracts for Deploy-

C ha p t e r 8

Container and Provider Contracts for Deployment and Bootstrapping

This chapter defines requirements on the Java EE container and on the persistence provider for deployment and bootstrapping.

8.1 Java EE Deployment


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.

8.1.1 Responsibilities of the Container


At deployment time the container is responsible for scanning the locations specified in Section 7.2 and discovering the persistence.xml files and processing them.

JSR-317 Public Review Draft

243

10/31/08

Sun Microsystems, Inc.


Container and Provider Contracts for Deployment and BootstrappingJava Persistence 2.0, Public Review 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_2_0.xsd or persistence_1_0.xsd schema and report any validation errors. Provider or data source information 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.persistence.spi.PersistenceProvider implementation class for each deployed named persistence unit. It creates an instance of this implementation class and invokes the createContainerEntityManagerFactory method on that instance. The metadatain the form of a PersistenceUnitInfo classis 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 EntityManagerFactory 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.

8.1.2 Responsibilities of the Persistence Provider


The persistence provider must implement the PersistenceProvider SPI and be able to process the metadata that is passed to it at the time createContainerEntityManagerFactory method is called. An instance of EntityManagerFactory is created using the PersistenceUnitInfo metadata for the factory. The factory is then returned to the container. 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 object/relational mapping schema and report any validation errors. The object relational mapping file must specify the object/relational mapping schema that it is written against by indicating the version element. Object relational mapping files for applications written to the Java Persistence 2.0 API should conform to the orm_2_0.xsd schema. In Java SE environments, the persistence provider must validate the persistence.xml file against the persistence_2_0.xsd or persistence_1_0.xsd schema and report any validation errors.

8.1.3 javax.persistence.spi.PersistenceProvider
The interface javax.persistence.spi.PersistenceProvider is implemented by the persistence provider.

10/31/08

244

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Java EE Deployment Java Persistence 2.0, Public Review Draft Container and Provider Contracts for Deploy-

It is invoked by the container in Java EE environments. It is invoked by the javax.persistence.Persistence class in Java SE environments. The javax.persistence.spi.PersistenceProvider implementation is not intended to be used by the application. The PersistenceProvider class must have a public no-arg constructor. The properties used in the createEntityManagerFactory method in Java SE environments are described further in section 8.1.3.1 below. 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 createContainerEntityManagerFactory(PersistenceUnitInfo info, Map map); }

JSR-317 Public Review Draft

245

10/31/08

Sun Microsystems, Inc.


Container and Provider Contracts for Deployment and BootstrappingJava Persistence 2.0, Public Review Draft Java EE Deployment

8.1.3.1 Persistence Unit Properties


Persistence unit properties and hints may be passed to persistence providers in the Map parameter of the createEntityManagerFactory(String, Map) method. These properties correspond to the elements in the persistence.xml file. When any of these properties are specified in the Map parameter, their values override the values of the corresponding elements in the persistence.xml file for the named persistence unit. They also override any defaults that the provider might have applied. The properties listed below are defined by this specification.

javax.persistence.lock.timeout value in seconds for pessimistic lock timeout. See section 3.4.4.3.

javax.persistence.query.timeout value in seconds for query timeout. See


section 3.6.4.

javax.persistence.provider corresponds to the provider element in the persistence.xml. See section 7.2.1.4.

javax.persistence.transactionType corresponds to the transaction-type attribute in the persistence.xml. See section 7.2.1.2.

javax.persistence.jtaDataSource corresponds to the jta-data-source


element in the persistence.xml. See section 7.2.1.5.

javax.persistence.nonJtaDataSource

corresponds to non-jta-data-source element in the persistence.xml. See section 7.2.1.5.

the

Any number of vendor-specific properties may also be included in the map. Properties that are not recognized by a vendor must be ignored. Vendors should use vendor namespaces for properties (e.g., com.acme.persistence.logging). Entries that make use of the namespace javax.persistence and its subnamespaces must not be used for vendor-specific information. The namespace javax.persistence is reserved for use by this specification.

10/31/08

246

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Java EE Deployment Java Persistence 2.0, Public Review Draft Container and Provider Contracts for Deploy-

8.1.4 javax.persistence.spi.PersistenceUnitInfo Interface


package javax.persistence.spi; import javax.sql.DataSource; /** * Interface implemented by the container and used by the * persistence provider when creating an EntityManagerFactory. */ public interface PersistenceUnitInfo { /** * @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
JSR-317 Public Review Draft

247

10/31/08

Sun Microsystems, Inc.


Container and Provider Contracts for Deployment and BootstrappingJava Persistence 2.0, Public Review Draft Java EE Deployment

* from the application classpath. * Each mapping file name corresponds to a <mapping-file> * element in the persistence.xml file. */ public List<String> getMappingFileNames(); /** * 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(); /**

10/31/08

248

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Java EE Deployment Java Persistence 2.0, Public Review Draft Container and Provider Contracts for Deploy-

* @return ClassLoader that the provider may use to load any * classes, resources, or open URLs. */ public ClassLoader getClassLoader(); /** * Add a transformer supplied by the provider that will be * called for every new class definition or class redefinition * that gets loaded by the loader returned by the * PersistenceUnitInfo.getClassLoader method. The transformer * has no effect on the result returned by the * PersistenceUnitInfo.getNewTempClassLoader method. * Classes are only transformed once within the same classloading * scope, regardless of how many persistence units they may be * a part of. * * @param transformer A provider-supplied transformer that the * Container invokes at class-(re)definition time */ public void addTransformer(ClassTransformer transformer); /** * 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(); } The enum javax.persistence.spi.PersistenceUnitTransactionType defines whether the entity managers created by the factory will be JTA or resource-local entity managers. public enum PersistenceUnitTransactionType { JTA, RESOURCE_LOCAL }

JSR-317 Public Review Draft

249

10/31/08

Sun Microsystems, Inc.


Container and Provider Contracts for Deployment and BootstrappingJava Persistence 2.0, Public Review Draft Bootstrapping in Java

The javax.persistence.spi.ClassTransformer interface is implemented by a persistence provider that wants to transform entities and managed classes at class load time or at class redefinition time. 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; }

8.2 Bootstrapping in Java SE Environments


In Java SE environments, the Persistence.createEntityManagerFactory method is used by the application to create an entity manager factory[63].

[63] Use of these Java SE bootstrapping APIs may be supported in Java EE containers; however, support for such use is not required.

10/31/08

250

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Bootstrapping in Java SE Environments Java Persistence 2.0, Public Review Draft Container and Provider Contracts for Deploy-

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 Persistence 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.persistence.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 The contents of the META-INF/services/javax.persistence.spi.PersistenceProvider file is nothing more than the name of the implementation class: com.acme.PersistenceProvider. Persistence provider jars may be installed or made available in the same ways as other service providers, 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 configuration 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.

The javax.persistence.provider property was included in the Map passed to createEntityManagerFactory and the value of the property is the providers implementation class.

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.

JSR-317 Public Review Draft

251

10/31/08

Sun Microsystems, Inc.


Container and Provider Contracts for Deployment and BootstrappingJava Persistence 2.0, Public Review Draft Bootstrapping in Java

8.2.1 javax.persistence.Persistence Class


package javax.persistence; import java.util.*; ... /** * Bootstrap class that is used to obtain an * EntityManagerFactory. */ public class Persistence { /** * Create and return an EntityManagerFactory for the * named persistence unit. * * @param persistenceUnitName The name of the persistence unit * @return The factory that creates EntityManagers configured * according to the specified persistence unit */ public static EntityManagerFactory createEntityManagerFactory(String persistenceUnitName) {...} /** * 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 createEntityManagerFactory(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.

javax.persistence.lock.timeout value in seconds for pessimistic lock timeout

javax.persistence.query.timeout value in seconds for query timeout javax.persistence.jdbc.driver value is the fully qualified name of the driver
class

javax.persistence.jdbc.url value is the driver-specific URL

10/31/08

252

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Bootstrapping in Java SE Environments Java Persistence 2.0, Public Review Draft Container and Provider Contracts for Deploy-

javax.persistence.jdbc.user value is the username used by database connection

javax.persistence.jdbc.password value is the password for database connection validation

javax.persistence.dataSource

value is instance of javax.sql.DataSource to be used for the specified persistence unit

If a persistence provider does not recognize a property (other than a property defined by this specification), the provider must ignore it. Vendors should use vendor namespaces for properties (e.g., com.acme.persistence.logging). Entries that make use of the namespace javax.persistence and its subnamespaces must not be used for vendor-specific information. The namespace javax.persistence is reserved for use by this specification.

JSR-317 Public Review Draft

253

10/31/08

Sun Microsystems, Inc.


Container and Provider Contracts for Deployment and BootstrappingJava Persistence 2.0, Public Review Draft Bootstrapping in Java

10/31/08

254

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Entity Java Persistence 2.0, Public Review Draft Metadata Annotations

C ha p t e r 9

Metadata Annotations

This chapter and chapter 10 define the metadata annotations introduced by this specification. The XML schema defined in chapter 11 provides an alternative to the use of metadata annotatations. These annotations are in the package javax.persistence.

9.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. @Target(TYPE) @Retention(RUNTIME) public @interface Entity { String name() default ""; }

JSR-317 Public Review Draft

255

10/31/08

Sun Microsystems, Inc.


Metadata Annotations Java Persistence 2.0, Public Review Draft Callback Annotations

9.2 Callback Annotations


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(); } The ExcludeSuperclassListeners annotation specifies that the invocation of superclass listeners is to be excluded for the entity class (or mapped superclass) and its subclasses. @Target({TYPE}) @Retention(RUNTIME) public @interface ExcludeSuperclassListeners { } The ExcludeDefaultListeners annotation specifies that the invocation of default listeners is to be excluded for the entity class (or mapped superclass) and its subclasses. @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 {}

10/31/08

256

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Queries Java Persistence 2.0, Public Review Draft Metadata Annotations

9.3 Annotations for Queries


9.3.1 NamedQuery Annotation
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 (); }

9.3.2 NamedNativeQuery Annotation


The NamedNativeQuery annotation is used to specify a native SQL named query. The name element is used to refer to the query when using the EntityManager methods that create query objects. The query element specifies the native query. 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.

JSR-317 Public Review Draft

257

10/31/08

Sun Microsystems, Inc.


Metadata Annotations Java Persistence 2.0, Public Review 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. The NamedNativeQuery and NamedNativeQueries annotations can be applied to an entity or mapped superclass. @Target({TYPE}) @Retention(RUNTIME) public @interface NamedNativeQuery { String name(); String query(); QueryHint[] hints() default {}; Class resultClass() default void.class; String resultSetMapping() default ""; // name of SqlResultSetMapping } @Target({TYPE}) @Retention(RUNTIME) public @interface NamedNativeQueries { NamedNativeQuery[] value (); }

9.3.3 Annotations for SQL Query Result Set Mappings


The SqlResultSetMapping annotation is used to specify the mapping of the result of a native SQL query. @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 entityClass element specifies the class of the result. The fields element is used to map the columns specified in the SELECT list of the query to the properties or fields of the entity class.

10/31/08

258

JSR-317 Public Review Draft

Sun Microsystems, Inc.


References to EntityManager and EntityManagerFactoryJava Persistence 2.0, Public Review 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 clausei.e., column aliases, if applicable. @Target({}) @Retention(RUNTIME) public @interface ColumnResult { String name(); }

9.4 References to EntityManager and EntityManagerFactory


These annotations are used to express dependencies on entity managers and entity manager factories.

9.4.1 PersistenceContext Annotation


The PersistenceContext annotation is used to express a dependency on a container-managed entity manager and its associated persistence context. 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 persistence provider by the container when the entity manager is created. Properties that are not recognized by a vendor must be ignored.

JSR-317 Public Review Draft

259

10/31/08

Sun Microsystems, Inc.


Metadata Annotations Java Persistence 2.0, Public Review Draft References to EntityManager and EntityMan-

@Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface PersistenceContext{ String name() default ""; String unitName() default ""; PersistenceContextType type default TRANSACTION; PersistenceProperty[] properties() default {}; } public enum PersistenceContextType { TRANSACTION, EXTENDED } @Target({}) @Retention(RUNTIME) public @interface PersistenceProperty { String name(); String value(); } @Target({TYPE}) @Retention(RUNTIME) public @interface PersistenceContexts{ PersistenceContext[] value(); }

9.4.2 PersistenceUnit Annotation


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 environment 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 persistence.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, METHOD, FIELD}) @Retention(RUNTIME) public @interface PersistenceUnit{ String name() default ""; String unitName() default ""; } @Target(TYPE) @Retention(RUNTIME) public @interface PersistenceUnits{ PersistenceUnit[] value(); }

10/31/08

260

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata for Object/Relational Mapping

C ha p t e r 1 0

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 relationships 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 specification. Portable applications should not rely upon the use of DDL generation.

10.1 Annotations for Object/Relational Mapping


These annotations and types are in the package javax.persistence. XML metadata may be used as an alternative to these annotations, or to override or augment annotations, as described in Chapter 11.

JSR-317 Public Review Draft

261

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations for Object/Relational Mapping

10.1.1 Access Annotation


The Access annotation is used to specify an access type to be applied to an entity class, mapped superclass, or embeddable class, or to a specific attribute of such a class. @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface Access { AccessType value(); } public enum AccessType { FIELD, PROPERTY } Table 4 lists the annotation elements that may be specified for the Access annotation.

Table 4

Access Annotation Elements


Type AccessType Name value Description (Required) The access type to be applied to the class or attribute. Default

10.1.2 AssociationOverride Annotation


The AssociationOverride annotation is used to override a mapping for an entity relationship. The AssociationOverride annotation may be applied to an entity that extends a mapped superclass to override a many-to-one or one-to-one mapping defined by the mapped superclass. If the AssociationOverride 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 AssociationOverride annotation is applied to the entity class. The AssociationOverride annotation may be used to override a relationship mapping from an embeddable within an entity to another entity when the embeddable is on the owning side of the relationship. When used to override a relationship mapping defined by an embeddable class (including an embeddable class embedded within another embeddable class), the AssociationOverride annotation is applied to the field or property containing the embeddable. When the AssociationOverride annotation is used to override a relationship mapping from an embeddable class, the name element specifies the referencing relationship field or property within the embeddable class. To override mappings at multiple levels of embedding, a dot (".") notation syntax 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. When the AssociationOverride annotation is applied to override the mappings of an embeddable class used as a map value, "value." must be used to prefix the name of the attribute within the embeddable class that is being overridden in order to specify it as part of the map value.[64]

10/31/08

262

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata for Object/Relational Mapping

If the relationship mapping is a foreign key mapping, the joinColumns element of the AssociationOverride 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.[65] Table 5 lists the annotation elements that may be specified for the AssociationOverride annotation. The joinColumns element refers to the table for the class that contains the annotation. @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface AssociationOverride { String name(); JoinColumn[] joinColumns() default {}; JoinTable joinTable() default @JoinTable; } Table 5 AssociationOverride Annotation Elements
Type String Name name Description (Required) The name of the relationship property whose mapping is being overridden if property-based access is being used, or the name of the relationship field if field-based access is used. The join column that is being mapped to the persistent 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 element must not be specified if a join table is used in the overriding of the mapping of the relationship The join table that maps the relationship. The joinTable 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. . Default

JoinColumn[]

joinColumns

JoinTable

joinTable

[64] The use of map keys that contain embeddables that reference entities is not permitted. [65] Note that either the joinColumns element or the joinTable element of the AssociationOverride annotation is specified for overriding a given relationship (but never both).

JSR-317 Public Review Draft

263

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations for Object/Relational Mapping

Example 1: @MappedSuperclass public class Employee { @Id protected Integer id; @Version protected Integer version; @ManyToOne protected Address address; public public public public } @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 ContactInfo 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; } Integer getId() { ... } void setId(Integer id) { ... } Address getAddress() { ... } void setAddress(Address address) { ... }

10/31/08

264

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata for Object/Relational Mapping

10.1.3 AssociationOverrides Annotation


The mappings of multiple many-to-one or one-to-one relationship properties or fields may be overridden. The AssociationOverrides annotation is used for this purpose. @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface AssociationOverrides { AssociationOverride[] value(); } Table 6 lists the annotation elements that may be specified for the AssociationOverrides annotation.

Table 6

AssociationOverrides Annotation Elements


Type AssociationOverride[] Name value Description (Required) The association override mappings that are to be applied to the relationship field or property. Default

Example: @MappedSuperclass public class Employee { @Id protected Integer id; @Version protected Integer version; @ManyToOne protected Address address; @OneToOne protected Locker locker; public public public public public public } @Entity @AssociationOverrides({ @AssociationOverride(name="address", joinColumns=@JoinColumn("ADDR_ID")), @AssociationOverride(name="locker", joinColumns=@JoinColumn("LCKR_ID"))}) public PartTimeEmployee { ... } Integer getId() { ... } void setId(Integer id) { ... } Address getAddress() { ... } void setAddress(Address address) { ... } Locker getLocker() { ... } void setLocker(Locker locker) { ... }

10.1.4 AttributeOverride Annotation


The AttributeOverride annotation is used to override the mapping of a Basic (whether explicit or default) property or field or Id property or field.

JSR-317 Public Review Draft

265

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations for Object/Relational Mapping

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). The AttributeOverride annotation may be applied to an element collection containing instances of an embeddable class or to a map collection whose key and/or value is an embeddable class. When the AttributeOverride annotation is applied to a map, "key." or "value." must be used to prefix the name of the attribute that is being overridden in order to specify it as part of the map key or map value. 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 7 lists the annotation elements that may be specified for the AttributeOverride annotation. The column element refers to the table for the class that contains the annotation. @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface AttributeOverride { String name(); Column column(); } Table 7 AttributeOverride Annotation Elements
Type String Name name Description (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. (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. Default

Column

column

10/31/08

266

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata for Object/Relational Mapping

Example 1: @MappedSuperclass public class Employee { @Id protected Integer id; @Version protected Integer version; protected String address; public public public public } @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) { ... } } Example 2: @Embeddable protected protected protected @Embedded } public class Address { String street; String city; String state; protected Zipcode zipcode; Integer getId() { ... } void setId(Integer id) { ... } String getAddress() { ... } void setAddress(String address) { ... }

@Embeddable public class ZipCode { protected String zip; protected String plusFour; } @Entity public class Customer { @Id protected Integer id; protected String name; @AttributeOverrides({ @AttributeOverride(name="state", column=@Column(name="ADDR_STATE")), @AttributeOverride(name="zipcode.zip", column= @Column(name="ADDR_ZIP")) }) @Embedded protected Address address; ... }

JSR-317 Public Review Draft

267

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations for Object/Relational Mapping

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; } @Embeddable public class PropertyInfo { Integer parcelNumber; Integer size; BigDecimal tax; }

10.1.5 AttributeOverrides Annotation


The mappings of multiple properties or fields may be overridden. The AttributeOverrides annotation is used for this purpose. @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface AttributeOverrides { AttributeOverride[] value(); } Table 8 lists the annotation elements that may be specified for the AttributeOverrides annotation.

Table 8

AtributeOverrides Annotation Elements


Type AttributeOverride[] Name value Description (Required) The AttributeOverride mappings that are to be applied to the field or property. Default

10/31/08

268

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata 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() { ... }

10.1.6 Basic Annotation


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 annotation is not specified for such a field or property, the default values of the Basic annotation will apply. @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Basic { FetchType fetch() default EAGER; boolean optional() default true; } Table 9 lists the annotation elements that may be specified for the Basic annotation and their default values. The FetchType enum defines strategies for fetching data from the database: public enum FetchType { LAZY, EAGER }; 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. The optional element is a hint as to whether the value of the field or property may be null. It is disregarded for primitive types.

JSR-317 Public Review Draft

269

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations for Object/Relational Mapping

Table 9

Basic Annotation Elements


Type FetchType Name fetch Description (Optional) Whether the value of the field or property should be lazily loaded or must be eagerly fetched. The EAGER strategy is a requirement on the persistence provider runtime that the value must be eagerly fetched. The LAZY strategy is a hint to the persistence provider runtime. (Optional) Whether the value of the field or property may be null. This is a hint and is disregarded for primitive types; it may be used in schema generation. Default EAGER

boolean

optional

true

Example 1: @Basic protected String name; Example 2: @Basic(fetch=LAZY) protected String getName() { return name; }

10.1.7 CollectionTable Annotation


The CollectionTable annotation is used in the mapping of collections of basic or embeddable types. The CollectionTable annotation specifies the table that is used for the mapping of the collection and is specified on the collection-valued field or property. @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface CollectionTable { String name() default ""; String catalog() default ""; String schema() default ""; JoinColumn[] joinColumns() default {}; UniqueConstraint[] uniqueConstraints() default {}; } 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 values of the Column annotation, as described in Section 10.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. 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.

10/31/08

270

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata for Object/Relational Mapping

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 OpenIssue: Should we introduce another annotation (e.g., ValueColumn or ElementColumn to be used instead of Column for this purpose?) To override these defaults for an embeddable class, the AttributeOverride and/or AttributeOverrides annotations must be used in addition to the ElementCollection annotation. The value of the table element of the Column annotation used in the AttributeOverride annotation 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. If the CollectionTable annotation is missing, the default values of the CollectionTable annotation elements apply. Table 10 lists the annotation elements that may be specified for the CollectionTable annotation and their default values.

Table 10

CollectionTable Annotation Elements


Type String Name name Description (Optional) The name of the collection table. Default The concatenation of the name of the containing entity and the name of the collection attribute, separated by an underscore. Default catalog. Default schema for user. (Default only applies if a single join column is used.) The same defaults as for JoinColumn (i.e., the concatenation of the following: the name of the entity; "_"; the name of the referenced primary key column.) However, if there is more than one join column, a JoinColumn annotation must be specified for each join column using the JoinColumns annotation. Both the name and the referencedColumnName elements must be specified in each such JoinColumn annotation. No additional constraints

String String JoinColumn[]

catalog schema joinColumns

(Optional) The catalog of the table. (Optional) The schema of the table. (Optional) The foreign key columns of the collection table which reference the primary table of the entity.

UniqueConstraint[]

uniqueConstraints

(Optional) Unique constraints that are to be placed on the table. These are only used if table generation is in effect.

JSR-317 Public Review Draft

271

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations for Object/Relational Mapping

Example: @Embeddable protected protected protected ... } public String String String class Address { street; city; state;

@Entity public class Person { @Id protected String ssn; protected String name; protected Address home; @ElementCollection // use default table (PERSON_NICKNAMES) @Column(name="name", length=50) protected Set<String> nickNames = new HashSet(); ... } @Entity public class WealthyPerson extends Person { @ElementCollection @CollectionTable(name="HOMES") // use default join column name @AttributeOverrides({ @AttributeOverride(name="street", column=@Column(name="HOME_STREET")), @AttributeOverride(name="city", column=@Column(name="HOME_CITY")), @AttributeOverride(name="state", column=@Column(name="HOME_STATE")) }) protected Set<Address> vacationHomes = new HashSet(); ... }

10.1.8 Column Annotation


The Column annotation is used to specify a mapped column for a persistent property or field. Table 11 lists the annotation elements that may be specified for the Column annotation and their default values.

10/31/08

272

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata for Object/Relational Mapping

If no Column annotation is specified, the default values in Table 11 apply. @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Column { String name() default ""; boolean unique() default false; boolean nullable() default true; boolean insertable() default true; boolean updatable() default true; String columnDefinition() default ""; String table() default ""; int length() default 255; int precision() default 0; // decimal precision int scale() default 0; // decimal scale } Table 11 Column Annotation Elements
Type String boolean Name name unique Description (Optional) The name of the column. (Optional) Whether the column is a unique key. This 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. (Optional) Whether the database column is nullable. (Optional) Whether the column is included in SQL INSERT statements generated by the persistence provider. (Optional) Whether the column is included in SQL UPDATE statements generated by the persistence provider. (Optional) The SQL fragment that is used when generating the DDL for the column. (Optional) The name of the table that contains the column. If absent the column is assumed to be in the primary table for the mapped object. (Optional) The column length. (Applies only if a string-valued column is used.) (Optional) The precision for a decimal (exact numeric) column. (Applies only if a decimal column is used.) (Optional) The scale for a decimal (exact numeric) column. (Applies only if a decimal column is used.) Default The property or field name false

boolean boolean

nullable insertable

true true

boolean

updatable

true

String

columnDefinition

Generated SQL to create a column of the inferred type. Column is in primary table. 255 0 (Value must be set by developer.) 0

String

table

int int

length precision

int

scale

JSR-317 Public Review Draft

273

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations for Object/Relational Mapping

Example 1: @Column(name="DESC", nullable=false, length=512) public String getDescription() { return description; } Example 2: @Column(name="DESC", columnDefinition="CLOB NOT NULL", table="EMP_DETAIL") @Lob public String getDescription() { return description; } Example 3: @Column(name="ORDER_COST", updatable=false, precision=12, scale=2) public BigDecimal getCost() { return cost; }

10.1.9 DiscriminatorColumn Annotation


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. The DiscriminatorColumn annotation can be specified on an entity class (including on an abstract entity class). If the DiscriminatorColumn annotation is missing, and a discriminator column is required, the name of the discriminator column defaults to "DTYPE" and the discriminator type to STRING. Table 12 lists the annotation elements that may be specified for the DiscriminatorColumn annotation and their default values. The supported discriminator types are defined by the DiscriminatorType enum: public enum DiscriminatorType { STRING, CHAR, INTEGER }; 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; }

10/31/08

274

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata for Object/Relational Mapping

Table 12

DiscriminatorColumn Annotation Elements


Type String DiscriminatorTy pe String Name name discriminatorType Description (Optional) The name of column to be used for the discriminator. (Optional) The type of object/column to use as a class discriminator. Default DTYPE DiscriminatorType.STRING

columnDefinition

(Optional) The SQL fragment that is used when generating the DDL for the discriminator column. (Optional) The column length for String-based discriminator types. Ignored for other discriminator types.

Provider-generated SQL to create a column of the specified discriminator type. 31

int

length

Example: @Entity @Table(name="CUST") @DiscriminatorColumn(name="DISC", discriminatorType=STRING,length=20) public class Customer { ... } @Entity public class ValuedCustomer extends Customer { ... }

10.1.10 DiscriminatorValue Annotation


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 concrete entity class. If the DiscriminatorValue annotation is not specified and a discriminator column 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 13 lists the annotation elements that may be specified for the DiscriminatorValue annotation and their default values.

JSR-317 Public Review Draft

275

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations 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(); } Table 13 DiscriminatorValueAnnotation Elements
Type String Name value Description (Optional) The value that indicates that the row is an entity of the annotated entity type. Default If the DiscriminatorValue annotation is not specified, a provider-specific function to generate a value representing the entity type is used for the value of the discriminator column. If the DiscriminatorType is STRING, the discriminator 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 { ... }

10.1.11 ElementCollection Annotation


The ElementCollection annotation defines a collection of instances of a basic type or embeddable class. The ElementCollection annotation (or equivalent XML element) must be specified if the collection is to be mapped by means of a collection table.[66] @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface ElementCollection { Class targetClass() default void.class; FetchType fetch() default LAZY; } Open Issue: Better name for this annotation.

[66] If it is not specified, the rules of section 2.8 apply.

10/31/08

276

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata for Object/Relational Mapping

Table 14 lists the annotation elements that may be specified for the ElementCollection annotation and their default values.

Table 14

ElementCollection Annotation Elements


Type Class Name targetClass Description (Optional) The basic or embeddable class that is the element type of the collection. Optional only if the collection field or property is defined using Java generics. Must be specified otherwise. (Optional) Whether the collection should be lazily loaded or must be eagerly fetched. The EAGER strategy is a requirement on the persistence provider runtime that the collection elements must be eagerly fetched. The LAZY strategy is a hint to the persistence provider runtime. Default The parameterized type of the collection when defined using generics.

FetchType

fetch

LAZY

Example: @Entity public class Person { @Id protected String ssn; protected String name; @ElementCollection protected Set<String> nickNames = new HashSet(); ... }

10.1.12 Embeddable Annotation


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

JSR-317 Public Review Draft

277

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations for Object/Relational Mapping

Example 2: @Embeddable public class PhoneNumber { protected String areaCode; protected String localNumber; @ManyToOne PhoneServiceProvider provider; ... } @Entity public class PhoneServiceProvider { @Id protected String name; ... } Example 3: @Embeddable protected protected protected @Embedded } public class Address { String street; String city; String state; protected Zipcode zipcode;

@Embeddable public class ZipCode { protected String zip; protected String plusFour; }

10.1.13 Embedded Annotation


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.[67] 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. The AttributeOverride, AttributeOverrides, AssociationOverride, and AssociationOverrides annotations may be used to override mappings declared or defaulted by the embeddable class. 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). @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Embedded {}

[67] If the embeddable class is used as a primary key, the EmbeddedId rather than the Embedded annotation is used.

10/31/08

278

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata 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() { ... }

10.1.14 EmbeddedId Annotation


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.[68] The AttributeOverride annotation may be used to override the column mappings declared within the embeddable class.[69] There must be only one EmbeddedId annotation and no Id annotation when the EmbeddedId annotation is used. The MappedById annotation may be used in conjunction with the EmbeddedId annotation to specify a derived primary key. See Sections 2.4.1 and 10.1.31. @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface EmbeddedId {} Example: @EmbeddedId protected EmployeePK empPK;

10.1.15 Enumerated Annotation


An Enumerated annotation specifies that a persistent property or field should be persisted as a enumerated 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[70]. The EnumType enum defines the mapping for enumerated types. public enum EnumType { ORDINAL, STRING }
[68] Note that theId annotation is not used in the embeddable class. [69] Relationship mappings defined within an embedded id class are not supported. [70] Mapping of enum values that contain state is not supported.

JSR-317 Public Review Draft

279

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations 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. @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Enumerated { EnumType value() default ORDINAL; } Table 15 lists the annotation elements that may be specified for the Enumerated annotation and their default values.

Table 15

Enumerated Annotation Elements


Type EnumType Name value Description (Optional) The type used in mapping an enum type. Default ORDINAL

Example: public enum EmployeeStatus {FULL_TIME, PART_TIME, CONTRACT} public enum SalaryRate {JUNIOR, SENIOR, MANAGER, EXECUTIVE} @Entity public class Employee { ... public EmployeeStatus getStatus() {...} @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".

10.1.16 GeneratedValue Annotation


The GeneratedValue annotation provides for the specification of generation strategies for the values 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. [71] The use of the GeneratedValue annotation is only required to be supported for simple primary keys. Use of the GeneratedValue annotation is not supported for derived primary keys. Table 16 lists the annotation elements that may be specified for the GeneratedValue annotation and their default values.

[71] Portable applications should not use the GeneratedValue annotation on other persistent fields or properties.

10/31/08

280

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata for Object/Relational Mapping

The types of primary key generation are defined by the GenerationType enum: public enum GenerationType { TABLE, SEQUENCE, IDENTITY, AUTO }; 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.[72] The AUTO value indicates that the persistence provider should pick an appropriate strategy for the particular 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. @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface GeneratedValue { GenerationType strategy() default AUTO; String generator() default ""; } Table 16 GeneratedValue Annotation Elements
Type GenerationType String Name strategy Description (Optional) The primary key generation strategy that the persistence provider must use to generate the annotated entity primary key. (Optional) The name of the primary key generator to use as specified in the SequenceGenerator or TableGenerator annotation. Default GenerationType.AUTO

generator

Default primary key generator supplied by persistence provider.

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;

[72] Note that SEQUENCE and IDENTITY are not portable across all databases.

JSR-317 Public Review Draft

281

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations for Object/Relational Mapping

10.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. @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Id {} Example: @Id public Long getId() { return id; }

10.1.18 IdClass Annotation


The IdClass annotation is applied to an entity class or a mapped superclass to specify a composite primary key class that is mapped to multiple fields or properties of the entity. 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 Identities. 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(); } Table 17 lists the annotation elements that may be specified for the IdClass annotation.

Table 17

IdClass Annotation Elements


Type Class Name value Description (Required) The composite primary key class. Default

10/31/08

282

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata for Object/Relational Mapping

Example: @IdClass(com.acme.EmployeePK.class) @Entity public class Employee { @Id String empName; @Id Date birthDay; ... }

10.1.19 Inheritance Annotation


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. 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 strategies. The inheritance strategy options are defined by the InheritanceType enum: public enum InheritanceType { SINGLE_TABLE, JOINED, TABLE_PER_CLASS }; Support for the TABLE_PER_CLASS mapping strategy is optional in this release. [Note to readers] We would like feedback as to the importance of requiring support for the table per class mapping strategy. Table 18 lists the annotation elements that may be specified for the Inheritance annotation and their default values. @Target({TYPE}) @Retention(RUNTIME) public @interface Inheritance { InheritanceType strategy() default SINGLE_TABLE; } Table 18 Inheritance Annotation Elements
Type InheritanceType Name strategy Description (Optional) The inheritance strategy to use for the entity inheritance hierarchy. Default InheritanceType.SINGLE_TABLE

JSR-317 Public Review Draft

283

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations for Object/Relational Mapping

Example: @Entity @Inheritance(strategy=JOINED) public class Customer { ... } @Entity public class ValuedCustomer extends Customer { ... }

10.1.20 JoinColumn Annotation


The JoinColumn annotation is used to specify a mapped column for joining an entity association or element collection. Table 19 lists the annotation elements that may be specified for the JoinColumn annotation and their default values. If the JoinColumn annotation itself is defaulted, a single join column is assumed and the default values described in Table 19 apply. 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 primary 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 column using the JoinColumns annotation. Both the name and the referencedColumnName elements must be specified in each such JoinColumn annotation. @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface JoinColumn { String name() default ""; String referencedColumnName() default ""; boolean unique() default false; boolean nullable() default true; boolean insertable() default true; boolean updatable() default true; String columnDefinition() default ""; String table() default ""; }

10/31/08

284

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata for Object/Relational Mapping

Table 19

JoinColumn Annotation Elements


Type String Name name Description (Optional) The name of the foreign key column. The table in which it is found depends upon the context. If the join is for a OneToOne or ManyToOne mapping using a foreign key mapping strategy, the foreign key column is in the table of the source entity or embeddable. If the join is for a unidirectional OneToMany mapping using a foreign key mapping strategy, the foreign key is in the table of the target entity. If the join is for a ManyToMany mapping or for a one-to-one or bidirectional ManyToOne/OneToMany mapping using a join table, the foreign key is in a join table. If the join is for an element collection, the foreign key is in a collection table. (Optional) The name of the column referenced by this foreign key column. When used with entity relationship mappings other than a unidirectional OneToMany foreign key mapping, the referenced column is in the table of the target entity. When used with a unidirectional OneToMany 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 definition. When used in a collection table mapping, the referenced column is in the table of the entity containing the collection. (Optional) Whether the property is a unique key. This is a shortcut for the UniqueConstraint annotation at the table level and is useful for when the unique key constraint is only a single field. It is not necessary to explicitly specify this for a join column that corresponds to a primary key that is part of a foreign key. (Optional) Whether the foreign key column is nullable. (Optional) Whether the column is included in SQL INSERT statements generated by the persistence provider. (Optional) Whether the column is included in SQL UPDATE statements generated by the persistence provider. (Optional) The SQL fragment that is used when generating the DDL for the column. Default (Default only applies if a single join column is used.) The concatenation of the following: the name of the referencing relationship property or field of the referencing entity or embeddable class; "_"; the name of the referenced primary key column. If there is no such referencing relationship property or field in the entity, or if the join is for an element collection, the join column name is formed as the concatenation of the following: the name of the entity; "_"; the name of the referenced primary key column. (Default only applies if single join column is being used.) The same name as the primary key column of the referenced table.

String

referencedColumnName

boolean

unique

false

boolean boolean

nullable insertable

true true

boolean

updatable

true

String

columnDefinition

Generated SQL for the column.

JSR-317 Public Review Draft

285

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations for Object/Relational Mapping

Type String

Name table

Description (Optional) The name of the table that contains the column.

Default If the join is for a OneToOne or ManyToOne mapping using a foreign 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 mapping strategy, the name of the table of the target entity. If the join is for a ManyToMany mapping or for a one-to-one or bidirectional ManyToOne/OneToMany mapping using a join table, the name of the join table. If the join is for an element collection, the name of the collection table.

Example 1: @ManyToOne @JoinColumn(name="ADDR_ID") public Address getAddress() { return address; } Example 2: Unidirectional One-to-Many association using a foreign key mapping. In Customer class: @OneToMany @JoinColumn(name="CUST_ID") // join column is in table for Order public Set<Order> getOrders() {return orders;}

10.1.21 JoinColumns Annotation


Composite foreign keys are supported by means of the JoinColumns annotation. The JoinColumns 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. @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface JoinColumns { JoinColumn[] value(); } Table 20 lists the annotation elements that may be specified for the JoinColumns annotation.

10/31/08

286

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata for Object/Relational Mapping

Table 20

JoinColumns Annotation Elements


Type JoinColumn[] Name value Description (Required) The join columns that map the relationship. Default

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

10.1.22 JoinTable Annotation


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 unidirectional). Table 21 lists the annotation elements that may be specified for the JoinTable annotation and their default values. If the JoinTable annotation is not explicitly specified for the mapping of a many-to-many or unidirectional one-to-many relationship, the default values of the annotation elements apply. The name of the join table is assumed to be the table names of the associated primary tables concatenated 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 relationship. @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface JoinTable { String name() default ""; String catalog() default ""; String schema() default ""; JoinColumn[] joinColumns() default {}; JoinColumn[] inverseJoinColumns() default {}; UniqueConstraint[] uniqueConstraints() default {}; }

JSR-317 Public Review Draft

287

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations for Object/Relational Mapping

Table 21

JoinTable Annotation Elements


Type String Name name Description (Optional) The name of the join table. Default The concatenated names of the two associated primary entity tables, separated by an underscore. Default catalog. Default schema for user. The same defaults as for JoinColumn.

String String JoinColumn[]

catalog schema joinColumns

(Optional) The catalog of the table. (Optional) The schema of the table. (Optional) The foreign key columns of the join table which reference the primary table of the entity owning the association (i.e. the owning side of the association). (Optional) The foreign key columns of the join table which reference the primary table of the entity that does not own the association (i.e. the inverse side of the association). (Optional) Unique constraints that are to be placed on the table. These are only used if table generation is in effect.

JoinColumn[]

inverseJoinColumns

The same defaults as for JoinColumn.

UniqueConstraint[]

uniqueConstraints

No additional constraints

Example: @JoinTable( name="CUST_PHONE", joinColumns= @JoinColumn(name="CUST_ID", referencedColumnName="ID"), inverseJoinColumns= @JoinColumn(name="PHONE_ID", referencedColumnName="ID") )

10.1.23 Lob Annotation


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 mapping to a database Lob type. The Lob annotation may be used in conjunction with the Basic annotation. 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. @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Lob { }

10/31/08

288

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata for Object/Relational Mapping

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;

10.1.24 ManyToMany Annotation


A ManyToMany annotation defines a many-valued association with many-to-many multiplicity. If the collection is defined using generics to specify the element type, the associated target entity class does not need to be specified; otherwise it must be specified. 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[73]. 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. Table 22 lists these annotation elements that may be specified for the 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: public enum CascadeType { ALL, PERSIST, MERGE, REMOVE, REFRESH, CLEAR};

[73] The ManyToMany annotation may not be used within an embeddable class used in an element collection.

JSR-317 Public Review Draft

289

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations for Object/Relational Mapping

The value cascade=ALL is equivalent to cascade={PERSIST, REFRESH, CLEAR}. @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface ManyToMany { Class targetEntity() default void.class; CascadeType[] cascade() default {}; FetchType fetch() default LAZY; String mappedBy() default ""; }

MERGE,

REMOVE,

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?

Table 22

ManyToMany Annotation Elements


Type Class Name targetEntity Description (Optional) The entity class that is the target of the association. Optional only if the collection-valued relationship property is defined using Java generics. Must be specified otherwise. (Optional) The operations that must be cascaded to the target of the association. (Optional) Whether the association should be lazily loaded or must be eagerly fetched. The EAGER strategy is a requirement on the persistence provider runtime that the associated entities must be eagerly fetched. The LAZY strategy is a hint to the persistence provider runtime. The field or property that owns the relationship. Required unless the relationship is unidirectional. Default The parameterized type of the collection when defined using generics.

CascadeType[] FetchType

cascade fetch

No operations are cascaded. LAZY

String

mappedBy

Example 1: In Customer class: @ManyToMany @JoinTable(name="CUST_PHONES") public Set<PhoneNumber> getPhones() { return phones; }

10/31/08

290

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata for Object/Relational Mapping

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: Embeddable class used by Employee entity specifies a many-to-many relationship. @Entity public class Employee { @Id int id; @Embedded ContactInfo contactInfo; ... }

JSR-317 Public Review Draft

291

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review 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; }

10.1.25 ManyToOne Annotation


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 23 lists the annotation elements that may be specified for the ManyToOne annotation and their default values. @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface ManyToOne { Class targetEntity() default void.class; CascadeType[] cascade() default {}; FetchType fetch() default EAGER; boolean optional() default true; } 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.

Table 23

ManyToOne Annotation Elements


Type Class Name targetEntity Description (Optional) The entity class that is the target of the association. Default The type of the field or property that stores the association.

10/31/08

292

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata for Object/Relational Mapping

Type CascadeType[] FetchType

Name cascade fetch

Description (Optional) The operations that must be cascaded to the target of the association. (Optional) Whether the association should be lazily loaded or must be eagerly fetched. 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. (Optional) Whether the association is optional. If set to false then a non-null relationship must always exist.

Default No operations are cascaded. EAGER

boolean

optional

true

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

10.1.26 MapKey Annotation


The MapKey annotation is used to specify the map key for associations of type java.util.Map when the map key is itself the primary key or a persistent field or property of the entity that is the value of the map. @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface MapKey { String name() default ""; }

JSR-317 Public Review Draft

293

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations for Object/Relational Mapping

The name element designates the name of the persistent field or property of the associated entity that is used as the map key. If the name element is not specified, the primary key of the associated entity is used as the map key. If the primary key is a composite primary key and is mapped as IdClass, an instance of the primary key class is used as the key. 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. Table 24 lists the annotation elements that may be specified for the MapKey annotation.

Table 24

MapKey Annotation Elements


Type String Name name Description (Optional) The name of the persistent field or property that is used as the map key. Default The primary key is used as the map key.

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() {... } ... }

10/31/08

294

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review 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; }

10.1.27 MapKeyClass Annotation


The MapKeyClass annotation is used to specify the type of the map key for associations of type java.util.Map. The map key can be a basic type, an embeddable class, or an entity. If the map is specified using Java generics, the MapKeyClass annotation and associated type need not be specified; otherwise they must be specified. @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface MapKeyClass { Class value(); } The MapKeyClass annotation is used in conjunction with ElementCollection or one of the collection-valued relationship annotations (OneToMany or ManyToMany). The MapKey annotation is not used when MapKeyClass is specified and vice versa. Table 25 lists the annotation elements that may be specified for the MapKeyClass annotation.

Table 25

MapKeyClass Annotation Elements


Type Class Name value Description (Required) The type of the map key. Default

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

JSR-317 Public Review Draft

295

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations for Object/Relational Mapping

Example 2: // MapKeyClass and target type of relationship can be defaulted @Entity public class Item { @Id int id; ... @ElementCollection Map<String, String> images; ... } Example 3: @Entity public class Company { @Id int id; ... @OneToMany(targetEntity=com.example.VicePresident.class) @MapKeyClass(com.example.Division.class) Map organization; } Example 4: // MapKeyClass and target type of relationship are defaulted @Entity public class Company { @Id int id; ... @OneToMany Map<Division, VicePresident> organization; }

10/31/08

296

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata for Object/Relational Mapping

10.1.28 MapKeyColumn Annotation


The MapKeyColumn annotation is used to specify the mapping for the key column of a map whose map key is a basic type. If the name element is not specified, it defaults to the concatenation of the following: the name of the referencing relationship field or property; "_"; "KEY". @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface MapKeyColumn { String name() default ""; boolean unique() default false; boolean nullable() default false; boolean insertable() default true; boolean updatable() default true; String columnDefinition() default ""; String table() default ""; int length() default 255; int precision() default 0; // decimal precision int scale() default 0; // decimal scale } If no MapKeyColumn annotation is specified, the default values in Table 26 apply.

Table 26

MapKeyColumn Annotation Elements


Type String Name name Description (Optional) The name of the map key column. The table in which it is found depends upon the context. If the map key is for an element collection, the map 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 OneToMany entity relationship using a foreign key mapping strategy, the map key column is in the table of the entity that is the value of the map. (Optional) Whether the column is a unique key. This 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. (Optional) Whether the database column is nullable. (Optional) Whether the column is included in SQL INSERT statements generated by the persistence provider. Default The concatenation of the following: the name of the referencing property or field name; "_"; "KEY".

boolean

unique

false

boolean boolean

nullable insertable

true true

JSR-317 Public Review Draft

297

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations for Object/Relational Mapping

Type boolean

Name updatable

Description (Optional) Whether the column is included in SQL UPDATE statements generated by the persistence provider. (Optional) The SQL fragment that is used when generating the DDL for the column. (Optional) The name of the table that contains the column.

Default true

String

columnDefinition

Generated SQL to create a column of the inferred type. If the map key is for an element collection, the name of the collection 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 255 0 (Value must be set by developer.)

String

table

int int

length precision

(Optional) The column length. (Applies only if a string-valued column is used.) (Optional) The precision for a decimal (exact numeric) column. (Applies only if a decimal column is used.) (Optional) The scale for a decimal (exact numeric) column. (Applies only if a decimal column is used.)

int

scale

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

10/31/08

298

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata for Object/Relational Mapping

10.1.29 MapKeyJoinColumn Annotation


The MapKeyJoinColumn annotation is used to specify a mapping to an entity that is a map key. The map key join column is in the collection table, join table, or table of the target entity that is used to represent the map. @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface MapKeyJoinColumn { String name() default ""; String referencedColumnName() default ""; boolean unique() default false; boolean nullable() default false; boolean insertable() default true; boolean updatable() default true; String columnDefinition() default ""; String table() default ""; } Table 27 lists the annotation elements that may be specified for the 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 27) apply. The name annotation element defines the name of the foreign key column. The remaining annotation elements (other than referencedColumnName) refer to this column. 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 relationship 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 primary 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 referencedColumnName elements must be specified in each such MapKeyJoinColumn annotation.

JSR-317 Public Review Draft

299

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations for Object/Relational Mapping

Table 27

MapKeyJoinColumn Annotation Elements


Type String Name name Description (Optional) The name of the foreign key column for the map key. The table in which it is found depends upon the context. If the join is for a map key for an element collection, the foreign key column is in the collection table for the map value. If the join is for a map key for a ManyToMany entity relationship or for a OneToMany entity relationship using a 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 column for the map key is in the table of the entity that is the value of the map. (Optional) The name of the column referenced by this foreign key column. The referenced column is in the table of the target entity. (Optional) Whether the property is a unique key. This is a shortcut for the UniqueConstraint annotation at the table level and is useful for when the unique key constraint is only a single field. (Optional) Whether the foreign key column is nullable. (Optional) Whether the column is included in SQL INSERT statements generated by the persistence provider. (Optional) Whether the column is included in SQL UPDATE statements generated by the persistence provider. (Optional) The SQL fragment that is used when generating the DDL for the column. (Optional) The name of the table that contains the foreign key column. If the join is for a map key for an element collection, the foreign key column is in the collection table for the map value. If the join is for a map key for a ManyToMany entity relationship or for a OneToMany entity relationship using a 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 column for the map key is in the table of the entity that is the value of the map. Default (Default only applies if a single join column is used.) The concatenation of the following: the name of the referencing relationship property or field of the referencing entity or embeddable class; "_"; "KEY".

String

referencedColumnName

(Default only applies if single join column is being used.) The same name as the primary key column of the referenced table. false

boolean

unique

boolean boolean

nullable insertable

true true

boolean

updatable

true

String

columnDefinition

Generated SQL for the column. If the map is for an element collection, the name of the collection table for the map value. If the map is for a OneToMany or ManyToMany entity relationship using a join table, the name of the join table for the map. If the map 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.

String

table

10/31/08

300

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata for Object/Relational Mapping

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

10.1.30 MapKeyJoinColumns Annotation


Composite map keys referencing entities are supported by means of the MapKeyJoinColumns annotation. The MapKeyJoinColumns annotation groups MapKeyJoinColumn annotations.

JSR-317 Public Review Draft

301

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations for Object/Relational Mapping

When the MapKeyJoinColumns annotation is used, both the name and the referencedColumnName elements must be specified in each of the grouped MapKeyJoinColumn annotations. @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface MapKeyJoinColumns { MapKeyJoinColumn[] value(); } Table 28 lists the annotation elements that may be specified for the MapKeyJoinColumns annotation.

Table 28

MapKeyJoinColumns Annotation Elements


Type MapKeyJoinColumn[] Name value Description (Required) The map key join columns that are used to map to the entity that is the map key. Default

10.1.31 MappedById Annotation


The MappedById annotation is used to designate a ManyToOne or OneToOne relationship attribute that corresponds to an EmbeddedId primary key, an attribute within an EmbeddedId primary key, or a simple primary key of the parent entity. The value attribute specifies the attribute within a composite key to which the relationship attribute corresponds. If the entitys primary key is of the same Java type as the primary key of the entity referenced by the relationship, the value attribute is not specified. @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface MappedById { String value() default ""; } Open Issue: Allow MappedBy to be extended to mapping against non-id persistent attributes? Table 29 lists the annotation elements that may be specified for the MappedById annotation.

Table 29

MappedBy IdAnnotation Elements


Type String Name value Description (Optional) The name of the attribute within the composite key to which the relationship attribute corresponds. Default The relationship is mapped by the entitys primary key.

10/31/08

302

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata for Object/Relational Mapping

Example: // parent entity has simple primary key @Entity public class Employee { @Id long empId; String name; ... } // dependent entity uses EmbeddedId for composite key @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; }

10.1.32 MappedSuperclass Annotation


The MappedSuperclass annotation designates a class whose mapping information is applied to the entities that inherit from it. A mapped superclass has no separate table defined for it. 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 AttributeOverride and AttributeOverrides annotations. @Target(TYPE) @Retention(RUNTIME) public @interface MappedSuperclass {}

10.1.33 OneToMany Annotation


A OneToMany annotation defines a many-valued association with one-to-many multiplicity. Table 30 lists the annotation elements that may be specified for the 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.

JSR-317 Public Review Draft

303

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations 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[74]. 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. @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface OneToMany { Class targetEntity() default void.class; CascadeType[] cascade() default {}; FetchType fetch() default LAZY; String mappedBy() default ""; boolean orphanRemoval() default false; } When the collection is a java.util.Map, the cascade element and the orphanRemoval element apply to the map value. Open Issue: Do we need a cascade option for the map key? If so, what form should this best take? Open Issue: Ditto for orphanRemoval ?? 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)[75]. 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 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 cascade 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.

[74] The OneToMany annotation may not be used within an embeddable class used in an element collection. [75] 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.

10/31/08

304

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata for Object/Relational Mapping

Table 30

OneToMany Annotation Elements


Type Class Name targetEntity Description (Optional) The entity class that is the target of the association. Optional only if the collection-valued relationship property is defined using Java generics. Must be specified otherwise. (Optional) The operations that must be cascaded to the target of the association. (Optional) Whether the association should be lazily loaded or must be eagerly fetched. The EAGER strategy is a requirement on the persistence provider runtime that the associated entities must be eagerly fetched. The LAZY strategy is a hint to the persistence provider runtime. The field or property that owns the relationship. Required unless the relationship is unidirectional. (Optional) Whether to apply the remove operation to entities that have been removed from the relationship and to cascade the remove operation to those entities. false Default The parameterized type of the collection when defined using generics.

CascadeType[] FetchType

cascade fetch

No operations are cascaded. LAZY

String

mappedBy

boolean

orphanRemoval

Example 1: One-to-Many association using generics In Customer class: @OneToMany(cascade=ALL, mappedBy=customer, orphanRemoval=true) public Set<Order> getOrders() { return orders; } In Order class: @ManyToOne @JoinColumn(name="CUST_ID", nullable=false) public Customer getCustomer() { return customer; } Example 2: One-to-Many association without using generics In Customer class: @OneToMany(targetEntity=com.acme.Order.class, cascade=ALL, mappedBy=customer, orphanRemoval=true) public Set getOrders() { return orders; }

JSR-317 Public Review Draft

305

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations for Object/Relational Mapping

In Order class: @ManyToOne @JoinColumn(name="CUST_ID", nullable=false) protected Customer customer; Example 3: Unidirectional One-to-Many association using a foreign key mapping In Customer class: @OneToMany(orphanRemoval=true) @JoinColumn(name="CUST_ID") // join column is in table for Order public Set<Order> getOrders() {return orders;}

10.1.34 OneToOne Annotation


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 31 lists the annotation elements that may be specified for the OneToOne annotation and their default values. @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface OneToOne { Class targetEntity() default void.class; CascadeType[] cascade() default {}; FetchType fetch() default EAGER; boolean optional() default true; String mappedBy() default ""; boolean orphanRemoval() default false; } 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.

10/31/08

306

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata 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)[76]. 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 reassign an entity that has been orphaned to another relationship or otherwise attempt to persist it.

Table 31

OneToOne Annotation Elements


Type Class Name targetEntity Description (Optional) The entity class that is the target of the association. (Optional) The operations that must be cascaded to the target of the association. (Optional) Whether the association should be lazily loaded or must be eagerly fetched. 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. (Optional) Whether the association is optional. If set to false then a non-null relationship must always exist. (Optional) The field that owns the relationship. The mappedBy element is only specified on the inverse (non-owning) side of the association. (Optional) Whether to apply the remove operation to entities that have been removed from the relationship and to cascade the remove operation to those entities. false Default The type of the field or property that stores the association. No operations are cascaded. EAGER

CascadeType[] FetchType

cascade fetch

boolean

optional

true

String

mappedBy

boolean

orphanRemoval

Example 1: One-to-one association that maps a foreign key column. On Customer class: @OneToOne(optional=false) @JoinColumn( name="CUSTREC_ID", unique=true, nullable=false, updatable=false) public CustomerRecord getCustomerRecord() { return customerRecord; }

[76] 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.

JSR-317 Public Review Draft

307

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations 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; ... } Example 3: One-to-one association from an embeddable class to another entity. @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; ... }

10/31/08

308

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata for Object/Relational Mapping

10.1.35 OrderBy Annotation


The OrderBy annotation specifies the ordering of the elements of a collection-valued association or element collection at the point when the association is retrieved. @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface OrderBy { String value() default ""; } The syntax of the value ordering element is an orderby_list, as follows: orderby_list::= orderby_item [,orderby_item]* orderby_item::= property_or_field_name [ASC | DESC] 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.[77] 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 10.1.36. Table 32 lists the annotation elements that may be specified for the OrderBy annotation.

Table 32

OrderBy Annotation Elements


Type String Name value Description (Optional) The list of attributes (optionally qualified with ASC or DESC) whose values are used in the ordering. Default Ascending ordering by the primary key.

[77] 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.

JSR-317 Public Review Draft

309

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations for Object/Relational Mapping

Example 1: @Entity public class Course { ... @ManyToMany @OrderBy("lastname ASC") public List<Student> getStudents() {...}; ... } Example 2: @Entity public class Student { ... @ManyToMany(mappedBy="students") @OrderBy // PK is assumed public List<Course> getCourses() {...}; ... } Example 3: @Entity public class Person { ... @ElementCollection @OrderBy("zipcode.zip, zipcode.plusFour") public Set<Address> getResidences() {...}; ... } @Embeddable protected protected protected @Embedded } public class Address { String street; String city; String state; protected Zipcode zipcode;

@Embeddable public class ZipCode { protected String zip; protected String plusFour; }

10.1.36 OrderColumn Annotation


The OrderColumn annotation specifies a column that is used to maintain the persistent order of a list. The persistence provider is responsible for maintaining the order upon retrieval and in the database. The persistence provider is responsible for updating the ordering upon flushing to the database to reflect any insertion, deletion, or reordering affecting the list. The OrderColumn annotation is specified on a one-to-many or many-to-many relationship or on an element collection. The OrderColumn annotation is specified on the side of the relationship that references the collection that is to be ordered. The order column is not visible as part of the state of the entity or embeddable class.[78]
[78] The OrderBy annotation should be used for ordering that is visible as persistent state and maintained by the application.

10/31/08

310

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata for Object/Relational Mapping

The OrderBy annotation is not used when OrderColumn is specified. Table 33 lists the annotation elements that may be specified for the OrderColumn annotation and their default values. @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface OrderColumn { String name() default ""; boolean nullable() default true; boolean insertable() default true; boolean updatable() default true; String columnDefinition() default ""; boolean contiguous() default true; int base() default 0; String table() default ""; } If name is not specified, the column name is the concatenation of the following: the name of the referencing 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 contiguous is false, the list order cannot be (portably) queried. Open Issue: Should contiguous be included in the spec or not? 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 column, 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.

Table 33

OrderColumn Annotation Elements


Type String Name name Description (Optional) The name of the ordering column. (Optional) Whether the database column is nullable. (Optional) Whether the column is included in SQL INSERT statements generated by the persistence provider. Default The concatenation of the name of the referencing property or field;

"_"; "ORDER".
true true

boolean boolean

nullable insertable

JSR-317 Public Review Draft

311

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations for Object/Relational Mapping

Type boolean

Name updatable

Description (Optional) Whether the column is included in SQL UPDATE statements generated by the persistence provider. (Optional) The SQL fragment that is used when generating the DDL for the column. (Optional) Whether the value of the ordering column need to be contiguous or may be sparse. (Optional) The ordering column value for the first element of the list. (Optional) The name of the table that contains the column.

Default true

String

columnDefinition

Generated SQL to create a column of the inferred type. true

boolean

contiguous

int String

base table

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 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 { @Id long ccNumber; @OneToMany // unidirectional @OrderColumn List<CardTransaction> transactionHistory; ... }

10/31/08

312

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata for Object/Relational Mapping

Example 2: @Entity public class Course { ... @ManyToMany @JoinTable(name="COURSE_ENROLLMENT") public Set<Student> getStudents() {...}; ... @ManyToMany // unidirectional @JoinTable(name="WAIT_LIST") @OrderColumn("WAITLIST_ORDER") public List<Student> getWaitList() {...} } @Entity public class Student { ... @ManyToMany(mappedBy="students") public Set<Course> getCourses() {...}; ... } Example of querying the ordered list: SELECT w FROM course c JOIN c.waitlist w WHERE c.name = "geometry" AND INDEX(w) = 0

10.1.37 PrimaryKeyJoinColumn Annotation


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 SecondaryTable 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[79]. Table 34 lists the annotation elements that may be specified for the PrimaryKeyJoinColumn annotation and their default values.

[79] The derived id mechanisms described in section 2.4.1.1 are now to be preferred over PrimaryKeyJoinColumn for the OneToOne mapping case.

JSR-317 Public Review Draft

313

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations for Object/Relational Mapping

If no PrimaryKeyJoinColumn annotation is specified for a subclass in the JOINED mapping strategy, the foreign key columns are assumed to have the same names as the primary key columns of the primary table of the superclass. @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface PrimaryKeyJoinColumn { String name() default ""; String referencedColumnName() default ""; String columnDefinition() default ""; } Table 34 PrimaryKeyJoinColumn Annotation Elements
Type String Name name Description The name of the primary key column of the current table. Default The same name as the primary key column of the primary table of the superclass (JOINED mapping strategy); the same name as the primary key column of the primary table (SecondaryTable mapping); or the same name as the primary key column for the table for the referencing entity (OneToOne mapping). The same name as the primary key column of the primary table of the superclass (JOINED mapping strategy); the same name as the primary key column of the primary table (SecondaryTable mapping); or the same name as the primary key column of the table for the referenced entity (OneToOne mapping). Generated SQL to create a column of the inferred type.

String

referencedColumnName

(Optional) The name of the primary key column of the table being joined to.

String

columnDefinition

(Optional) The SQL fragment that is used when generating the DDL for the column. This should not be specified for a OneToOne primary key association.

Example: Customer and ValuedCustomer subclass @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 { ... }

10/31/08

314

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata for Object/Relational Mapping

10.1.38 PrimaryKeyJoinColumns Annotation


Composite foreign keys are supported by means of the PrimaryKeyJoinColumns annotation. The PrimaryKeyJoinColumns annotation groups PrimaryKeyJoinColumn annotations. @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface PrimaryKeyJoinColumns { PrimaryKeyJoinColumn[] value(); } Table 35 lists the annotation elements that may be specified for the PrimaryKeyJoinColumns annotation.

Table 35

PrimaryKeyJoinColumns Annotation Elements


Type PrimaryKeyJoinColumn[] Name value Description (Required) The primary key join columns. Default

Example 1: ValuedCustomer subclass @Entity @Table(name="VCUST") @DiscriminatorValue("VCUST") @PrimaryKeyJoinColumns({ @PrimaryKeyJoinColumn(name="CUST_ID", referencedColumnName="ID"), @PrimaryKeyJoinColumn(name="CUST_TYPE", referencedColumnName="TYPE") }) public class ValuedCustomer extends Customer { ... } Example 2: OneToOne relationship between Employee and EmployeeInfo classes.[80] public class EmpPK { public Integer id; public String name; }

[80] Note that the derived identity mechanisms decribed in section 2.4.1.1 is now preferred to the use of PrimaryKeyJoinColumn for this case.

JSR-317 Public Review Draft

315

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations for Object/Relational Mapping

@Entity @IdClass(com.acme.EmpPK.class) public class Employee { @Id Integer id; @Id String name; @OneToOne @PrimaryKeyJoinColumns({ @PrimaryKeyJoinColumn(name="ID", referencedColumnName="EMP_ID"), @PrimaryKeyJoinColumn(name="NAME", referencedColumnName="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; ... }

10.1.39 SecondaryTable Annotation


The SecondaryTable annotation is used to specify a secondary table for the annotated entity class. If no SecondaryTable annotation is specified, it is assumed that all persistent fields or properties of the entity are mapped to the primary table. Specifying one or more secondary tables indicates that the data for the entity class is stored across multiple tables. Table 36 lists the annotation elements that may be specified for the 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 columns 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 {}; }

10/31/08

316

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata for Object/Relational Mapping

Table 36

SecondaryTable Annotation Elements


Type String String String PrimaryKeyJoinColumn[] Name name catalog schema pkJoinColumns Description (Required) The name of the table. (Optional) The catalog of the table. (Optional) The schema of the table. (Optional) The columns that are used to join with the primary table. Default catalog Default schema for user Column(s) of the same name(s) as the primary key column(s) in the primary table No additional constraints Default

UniqueConstraint[]

uniqueConstraints

(Optional) Unique constraints that are to be placed on the table. These are typically only used if table generation is in effect. These constraints apply in addition to any constraints specified by the Column and JoinColumn annotations and constraints entailed by primary key mappings.

Example 1: Single secondary table with a single primary key column. @Entity @Table(name="CUSTOMER") @SecondaryTable(name="CUST_DETAIL", pkJoinColumns=@PrimaryKeyJoinColumn(name="CUST_ID")) public class Customer { ... } Example 2: Single secondary table with multiple primary key columns. @Entity @Table(name="CUSTOMER") @SecondaryTable(name="CUST_DETAIL", pkJoinColumns={ @PrimaryKeyJoinColumn(name="CUST_ID"), @PrimaryKeyJoinColumn(name="CUST_TYPE")}) public class Customer { ... }

10.1.40 SecondaryTables Annotation


The SecondaryTables annotation is used to specify multiple secondary tables for an entity. @Target({TYPE}) @Retention(RUNTIME) public @interface SecondaryTables { SecondaryTable[] value(); } Table 37 lists the annotation elements that may be specified for the SecondaryTables annotation.

JSR-317 Public Review Draft

317

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations for Object/Relational Mapping

Table 37

SecondaryTables Annotation Elements


Type SecondaryTable[] Name value Description (Required) The secondary tables that are used to map the entity class. Default

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 { ... }

10.1.41 SequenceGenerator Annotation


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 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 38 lists the annotation elements that may be specified for the SequenceGenerator annotation and their default values. @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface SequenceGenerator { String name(); String sequenceName() default ""; String catalog() default ""; String schema() default ""; int initialValue() default 1; int allocationSize() default 50; }

10/31/08

318

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata for Object/Relational Mapping

Table 38

SequenceGenerator Annotation Elements


Type String String Name name sequenceName Description (Required) A unique generator name that can be referenced by one or more classes to be the generator for primary key values. (Optional) The name of the database sequence object from which to obtain primary key values. (Optional) The catalog of the sequence generator. (Optional) The schema of the sequence generator. A providerchosen value Default catalog Default schema for user 1 50 Default

String String

catalog schema

int int

initialValue allocationSize

(Optional) The value from which the sequence object is to start generating. (Optional) The amount to increment by when allocating sequence numbers from the sequence.

Example: @SequenceGenerator(name="EMP_SEQ", allocationSize=25)

10.1.42 Table Annotation


The Table annotation specifies the primary table for the annotated entity. Additional tables may be specified using SecondaryTable or SecondaryTables annotation. Table 39 lists the annotation elements that may be specified for the Table annotation and their default values. If no Table annotation is specified for an entity class, the default values defined in Table 39 apply. @Target({TYPE}) @Retention(RUNTIME) public @interface Table { String name() default ""; String catalog() default ""; String schema() default ""; UniqueConstraint[] uniqueConstraints() default {}; } Table 39 Table Annotation Elements
Type String Name name Description (Optional) The name of the table. Default Entity name

JSR-317 Public Review Draft

319

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations for Object/Relational Mapping

Type String String UniqueConstraint[]

Name catalog schema uniqueConstraints

Description (Optional) The catalog of the table. (Optional) The schema of the table. (Optional) Unique constraints that are to be placed on the table. These are only used if table generation is in effect. These constraints apply in addition to any constraints specified by the Column and JoinColumn annotations and constraints entailed by primary key mappings.

Default Default catalog Default schema for user No additional constraints

Example: @Entity @Table(name="CUST", schema="RECORDS") public class Customer { ... }

10.1.43 TableGenerator Annotation


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 40 lists the annotation elements that may be specified for the TableGenerator annotation and their default values. The table element specifies the name of the table that is used by the persistence provider to store generated 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. @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface TableGenerator { String name(); String table() default ""; String catalog() default ""; String schema() default ""; String pkColumnName() default ""; String valueColumnName() default ""; String pkColumnValue() default ""; int initialValue() default 0; int allocationSize() default 50; UniqueConstraint[] uniqueConstraints() default {}; }

10/31/08

320

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata for Object/Relational Mapping

Table 40

TableGenerator Annotation Elements


Type String Name name Description (Required) A unique generator name that can be referenced by one or more classes to be the generator for primary key values. (Optional) Name of table that stores the generated primary key values. (Optional) The catalog of the table. (Optional) The schema of the table. (Optional) Name of the primary key column in the table. (Optional) Name of the column that stores the last value generated. (Optional) The primary key value in the generator table that distinguishes this set of generated values from others that may be stored in the table. (Optional) The value used to initialize the column that stores the last value generated. (Optional) The amount to increment by when allocating numbers from the generator. (Optional) Unique constraints that are to be placed on the table. These are only used if table generation is in effect. These constraints apply in addition to primary key constraints . Name is chosen by persistence provider Default catalog Default schema for user A provider-chosen name A provider-chosen name A provider-chosen value to store in the primary key column of the generator table 0 50 Default

String String String String String String

table catalog schema pkColumnName valueColumnName pkColumnValue

int int

initialValue allocationSize

Uniqu eConstraint []

uniqueConstraints

No additional constraints

Example 1: @Entity public class Employee { ... @TableGenerator( name="empGen", table="ID_GEN", pkColumnName="GEN_KEY", valueColumnName="GEN_VALUE", pkColumnValue="EMP_ID", allocationSize=1) @Id @GeneratedValue(strategy=TABLE, generator="empGen") public int id; ... }

JSR-317 Public Review Draft

321

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations for Object/Relational Mapping

Example 2: @Entity public class Address { ... @TableGenerator( name="addressGen", table="ID_GEN", pkColumnName="GEN_KEY", valueColumnName="GEN_VALUE", pkColumnValue="ADDR_ID") @Id @GeneratedValue(strategy=TABLE, generator="addressGen") public int id; ... }

10.1.44 Temporal Annotation


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. public enum TemporalType { DATE, //java.sql.Date TIME, //java.sql.Time TIMESTAMP //java.sql.Timestamp } @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Temporal { TemporalType value(); } Table 41 lists the annotation elements that may be specified for the Temporal annotation and their default values.

Table 41

Temporal Annotation Elements


Type TemporalType Name value Description (Required) The type used in mapping java.util.Date or java.util.Calendar. Default

10/31/08

322

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Annotations for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Metadata for Object/Relational Mapping

Example: @Embeddable public class EmploymentPeriod { @Temporal(DATE) java.util.Date startDate; @Temporal(DATE) java.util.Date endDate; ... }

10.1.45 Transient Annotation


The Transient annotation is used to annotate a property or field of an entity class, mapped superclass, or embeddable class. It specifies that the property or field is not persistent. @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Transient {} Example: @Entity public class Employee { @Id int id; @Transient User currentUser; ... }

10.1.46 UniqueConstraint Annotation


The UniqueConstraint annotation is used to specify that a unique constraint is to be included in the generated DDL for a primary or secondary table. Table 42 lists the annotation elements that may be specified for the UniqueConstraint annotation. @Target({}) @Retention(RUNTIME) public @interface UniqueConstraint { String[] columnNames(); } Table 42 UniqueConstraint Annotation Elements
Type String[] Name columnNames Description (Required) An array of the column names that make up the constraint. Default

JSR-317 Public Review Draft

323

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Annotations for Object/Relational Mapping

Example: @Entity @Table( name="EMPLOYEE", uniqueConstraints= @UniqueConstraint(columnNames={"EMP_ID", "EMP_NAME"}) ) public class Employee { ... }

10.1.47 Version Annotation


The Version annotation specifies the version field or property of an entity class that serves as its optimistic 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.[81] The following types are supported for version properties: int, Integer, short, Short, long, Long, Timestamp. @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Version {} Example: @Version @Column(name="OPTLOCK") protected int getVersionNum() { return versionNum; }

[81] See, however, section 4.10.

10/31/08

324

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Examples of the Application of Annotations for Object/Relational MappingJava Persistence 2.0, Public Review Draft Metadata for

10.2 Examples of the Application of Annotations for Object/Relational Mapping


10.2.1 Examples of Simple Mappings
@Entity public class Customer { @Id @GeneratedValue(strategy=AUTO) Long id; @Version protected int version; @ManyToOne Address address; @Basic String description; @OneToMany(targetEntity=com.acme.Order.class, mappedBy="customer") Collection orders = new Vector(); @ManyToMany(mappedBy="customers") Set<DeliveryService> serviceOptions = new HashSet(); public Long getId() { return id; } public Address getAddress() { return address; } public void setAddress(Address addr) { this.address = addr; } public String getDescription() { return description; } public void setDescription(String desc) { this.description = desc; } public Collection getOrders() { return orders; } public Set<DeliveryService> getServiceOptions() { return serviceOptions; } } @Entity public class Address { private Long id; private int version; private String street; @Id @GeneratedValue(strategy=AUTO) public Long getId() { return id; } protected void setId(Long id) { this.id = id; } @Version public int getVersion() { return version; } protected void setVersion(int version) { this.version = version; }

JSR-317 Public Review Draft

325

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Examples of the Application of Annotations

public String getStreet() { return street; } public void setStreet(String street) { this.street = street; } } @Entity public class Order { private private private private private Long id; int version; String itemName; int quantity; Customer cust;

@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; } public String getItemName() { return itemName; } public void setItemName(String itemName) { this.itemName = itemName; } public int getQuantity() { return quantity; } public void setQuantity(int quantity) { this.quantity = quantity; } @ManyToOne public Customer getCustomer() { return cust; } public void setCustomer(Customer cust) { this.cust = cust; } } @Entity @Table(name="DLVY_SVC") public class DeliveryService { private String serviceName; private int priceCategory; private Collection customers; @Id public String getServiceName() { return serviceName; } public void setServiceName(String serviceName) { this.serviceName = serviceName; } public int getPriceCategory() { return priceCategory; }

10/31/08

326

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Examples of the Application of Annotations for Object/Relational MappingJava Persistence 2.0, Public Review Draft Metadata for

public void setPriceCategory(int priceCategory) { this.priceCategory = priceCategory; } @ManyToMany(targetEntity=com.acme.Customer.class) @JoinTable(name="CUST_DLVRY") public Collection getCustomers() { return customers; } public setCustomers(Collection customers) { this.customers = customers; } }

JSR-317 Public Review Draft

327

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Examples of the Application of Annotations

10.2.2 A More Complex Example


/***** Employee class *****/ @Entity @Table(name="EMPL") @SecondaryTable(name="EMP_SALARY", pkJoinColumns=@PrimaryKeyJoinColumn(name="EMP_ID", referencedColumnName="ID")) public class Employee implements Serializable { private private private private private private private private Long id; int version; String name; Address address; Collection phoneNumbers; Collection<Project> projects; Long salary; EmploymentPeriod period;

@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) {
10/31/08

328

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Examples of the Application of Annotations for Object/Relational MappingJava Persistence 2.0, Public Review Draft Metadata for

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; } } /***** Address class *****/ @Entity public class Address implements Serializable { private private private private Integer id; int version; String street; String city;

@Id @GeneratedValue(strategy=IDENTITY) public Integer getId() { return id; } protected void setId(Integer id) { this.id = id; } @Version @Column(name="VERS", nullable=false) public int getVersion() { return version; } protected void setVersion(int version) { this.version = version; } @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; } } /***** PhoneNumber class *****/ @Entity

JSR-317 Public Review Draft

329

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Examples of the Application of Annotations

@Table(name="PHONE") public class PhoneNumber implements Serializable { private String number; private int phoneType; private Employee employee; @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; } } /***** Project class *****/ @Entity @Inheritance(strategy=JOINED) DiscriminatorValue("Proj") @DiscriminatorColumn(name="DISC") public class Project implements Serializable { private private private private Integer projId; int version; String name; Set<Employee> employees;

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

10/31/08

330

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Examples of the Application of Annotations for Object/Relational MappingJava Persistence 2.0, Public Review Draft Metadata for

/***** GovernmentProject subclass *****/ @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; } } /***** CovertProject subclass *****/ @Entity @Table(name="C_PROJECT") @DiscriminatorValue("CovProj") @PrimaryKeyJoinColumn(name="COV_PROJ_ID", referencedColumnName="ID") public class CovertProject extends Project { private String classified; public CovertProject() { super(); } public CovertProject(String classified) { this(); this.classified = classified; } @Column(updatable=false) public String getClassified() { return classified; } protected void setClassified(String classified) { this.classified = classified; } } /***** EmploymentPeriod class *****/ @Embeddable public class EmploymentPeriod implements Serializable { private Date start; private Date end; @Column(nullable=false) public Date getStartDate() { return start; } public void setStartDate(Date start) { this.start = start;

JSR-317 Public Review Draft

331

10/31/08

Sun Microsystems, Inc.


Metadata for Object/Relational Mapping Java Persistence 2.0, Public Review Draft Examples of the Application of Annotations

} public Date getEndDate() { return end; } public void setEndDate(Date end) { this.end = end; } }

10/31/08

332

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Use of the XML Descriptor Java Persistence 2.0, Public Review Draft XML Object/Relational Mapping Descriptor

C ha p t e r 11

XML Object/Relational Mapping Descriptor

The XML object/relational mapping descriptor serves as both an alternative to and an overriding mechanism for Java language metadata annotations.

11.1 Use of the XML Descriptor


The XML schema for the object relational/mapping descriptor is contained in Section 11.3. The root element of this schema is the entity-mappings element. The absence or present of the xml-mapping-metadata-complete subelement contained in the persistence-unit-defaults subelement of the entity-mappings element controls whether the XML object/relational mapping descriptor is used to selectively override annotation values or whether it serves as a complete alternative to Java language metadata annotations. If the xml-mapping-metadata-complete subelement is specified, the complete set of mapping metadata for the persistence unit is contained in the XML mapping files for the persistence unit, and any annotations on the classes are ignored.

JSR-317 Public Review Draft

333

10/31/08

Sun Microsystems, Inc.


XML Object/Relational Mapping Descriptor Java Persistence 2.0, Public Review Draft XML Overriding Rules

If xml-mapping-metadata-complete is specified and XML elements are omitted, the default values apply. These default values are the same as the corresponding defaults when annotations are used, except in the cases specified in Section 11.2 below. When the xml-mapping-metadata-complete element is specified, any metadata-complete attributes specified within the entity, mapped-superclass, and embeddable elements are ignored. If the xml-mapping-metadata-complete subelement is not specified, the XML descriptor overrides the values set or defaulted by the use of annotations, as described below. The mapping files used by the application developer must conform to the XML schema defined in Section 11.3 or to the object/relational mapping schema defined in the previous version of this specification [1]. The Java Persistence 2.0 persistence provider must support use of the object/relational mapping schema defined in [1] as well as the object/relational mapping schema defined in Section 11.3, whether singly or in combination when multiple mapping files are used.

11.2 XML Overriding Rules


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 persistence-unit-defaults, entity-mappings, entity, mapped-superclass, and embeddable elements.

11.2.1 persistence-unit-defaults Subelements 11.2.1.1 schema


The schema subelement applies to all entities, tables, secondary tables, join tables, collection tables, table generators, and sequence generators in the persistence unit. The schema subelement is overridden by any schema subelement of the entity-mappings element; 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; any schema element explicitly specified in a SequenceGenerator annotation or sequence-generator subelement; any schema element explicitly specified in a JoinTable annotation or join-table subelement; and any schema element explicitly specified in a CollectionTable annotation or collection-table subelement.

11.2.1.2 catalog
The catalog subelement applies to all entities, tables, secondary tables, join tables, collection tables, table generators, and sequence generators in the persistence unit.

10/31/08

334

JSR-317 Public Review Draft

Sun Microsystems, Inc.


XML Overriding Rules Java Persistence 2.0, Public Review Draft XML Object/Relational Mapping Descriptor

The catalog subelement is overridden by any catalog subelement of the entity-mappings element; any catalog element explicitly specified in the Table or SecondaryTable annotation on an entity or any catalog attribute on any table or secondary-table subelement defined within an entity XML element; any catalog element explicitly specified in a TableGenerator annotation or table-generator subelement; any catalog element explicitly specified in a SequenceGenerator annotation or sequence-generator subelement; any catalog element explicitly specified in a JoinTable annotation or join-table subelement; and any catalog element explicitly specified in a CollectionTable annotation or collection-table subelement.

11.2.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 annotation on the entity class, mapped superclass, or embeddable class; by any access subelement of the entity-mappings element; by any Access annotation on a field or property of an entity class, mapped superclass, or embeddable class; by any access attribute defined within an entity, mapped-superclass, or embeddable XML element, or by any access attribute defined within an id, embedded-id, version, basic, embedded, many-to-one, one-to-one, one-to-many, many-to-many, or element-collection element.

11.2.1.4 cascade-persist
The cascade-persist subelement applies to all relationships in the persistence unit. Specifying this subelement adds the cascade persist option to all relationships in addition to any settings specified in annotations or XML. The cascade-persist subelement may not be overridden in this release. The ability to override the cascade-persist of the persistence-unit-defaults element will be added in a future release of this specification.

11.2.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 ExcludeDefaultListeners annotation is present on the entity or mapped superclass or the exclude-default-listeners subelement is specified within the corresponding entity or mapped-superclass XML element.

11.2.2 Other Subelements of the entity-mappings element 11.2.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.

JSR-317 Public Review Draft

335

10/31/08

Sun Microsystems, Inc.


XML Object/Relational Mapping Descriptor Java Persistence 2.0, Public Review Draft XML Overriding Rules

11.2.2.2 schema
The schema subelement applies only to the entities, tables, secondary tables, join tables, and collection tables listed within the same mapping file. The schema subelement is overridden by any schema element explicitly specified in the Table, SecondaryTable, JoinTable, or CollectionTable annotation on an entity listed within the mapping file or any schema attribute on any table or secondary-table subelement defined within the entity element for such an entity, or by any schema attribute on any join-table or collection-table subelement of an attribute defined within the attributes subelement of the entity element for such an entity.

11.2.2.3 catalog
The catalog subelement applies only to the entities, tables, secondary tables, join tables, and collection tables listed within the same mapping file. The catalog subelement is overridden by any catalog element explicitly specified in the Table, SecondaryTable, JoinTable, or CollectionTable annotation on an entity listed within the mapping file or any catalog attribute on any table or secondary-table subelement defined within the entity element for such an entity, or by any catalog attribute on any join-table or collection-table subelement of an attribute defined within the attributes subelement of the entity element for such an entity.

11.2.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; by any Access annotation on the entity class, mapped superclass, or embeddable class; by any access subelement of the entity-mappings element; by any Access annotation on a fieldf or property of an entity class, mapped superclass, or embeddable class; by any access attribute defined within an entity, mapped-superclass, or embeddable XML element, or by any access attribute defined within an id, embedded-id, version, basic, embedded, many-to-one, one-to-one, one-to-many, many-to-many, or element-collection element.

11.2.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.

11.2.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. 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/31/08

336

JSR-317 Public Review Draft

Sun Microsystems, Inc.


XML Overriding Rules Java Persistence 2.0, Public Review Draft XML Object/Relational Mapping Descriptor

11.2.2.7 named-query
The named query defined by the named-query subelement applies to the persistence unit. It is undefined 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 definition.

11.2.2.8 named-native-query
The named native query defined by the named-native-query subelement applies to the persistence 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.

11.2.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.

11.2.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 and attributes of the entity element override as specified in section 11.2.3.

11.2.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 superclass. The mapped superclass may or may not have been annotated as MappedSuperclass. The subelements and attributes of the mapped-superclass element override as specified in section 11.2.4.

11.2.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. The embeddable class may or may not have been annotated as Embeddable. The subelements and attributes of the embeddable element override as specified in section 11.2.5.

JSR-317 Public Review Draft

337

10/31/08

Sun Microsystems, Inc.


XML Object/Relational Mapping Descriptor Java Persistence 2.0, Public Review Draft XML Overriding Rules

11.2.3 entity Subelements and Attributes


These apply only to the entity for which they are subelements or attributes, unless otherwise specified below.

11.2.3.1 metadata-complete
If the metadata-complete attribute of the entity element is specified as true, any annotations on the entity class (and its fields and properties) are ignored. When metadata-complete is specified as true and XML attributes or sub-elements of the entity element are omitted, the default values for those attributes and elements are applied.

11.2.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. The access type for a field or property of the entity may be overridden by specifying by overriding the mapping for that field or property using the appropriate XML subelement, as described in Section 11.2.3.22 below. Caution must be exercised in overriding an access type that was specified or defaulted using annotations, as doing so may cause applications to break.

11.2.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.

11.2.3.4 table
The table subelement overrides any Table annotation (including defaulted Table values) on the entity. If a table subelement is present, and attributes or subelements of that table subelement are not explicitly specified, their default values are applied.

11.2.3.5 secondary-table
The secondary-table subelement overrides all SecondaryTable and SecondaryTables annotations (including defaulted SecondaryTable values) on the entity. If a secondary-table subelement is present, and attributes or subelements of that secondary-table subelement are not explicitly specified, their default values are applied.

11.2.3.6 primary-key-join-column
The primary-key-join-column subelement of the entity element specifies a primary key column that is used to join the table of an entity subclass to the primary table for the entity when the joined strategy is used. The primary-key-join-column subelement overrides all PrimaryKeyJoinColumn and PrimaryKeyJoinColumns annotations (including defaulted PrimaryKeyJoinColumn values) on the entity. If a primary-key-join-column subelement is present, and attributes or subelements of that primary-key-join-column subelement are not explicitly specified, their default values are applied.

10/31/08

338

JSR-317 Public Review Draft

Sun Microsystems, Inc.


XML Overriding Rules Java Persistence 2.0, Public Review Draft XML Object/Relational Mapping Descriptor

11.2.3.7 id-class
The id-class subelement overrides any IdClass annotation specified on the entity.

11.2.3.8 inheritance
The inheritance subelement overrides any Inheritance annotation (including defaulted Inheritance values) on the entity. If an inheritance subelement is present, and the strategy attribute is not explicitly specified, its default value is applied. This element applies to the entity and its subclasses (unless otherwise overridden for a subclass by an annotation or XML element). Support for the combination of inheritance strategies is not required by this specification. Portable applications should use only a single inheritance strategy within an entity hierarchy.

11.2.3.9 discriminator-value
The discriminator-value subelement overrides any DiscriminatorValue annotations (including defaulted DiscriminatorValue values) on the entity.

11.2.3.10 discriminator-column
The discriminator-column subelement overrides any DiscriminatorColumn annotation (including defaulted DiscriminatorColumn values) on the entity. If a discriminator-column subelement is present, and attributes of that discriminator-column subelement are not explicitly specified, their default values are applied. This element applies to the entity and its subclasses (unless otherwise overridden for a subclass by an annotation or XML element).

11.2.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. If a sequence-generator subelement is present, and attributes or subelements of that sequence-generator subelement are not explicitly specified, their default values are applied. 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.

11.2.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. If a table-generator subelement is present, and attributes or subelements of that table-generator subelement are not explicitly specified, their default values are applied. 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.

JSR-317 Public Review Draft

339

10/31/08

Sun Microsystems, Inc.


XML Object/Relational Mapping Descriptor Java Persistence 2.0, Public Review Draft XML Overriding Rules

11.2.3.13 attribute-override
The attribute-override subelement is additive to any AttributeOverride or AttributeOverrides annotations on the entity. It overrides any AttributeOverride elements for the same attribute name. If an attribute-override subelement is present, and attributes or subelements of that attribute-override subelement are not explicitly specified, their default values are applied.

11.2.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. If an association-override subelement is present, and attributes or subelements of that association-override subelement are not explicitly specified, their default values are applied.

11.2.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. If a named-query subelement is present, and attributes or subelements of that named-query subelement are not explicitly specified, their default values are applied. The named query defined by the named-query subelement applies to the persistence unit. It is undefined if multiple mapping files for the persistence unit contain named queries of the same name.

11.2.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. If a named-native-query subelement is present, and attributes or subelements of that named-native-query subelement are not explicitly specified, their default values are applied. The named native query defined by the named-native-query subelement applies to the persistence unit. It is undefined if multiple mapping files for the persistence unit contain named queries of the same name.

11.2.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. If a sql-result-set-mapping subelement is present, and attributes or subelements of that sql-result-set-mapping subelement are not explicitly specified, their default values are applied. 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/31/08

340

JSR-317 Public Review Draft

Sun Microsystems, Inc.


XML Overriding Rules Java Persistence 2.0, Public Review Draft XML Object/Relational Mapping Descriptor

11.2.3.18 exclude-default-listeners
The exclude-default-listeners subelement applies whether or not the ExcludeDefaultListeners annotation was specified on the entity. This element causes the default entity listeners to be excluded for the entity and its subclasses.

11.2.3.19 exclude-superclass-listeners
The exclude-superclass-listeners subelement applies whether or not the ExcludeSuperclassListeners annotation was specified on the entity. This element causes any superclass listeners to be excluded for the entity and its subclasses.

11.2.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.

11.2.3.21 pre-persist, post-persist, pre-remove, post-remove, pre-update, post-update, post-load


These subelements override any lifecycle callback methods defined by the corresponding annotations on the entity.

11.2.3.22 attributes
The attributes element groups the mapping subelements for the fields and properties of the entity. It may be sparsely populated to include only a subset of the fields and properties. If the value of metadata-complete is true, the remainder of the attributes will be defaulted according to the default rules. If metadata-complete is not specified, or is false, the mappings for only those properties and fields that are explicitly specified will be overridden. 11.2.3.22.1 id The id subelement overrides the mapping for the specified field or property. If an id subelement is present, and attributes or subelements of that id subelement are not explicitly specified, their default values are applied. 11.2.3.22.2 embedded-id The embedded-id subelement overrides the mapping for the specified field or property. If an embedded-id subelement is present, and attributes or subelements of that embedded-id subelement are not explicitly specified, their default values are applied. 11.2.3.22.3 basic The basic subelement overrides the mapping for the specified field or property. If a basic subelement is present, and attributes or subelements of that basic subelement are not explicitly specified, their default values are applied. 11.2.3.22.4 version The version subelement overrides the mapping for the specified field or property. If a version subelement is present, and attributes or subelements of that version subelement are not explicitly specified, their default values are applied.
JSR-317 Public Review Draft

341

10/31/08

Sun Microsystems, Inc.


XML Object/Relational Mapping Descriptor Java Persistence 2.0, Public Review Draft XML Overriding Rules

11.2.3.22.5 many-to-one The many-to-one subelement overrides the mapping for the specified field or property. If a many-to-one subelement is present, and attributes or subelements of that many-to-one subelement are not explicitly specified, their default values are applied. 11.2.3.22.6 one-to-many The one-to-many subelement overrides the mapping for the specified field or property. If a one-to-many subelement is present, and attributes or subelements of that one-to-many subelement are not explicitly specified, their default values are applied. 11.2.3.22.7 one-to-one The one-to-one subelement overrides the mapping for the specified field or property. If a one-to-one subelement is present, and attributes or subelements of that one-to-one subelement are not explicitly specified, their default values are applied. 11.2.3.22.8 many-to-many The many-to-many subelement overrides the mapping for the specified field or property. If a many-to-many subelement is present, and attributes or subelements of that many-to-many subelement are not explicitly specified, their default values are applied. 11.2.3.22.9 element-collection The element-collection subelement overrides the mapping for the specified field or property. If an element-collection subelement is present, and attributes or subelements of that element-collection subelement are not explicitly specified, their default values are applied. 11.2.3.22.10 embedded The embedded subelement overrides the mapping for the specified field or property. If an embedded subelement is present, and attributes or subelements of that embedded subelement are not explicitly specified, their default values are applied. 11.2.3.22.11 transient The transient subelement overrides the mapping for the specified field or property.

11.2.4 mapped-superclass Subelements and Attributes


These apply only to the mapped-superclass for which they are subelementsor attributes, unless otherwise specified below.

11.2.4.1 metadata-complete
If the metadata-complete attribute of the mapped-superclass element is specified as true, any annotations on the mapped superclass (and its fields and properties) are ignored. When metadata-complete is specified as true and attributes or sub-elements of the mapped-superclass element are omitted, the default values for those attributes and elements are applied.

10/31/08

342

JSR-317 Public Review Draft

Sun Microsystems, Inc.


XML Overriding Rules Java Persistence 2.0, Public Review Draft XML Object/Relational Mapping Descriptor

11.2.4.2 access
The access attribute defines the access type for the mapped superclass. The access attribute overrides any access type specified by the persistence-unit-defaults element or entity-mappings element for the given mapped superclass. The access type for a field or property of the mapped superclass may be overridden by specifying by overriding the mapping for that field or property using the appropriate XML subelement, as described in Section 11.2.4.8 below. Caution must be exercised in overriding an access type that was specified or defaulted using annotations, as doing so may cause applications to break.

11.2.4.3 id-class
The id-class subelement overrides any IdClass annotation specified on the mapped superclass.

11.2.4.4 exclude-default-listeners
The exclude-default-listeners subelement applies whether or not the ExcludeDefaultListeners annotation was specified on the mapped superclass. This element causes the default entity listeners to be excluded for the mapped superclass and its subclasses.

11.2.4.5 exclude-superclass-listeners
The exclude-superclass-listeners subelement applies whether or not the ExcludeSuperclassListeners annotation was specified on the mapped superclass. This element causes any superclass listeners to be excluded for the mapped superclass and its subclasses.

11.2.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.

11.2.4.7 pre-persist, post-persist, pre-remove, post-remove, pre-update, post-update, post-load


These subelements override any lifecycle callback methods defined by the corresponding annotations on the mapped superclass.

11.2.4.8 attributes
The attributes element groups the mapping subelements for the fields and properties defined by the mapped superclass. It may be sparsely populated to include only a subset of the fields and properties. If the value of metadata-complete is true, the remainder of the attributes will be defaulted according to the default rules. If metadata-complete is not specified, or is false, the mappings for only those properties and fields that are explicitly specified will be overridden.

JSR-317 Public Review Draft

343

10/31/08

Sun Microsystems, Inc.


XML Object/Relational Mapping Descriptor Java Persistence 2.0, Public Review Draft XML Overriding Rules

11.2.4.8.1 id The id subelement overrides the mapping for the specified field or property. If an id subelement is present, and attributes or subelements of that id subelement are not explicitly specified, their default values are applied. 11.2.4.8.2 embedded-id The embedded-id subelement overrides the mapping for the specified field or property. If an embedded-id subelement is present, and attributes or subelements of that embedded-id subelement are not explicitly specified, their default values are applied. 11.2.4.8.3 basic The basic subelement overrides the mapping for the specified field or property. If a basic subelement is present, and attributes or subelements of that basic subelement are not explicitly specified, their default values are applied. 11.2.4.8.4 version The version subelement overrides the mapping for the specified field or property. If a version subelement is present, and attributes or subelements of that version subelement are not explicitly specified, their default values are applied. 11.2.4.8.5 many-to-one The many-to-one subelement overrides the mapping for the specified field or property. If a many-to-one subelement is present, and attributes or subelements of that many-to-one subelement are not explicitly specified, their default values are applied. 11.2.4.8.6 one-to-many The one-to-many subelement overrides the mapping for the specified field or property. If a one-to-many subelement is present, and attributes or subelements of that one-to-many subelement are not explicitly specified, their default values are applied. 11.2.4.8.7 one-to-one The one-to-one subelement overrides the mapping for the specified field or property. If a one-to-one subelement is present, and attributes or subelements of that one-to-one subelement are not explicitly specified, their default values are applied. 11.2.4.8.8 many-to-many The many-to-many subelement overrides the mapping for the specified field or property. If a many-to-many subelement is present, and attributes or subelements of that many-to-many subelement are not explicitly specified, their default values are applied. 11.2.4.8.9 element-collection The element-collection subelement overrides the mapping for the specified field or property. If an element-collection subelement is present, and attributes or subelements of that element-collection subelement are not explicitly specified, their default values are applied. 11.2.4.8.10 embedded The embedded subelement overrides the mapping for the specified field or property. If an embedded subelement is present, and attributes or subelements of that embedded subelement are not explicitly specified, their default values are applied.
10/31/08

344

JSR-317 Public Review Draft

Sun Microsystems, Inc.


XML Overriding Rules Java Persistence 2.0, Public Review Draft XML Object/Relational Mapping Descriptor

11.2.4.8.11 transient The transient subelement overrides the mapping for the specified field or property.

11.2.5 embeddable Subelements and Attributes


These apply only to the embeddable for which they are subelements or attributes.

11.2.5.1 metadata-complete
If the metadata-complete attribute of the embeddable element is specified as true, any annotations on the embeddable class (and its fields and properties) are ignored. When metadata-complete is specified as true and attributes and sub-elements of the embeddable element are omitted, the default values for those attributes and elements are applied.

11.2.5.2 access
The access attribute defines the access type for the embeddable class. The access attribute overrides any access type specified by the persistence-unit-defaults element or entity-mappings element for the given embeddable class. The access type for a field or property of the embeddable class may be overridden by specifying by overriding the mapping for that field or property using the appropriate XML subelement, as described in Section 11.2.5.3 below. Caution must be exercised in overriding an access type that was specified or defaulted using annotations, as doing so may cause applications to break.

11.2.5.3 attributes
The attributes element groups the mapping subelements for the fields and properties defined by the embeddable class. It may be sparsely populated to include only a subset of the fields and properties. If the value of metadata-complete is true, the remainder of the attributes will be defaulted according to the default rules. If metadata-complete is not specified, or is false, the mappings for only those properties and fields that are explicitly specified will be overridden. 11.2.5.3.1 basic The basic subelement overrides the mapping for the specified field or property. If a basic subelement is present, and attributes or subelements of that basic subelement are not explicitly specified, their default values are applied. 11.2.5.3.2 many-to-one The many-to-one subelement overrides the mapping for the specified field or property. If a many-to-one subelement is present, and attributes or subelements of that many-to-one subelement are not explicitly specified, their default values are applied.. 11.2.5.3.3 one-to-many The one-to-many subelement overrides the mapping for the specified field or property. If a one-to-many subelement is present, and attributes or subelements of that one-to-many subelement are not explicitly specified, their default values are applied.

JSR-317 Public Review Draft

345

10/31/08

Sun Microsystems, Inc.


XML Object/Relational Mapping Descriptor Java Persistence 2.0, Public Review Draft XML Overriding Rules

11.2.5.3.4 one-to-one The one-to-one subelement overrides the mapping for the specified field or property. If a one-to-one subelement is present, and attributes or subelements of that one-to-one subelement are not explicitly specified, their default values are applied. 11.2.5.3.5 many-to-many The many-to-many subelement overrides the mapping for the specified field or property. If a many-to-many subelement is present, and attributes or subelements of that many-to-many subelement are not explicitly specified, their default values are applied. 11.2.5.3.6 element-collection The element-collection subelement overrides the mapping for the specified field or property. If an element-collection subelement is present, and attributes or subelements of that element-collection subelement are not explicitly specified, their default values are applied. 11.2.5.3.7 embedded The embedded subelement overrides the mapping for the specified field or property. If an embedded subelement is present, and attributes or subelements of that embedded subelement are not explicitly specified, their default values are applied. 11.2.5.3.8 transient The transient subelement overrides the mapping for the specified field or property.

10/31/08

346

JSR-317 Public Review Draft

Sun Microsystems, Inc.


XML Schema Java Persistence 2.0, Public Review Draft XML Object/Relational Mapping Descriptor

11.3 XML Schema


This section provides the XML schema for use with the persistence API.
<?xml version="1.0" encoding="UTF-8"?> <!-- Java Persistence API object/relational mapping file schema --> <xsd:schema targetNamespace="http://java.sun.com/xml/ns/persistence/orm" xmlns:orm="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified" version="2.0"> <xsd:annotation> <xsd:documentation> @(#)orm_2_0.xsd 2.0 August 27 2008 </xsd:documentation> </xsd:annotation> <xsd:annotation> <xsd:documentation><![CDATA[ This is the XML Schema for the persistence object/relational mapping file. The file may be named "META-INF/orm.xml" in the persistence archive or it may be named some other name which would be used to locate the file as resource on the classpath. Object/relational mapping files must indicate the object/relational mapping file schema by using the persistence namespace: http://java.sun.com/xml/ns/persistence and indicate the version of the schema by using the version element as shown below: <entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm/orm_2_0.xsd" version="2.0"> ... </entity-mappings> ]]></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> The entity-mappings element is the root element of an mapping

JSR-317 Public Review Draft

347

10/31/08

Sun Microsystems, Inc.


XML Object/Relational Mapping Descriptor Java Persistence 2.0, Public Review Draft XML Schema

file. It contains the following four types of elements: 1. The persistence-unit-metadata element contains metadata for the entire persistence unit. It is undefined if this element occurs in multiple mapping files within the same persistence unit. 2. The package, schema, catalog and access elements apply to all of the entity, mapped-superclass and embeddable elements defined in the same file in which they occur. 3. The sequence-generator, table-generator, named-query, named-native-query and sql-result-set-mapping elements are global to the persistence unit. It is undefined to have more than one sequence-generator or table-generator of the same name in the same or different mapping files in a persistence unit. It is also undefined to have more than one named-query, named-native-query, or result-set-mapping of the same name in the same or different mapping files in a persistence unit. 4. The entity, mapped-superclass and embeddable elements each define the mapping information for a managed persistent class. The mapping information contained in these elements may be complete or it may be partial. </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="2.0" use="required"/> </xsd:complexType> </xsd:element> <!-- **************************************************** --> <xsd:complexType name="persistence-unit-metadata">

10/31/08

348

JSR-317 Public Review Draft

Sun Microsystems, Inc.


XML Schema Java Persistence 2.0, Public Review Draft XML Object/Relational Mapping Descriptor

<xsd:annotation> <xsd:documentation> Metadata that applies to the persistence unit and not just to the mapping file in which it is contained. If the xml-mapping-metadata-complete element is specified, the complete set of mapping metadata for the persistence unit is contained in the XML mapping files for the persistence unit. </xsd:documentation> </xsd:annotation> <xsd:sequence> <xsd:element name="description" type="xsd:string" minOccurs="0"/> <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> These defaults are applied to the persistence unit as a whole unless they are overridden by local annotation or XML element settings. schema - Used as the schema for all tables, secondary tables, collection tables, sequence generators, and table generators that apply to the persistence unit catalog - Used as the catalog for all tables, secondary tables, collection tables, sequence generators, and table generators that apply to the persistence unit access - Used as the access type for all managed classes in the persistence unit cascade-persist - Adds cascade-persist to the set of cascade options in all entity relationships of the persistence unit entity-listeners - List of default entity listeners to be invoked on each entity in the persistence unit. </xsd:documentation> </xsd:annotation> <xsd:sequence> <xsd:element name="description" 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="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>

JSR-317 Public Review Draft

349

10/31/08

Sun Microsystems, Inc.


XML Object/Relational Mapping Descriptor Java Persistence 2.0, Public Review Draft XML Schema

<xsd:documentation> Defines the settings and mappings for an entity. Is allowed to be sparsely populated and used in conjunction with the annotations. Alternatively, the metadata-complete attribute can be used to indicate that no annotations on the entity class (and its fields or properties) are to be processed. If this is the case then the defaulting rules for the entity and its subelements will be recursively applied. @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:element name="secondary-table" type="orm:secondary-table" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="primary-key-join-column" type="orm:primary-key-join-column" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="id-class" type="orm:id-class" minOccurs="0"/> <xsd:element name="inheritance" type="orm:inheritance" minOccurs="0"/> <xsd:element name="discriminator-value" type="orm:discriminator-value" minOccurs="0"/> <xsd:element name="discriminator-column" type="orm:discriminator-column" minOccurs="0"/> <xsd:element name="sequence-generator" type="orm:sequence-generator" minOccurs="0"/> <xsd:element name="table-generator" type="orm:table-generator" minOccurs="0"/> <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="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:element name="post-update" type="orm:post-update" minOccurs="0"/> <xsd:element name="post-load" type="orm:post-load" minOccurs="0"/> <xsd:element name="attribute-override" type="orm:attribute-override" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="association-override" type="orm:association-override" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="attributes" type="orm:attributes" minOccurs="0"/> </xsd:sequence> <xsd:attribute name="name" type="xsd:string"/>

10/31/08

350

JSR-317 Public Review Draft

Sun Microsystems, Inc.


XML Schema Java Persistence 2.0, Public Review Draft XML Object/Relational Mapping Descriptor

<xsd:attribute name="class" type="xsd:string" use="required"/> <xsd:attribute name="access" type="orm:access-type"/> <xsd:attribute name="metadata-complete" type="xsd:boolean"/> </xsd:complexType> <!-- **************************************************** --> <xsd:simpleType name="access-type"> <xsd:annotation> <xsd:documentation> This element determines how the persistence provider accesses the state of an entity or embedded object. </xsd:documentation> </xsd:annotation> <xsd:restriction base="xsd:token"> <xsd:enumeration value="PROPERTY"/> <xsd:enumeration value="FIELD"/> </xsd:restriction> </xsd:simpleType> <!-- **************************************************** --> <xsd:complexType name="association-override"> <xsd:annotation> <xsd:documentation> @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface AssociationOverride { String name(); JoinColumn[] joinColumns() default{}; JoinTable joinTable() default @JoinTable; } </xsd:documentation> </xsd:annotation> <xsd:sequence> <xsd:element name="description" type="xsd:string" minOccurs="0"/> <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:sequence> <xsd:attribute name="name" type="xsd:string" use="required"/> </xsd:complexType> <!-- **************************************************** --> <xsd:complexType name="attribute-override"> <xsd:annotation> <xsd:documentation> @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface AttributeOverride { String name(); Column column(); } </xsd:documentation> </xsd:annotation> <xsd:sequence> <xsd:element name="description" type="xsd:string" minOccurs="0"/> <xsd:element name="column" type="orm:column"/> </xsd:sequence>

JSR-317 Public Review Draft

351

10/31/08

Sun Microsystems, Inc.


XML Object/Relational Mapping Descriptor Java Persistence 2.0, Public Review Draft XML Schema

<xsd:attribute name="name" type="xsd:string" use="required"/> </xsd:complexType> <!-- **************************************************** --> <xsd:complexType name="attributes"> <xsd:annotation> <xsd:documentation> This element contains the entity field or property mappings. It may be sparsely populated to include only a subset of the fields or properties. If metadata-complete for the entity is true then the remainder of the attributes will be defaulted according to the default rules. </xsd:documentation> </xsd:annotation> <xsd:sequence> <xsd:element name="description" type="xsd:string" minOccurs="0"/> <xsd:choice> <xsd:element name="id" type="orm:id" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="embedded-id" type="orm:embedded-id" minOccurs="0"/> </xsd:choice> <xsd:element name="basic" type="orm:basic" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="version" type="orm:version" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="many-to-one" type="orm:many-to-one" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="one-to-many" type="orm:one-to-many" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="one-to-one" type="orm:one-to-one" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="many-to-many" type="orm:many-to-many" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="element-collection" type="orm:element-collection" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="embedded" type="orm:embedded" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="transient" type="orm:transient" minOccurs="0" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> <!-- **************************************************** --> <xsd:complexType name="basic"> <xsd:annotation> <xsd:documentation> @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Basic { FetchType fetch() default EAGER; boolean optional() default true; } </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"/>

10/31/08

352

JSR-317 Public Review Draft

Sun Microsystems, Inc.


XML Schema Java Persistence 2.0, Public Review Draft XML Object/Relational Mapping Descriptor

</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:attribute name="access" type="orm:access-type"/> </xsd:complexType> <!-- **************************************************** --> <xsd:complexType name="cascade-type"> <xsd:annotation> <xsd:documentation> public enum CascadeType { ALL, PERSIST, MERGE, REMOVE, REFRESH}; </xsd:documentation> </xsd:annotation> <xsd:sequence> <xsd:element name="cascade-all" type="orm:emptyType" minOccurs="0"/> <xsd:element name="cascade-persist" type="orm:emptyType" minOccurs="0"/> <xsd:element name="cascade-merge" type="orm:emptyType" minOccurs="0"/> <xsd:element name="cascade-remove" type="orm:emptyType" minOccurs="0"/> <xsd:element name="cascade-refresh" type="orm:emptyType" minOccurs="0"/> </xsd:sequence> </xsd:complexType> <!-- **************************************************** --> <xsd:complexType name="collection-table"> <xsd:annotation> <xsd:documentation> @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface CollectionTable { String name() default ""; String catalog() default ""; String schema() default ""; JoinColumn[] joinColumns() default {}; UniqueConstraint[] uniqueConstraints() default {}; } </xsd:documentation> </xsd:annotation> <xsd:sequence> <xsd:element name="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="column"> <xsd:annotation> <xsd:documentation>

JSR-317 Public Review Draft

353

10/31/08

Sun Microsystems, Inc.


XML Object/Relational Mapping Descriptor Java Persistence 2.0, Public Review Draft XML Schema

@Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Column { String name() default ""; boolean unique() default false; boolean nullable() default true; boolean insertable() default true; boolean updatable() default true; String columnDefinition() default ""; String table() default ""; int length() default 255; int precision() default 0; // decimal precision int scale() default 0; // decimal scale } </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="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="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>

10/31/08

354

JSR-317 Public Review Draft

Sun Microsystems, Inc.


XML Schema Java Persistence 2.0, Public Review Draft XML Object/Relational Mapping Descriptor

<!-- **************************************************** --> <xsd:simpleType name="discriminator-type"> <xsd:annotation> <xsd:documentation> public enum DiscriminatorType { STRING, CHAR, INTEGER }; </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: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:complexType name="element-collection"> <xsd:annotation> <xsd:documentation> @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface ElementCollection { Class targetClass() default void.class; FetchType fetch() default LAZY; } </xsd:documentation> </xsd:annotation> <xsd:sequence> <xsd:element name="column" type="orm:column" minOccurs="0"/> <xsd:choice> <xsd:element name="order-by" type="orm:order-by" minOccurs="0"/> <xsd:element name="order-column" type="orm:order-column" minOccurs="0"/> </xsd:choice> <xsd:choice> <xsd:element name="map-key" type="orm:map-key" minOccurs="0"/> <xsd:sequence> <xsd:element name="map-key-class" type="orm:map-key-class" minOccurs="0"/> <xsd:choice> <xsd:element name="map-key-column" type="orm:map-key-column" minOccurs="0"/> <xsd:element name="map-key-join-column"

JSR-317 Public Review Draft

355

10/31/08

Sun Microsystems, Inc.


XML Object/Relational Mapping Descriptor Java Persistence 2.0, Public Review Draft XML Schema

type="orm:map-key-join-column" minOccurs="0" maxOccurs="unbounded"/> </xsd:choice> </xsd:sequence> </xsd:choice> <xsd:element name="collection-table" type="orm:collection-table" 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="access" type="orm:access-type"/> </xsd:complexType> <!-- **************************************************** --> <xsd:complexType name="embeddable"> <xsd:annotation> <xsd:documentation> Defines the settings and mappings for embeddable objects. Is allowed to be sparsely populated and used in conjunction with the annotations. Alternatively, the metadata-complete attribute can be used to indicate that no annotations are to be processed in the class. If this is the case then the defaulting rules will be recursively applied. @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:attribute name="access" type="orm:access-type"/> <xsd:attribute name="metadata-complete" type="xsd:boolean"/> </xsd:complexType> <!-- **************************************************** --> <xsd:complexType name="embeddable-attributes"> <xsd:sequence> <xsd:element name="basic" type="orm:basic" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="many-to-one" type="orm:many-to-one" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="one-to-many" type="orm:one-to-many" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="one-to-one" type="orm:one-to-one" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="many-to-many" type="orm:many-to-many" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="element-collection" type="orm:element-collection" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="embedded" type="orm:embedded" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="transient" type="orm:transient" minOccurs="0" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> <!-- **************************************************** -->

10/31/08

356

JSR-317 Public Review Draft

Sun Microsystems, Inc.


XML Schema Java Persistence 2.0, Public Review Draft XML Object/Relational Mapping Descriptor

<xsd:complexType name="embedded"> <xsd:annotation> <xsd:documentation> @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Embedded {} </xsd:documentation> </xsd:annotation> <xsd:sequence> <xsd:element name="attribute-override" type="orm:attribute-override" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="association-override" type="orm:association-override" minOccurs="0" maxOccurs="unbounded"/> </xsd:sequence> <xsd:attribute name="name" type="xsd:string" use="required"/> <xsd:attribute name="access" type="orm:access-type"/> </xsd:complexType> <!-- **************************************************** --> <xsd:complexType name="embedded-id"> <xsd:annotation> <xsd:documentation> @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface EmbeddedId {} </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:attribute name="access" type="orm:access-type"/> </xsd:complexType> <!-- **************************************************** --> <xsd:complexType name="entity-listener"> <xsd:annotation> <xsd:documentation> Defines an entity listener to be invoked at lifecycle events for the entities that list this listener. </xsd:documentation> </xsd:annotation> <xsd:sequence> <xsd:element name="description" type="xsd:string" 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: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> <!-- **************************************************** -->

JSR-317 Public Review Draft

357

10/31/08

Sun Microsystems, Inc.


XML Object/Relational Mapping Descriptor Java Persistence 2.0, Public Review Draft XML Schema

<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: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:simpleType name="enum-type"> <xsd:annotation> <xsd:documentation> public enum EnumType { ORDINAL, STRING } </xsd:documentation> </xsd:annotation> <xsd:restriction base="xsd:token"> <xsd:enumeration value="ORDINAL"/> <xsd:enumeration value="STRING"/> </xsd:restriction> </xsd:simpleType> <!-- **************************************************** --> <xsd:simpleType name="enumerated"> <xsd:annotation> <xsd:documentation>

10/31/08

358

JSR-317 Public Review Draft

Sun Microsystems, Inc.


XML Schema Java Persistence 2.0, Public Review Draft XML Object/Relational Mapping Descriptor

@Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Enumerated { EnumType value() default ORDINAL; } </xsd:documentation> </xsd:annotation> <xsd:restriction base="orm:enum-type"/> </xsd:simpleType> <!-- **************************************************** --> <xsd:simpleType name="fetch-type"> <xsd:annotation> <xsd:documentation> public enum FetchType { LAZY, EAGER }; </xsd:documentation> </xsd:annotation> <xsd:restriction base="xsd:token"> <xsd:enumeration value="LAZY"/> <xsd:enumeration value="EAGER"/> </xsd:restriction> </xsd:simpleType> <!-- **************************************************** --> <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="generated-value"> <xsd:annotation> <xsd:documentation> @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface GeneratedValue { GenerationType strategy() default AUTO; String generator() default ""; } </xsd:documentation> </xsd:annotation> <xsd:attribute name="strategy" type="orm:generation-type"/> <xsd:attribute name="generator" type="xsd:string"/> </xsd:complexType> <!-- **************************************************** --> <xsd:simpleType name="generation-type"> <xsd:annotation>

JSR-317 Public Review Draft

359

10/31/08

Sun Microsystems, Inc.


XML Object/Relational Mapping Descriptor Java Persistence 2.0, Public Review Draft XML Schema

<xsd:documentation> public enum GenerationType { TABLE, SEQUENCE, IDENTITY, AUTO }; </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="id"> <xsd:annotation> <xsd:documentation> @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Id {} </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:attribute name="access" type="orm:access-type"/> </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="inheritance"> <xsd:annotation> <xsd:documentation> @Target({TYPE}) @Retention(RUNTIME) public @interface Inheritance { InheritanceType strategy() default SINGLE_TABLE;

10/31/08

360

JSR-317 Public Review Draft

Sun Microsystems, Inc.


XML Schema Java Persistence 2.0, Public Review Draft XML Object/Relational Mapping Descriptor

} </xsd:documentation> </xsd:annotation> <xsd:attribute name="strategy" type="orm:inheritance-type"/> </xsd:complexType> <!-- **************************************************** --> <xsd:simpleType name="inheritance-type"> <xsd:annotation> <xsd:documentation> public enum InheritanceType { SINGLE_TABLE, JOINED, TABLE_PER_CLASS}; </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:complexType name="join-column"> <xsd:annotation> <xsd:documentation> @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface JoinColumn { String name() default ""; String referencedColumnName() default ""; boolean unique() default false; boolean nullable() default true; boolean insertable() default true; boolean updatable() default true; String columnDefinition() default ""; String table() default ""; } </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: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:complexType> <!-- **************************************************** --> <xsd:complexType name="join-table"> <xsd:annotation> <xsd:documentation> @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface JoinTable { String name() default ""; String catalog() default ""; String schema() default "";

JSR-317 Public Review Draft

361

10/31/08

Sun Microsystems, Inc.


XML Object/Relational Mapping Descriptor Java Persistence 2.0, Public Review Draft XML Schema

JoinColumn[] joinColumns() default {}; JoinColumn[] inverseJoinColumns() default {}; UniqueConstraint[] uniqueConstraints() default {}; } </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="lob"> <xsd:annotation> <xsd:documentation> @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Lob {} </xsd:documentation> </xsd:annotation> </xsd:complexType> <!-- **************************************************** --> <xsd:complexType name="many-to-many"> <xsd:annotation> <xsd:documentation> @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface ManyToMany { Class targetEntity() default void.class; CascadeType[] cascade() default {}; FetchType fetch() default LAZY; String mappedBy() default ""; } </xsd:documentation> </xsd:annotation> <xsd:sequence> <xsd:choice> <xsd:element name="order-by" type="orm:order-by" minOccurs="0"/> <xsd:element name="order-column" type="orm:order-column" minOccurs="0"/> </xsd:choice> <xsd:choice> <xsd:element name="map-key" type="orm:map-key" minOccurs="0"/> <xsd:sequence> <xsd:element name="map-key-class" type="orm:map-key-class" minOccurs="0"/> <xsd:choice> <xsd:element name="map-key-column" type="orm:map-key-column" minOccurs="0"/> <xsd:element name="map-key-join-column"

10/31/08

362

JSR-317 Public Review Draft

Sun Microsystems, Inc.


XML Schema Java Persistence 2.0, Public Review Draft XML Object/Relational Mapping Descriptor

type="orm:map-key-join-column" minOccurs="0" maxOccurs="unbounded"/> </xsd:choice> </xsd:sequence> </xsd:choice> <xsd:element name="join-table" type="orm:join-table" minOccurs="0"/> <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="access" type="orm:access-type"/> <xsd:attribute name="mapped-by" type="xsd:string"/> </xsd:complexType> <!-- **************************************************** --> <xsd:complexType name="many-to-one"> <xsd:annotation> <xsd:documentation> @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface ManyToOne { Class targetEntity() default void.class; CascadeType[] cascade() default {}; FetchType fetch() default EAGER; boolean optional() default true; } </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:attribute name="access" type="orm:access-type"/> <xsd:attribute name="mapped-by-id" type="xsd:string"/> <xsd:attribute name="id" type="xsd:boolean"/> </xsd:complexType> <!-- **************************************************** --> <xsd:complexType name="map-key"> <xsd:annotation> <xsd:documentation> @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface MapKey { String name() default ""; } </xsd:documentation> </xsd:annotation> <xsd:attribute name="name" type="xsd:string"/>

JSR-317 Public Review Draft

363

10/31/08

Sun Microsystems, Inc.


XML Object/Relational Mapping Descriptor Java Persistence 2.0, Public Review Draft XML Schema

</xsd:complexType> <!-- **************************************************** --> <xsd:complexType name="map-key-class"> <xsd:annotation> <xsd:documentation> @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface MapKeyClass { Class value(); } </xsd:documentation> </xsd:annotation> <xsd:attribute name="class" type="xsd:string" use="required"/> </xsd:complexType> <!-- **************************************************** --> <xsd:complexType name="map-key-column"> <xsd:annotation> <xsd:documentation> @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface MapKeyColumn { String name() default ""; boolean unique() default false; boolean nullable() default false; boolean insertable() default true; boolean updatable() default true; String columnDefinition() default ""; String table() default ""; int length() default 255; int precision() default 0; // decimal precision int scale() default 0; // decimal scale } </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="map-key-join-column"> <xsd:annotation> <xsd:documentation> @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface MapKeyJoinColumn { String name() default ""; String referencedColumnName() default ""; boolean unique() default false; boolean nullable() default false; boolean insertable() default true; boolean updatable() default true;

10/31/08

364

JSR-317 Public Review Draft

Sun Microsystems, Inc.


XML Schema Java Persistence 2.0, Public Review Draft XML Object/Relational Mapping Descriptor

String columnDefinition() default ""; String table() default ""; } </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: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:complexType> <!-- **************************************************** --> <xsd:complexType name="mapped-superclass"> <xsd:annotation> <xsd:documentation> Defines the settings and mappings for a mapped superclass. Is allowed to be sparsely populated and used in conjunction with the annotations. Alternatively, the metadata-complete attribute can be used to indicate that no annotations are to be processed If this is the case then the defaulting rules will be recursively applied. @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:element name="post-update" type="orm:post-update" minOccurs="0"/> <xsd:element name="post-load" type="orm:post-load" minOccurs="0"/> <xsd:element name="attributes" type="orm:attributes" minOccurs="0"/> </xsd:sequence> <xsd:attribute name="class" type="xsd:string" use="required"/> <xsd:attribute name="access" type="orm:access-type"/> <xsd:attribute name="metadata-complete" type="xsd:boolean"/> </xsd:complexType> <!-- **************************************************** --> <xsd:complexType name="named-native-query"> <xsd:annotation> <xsd:documentation> @Target({TYPE}) @Retention(RUNTIME)

JSR-317 Public Review Draft

365

10/31/08

Sun Microsystems, Inc.


XML Object/Relational Mapping Descriptor Java Persistence 2.0, Public Review Draft XML Schema

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="description" type="xsd:string" minOccurs="0"/> <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="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="description" type="xsd:string" minOccurs="0"/> <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="one-to-many"> <xsd:annotation> <xsd:documentation> @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface OneToMany { Class targetEntity() default void.class; CascadeType[] cascade() default {}; FetchType fetch() default LAZY; String mappedBy() default ""; } </xsd:documentation> </xsd:annotation> <xsd:sequence> <xsd:choice> <xsd:element name="order-by" type="orm:order-by" minOccurs="0"/> <xsd:element name="order-column" type="orm:order-column"

10/31/08

366

JSR-317 Public Review Draft

Sun Microsystems, Inc.


XML Schema Java Persistence 2.0, Public Review Draft XML Object/Relational Mapping Descriptor

minOccurs="0"/> </xsd:choice> <xsd:choice> <xsd:element name="map-key" type="orm:map-key" minOccurs="0"/> <xsd:sequence> <xsd:element name="map-key-class" type="orm:map-key-class" minOccurs="0"/> <xsd:choice> <xsd:element name="map-key-column" type="orm:map-key-column" minOccurs="0"/> <xsd:element name="map-key-join-column" type="orm:map-key-join-column" minOccurs="0" maxOccurs="unbounded"/> </xsd:choice> </xsd:sequence> </xsd:choice> <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="access" type="orm:access-type"/> <xsd:attribute name="mapped-by" type="xsd:string"/> <xsd:attribute name="orphan-removal" type="xsd:boolean"/> </xsd:complexType> <!-- **************************************************** --> <xsd:complexType name="one-to-one"> <xsd:annotation> <xsd:documentation> @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface OneToOne { Class targetEntity() default void.class; CascadeType[] cascade() default {}; FetchType fetch() default EAGER; boolean optional() default true; String mappedBy() default ""; boolean orphanRemoval() default false; } </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"/>

JSR-317 Public Review Draft

367

10/31/08

Sun Microsystems, Inc.


XML Object/Relational Mapping Descriptor Java Persistence 2.0, Public Review Draft XML Schema

<xsd:attribute <xsd:attribute <xsd:attribute <xsd:attribute <xsd:attribute <xsd:attribute <xsd:attribute <xsd:attribute </xsd:complexType>

name="target-entity" type="xsd:string"/> name="fetch" type="orm:fetch-type"/> name="optional" type="xsd:boolean"/> name="access" type="orm:access-type"/> name="mapped-by" type="xsd:string"/> name="orphan-removal" type="xsd:boolean"/> name="mapped-by-id" type="xsd:string"/> name="id" type="xsd:boolean"/>

<!-- **************************************************** --> <xsd:simpleType name="order-by"> <xsd:annotation> <xsd:documentation> @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface OrderBy { String value() default ""; } </xsd:documentation> </xsd:annotation> <xsd:restriction base="xsd:string"/> </xsd:simpleType> <!-- **************************************************** --> <xsd:complexType name="order-column"> <xsd:annotation> <xsd:documentation> @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface OrderColumn { String name() default ""; boolean nullable() default true; boolean insertable() default true; boolean updatable() default true; String columnDefinition() default ""; boolean contiguous() default true; int base() default 0; String table() default ""; } </xsd:documentation> </xsd:annotation> <xsd:attribute name="name" type="xsd:string"/> <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="contiguous" type="xsd:boolean"/> <xsd:attribute name="base" type="xsd:int"/> <xsd:attribute name="table" type="xsd:string"/> </xsd:complexType> <!-- **************************************************** --> <xsd:complexType name="post-load"> <xsd:annotation> <xsd:documentation> @Target({METHOD}) @Retention(RUNTIME) public @interface PostLoad {}

10/31/08

368

JSR-317 Public Review Draft

Sun Microsystems, Inc.


XML Schema Java Persistence 2.0, Public Review Draft XML Object/Relational Mapping Descriptor

</xsd:documentation> </xsd:annotation> <xsd:sequence> <xsd:element name="description" type="xsd:string" minOccurs="0"/> </xsd:sequence> <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:sequence> <xsd:element name="description" type="xsd:string" minOccurs="0"/> </xsd:sequence> <xsd:attribute name="method-name" type="xsd:string" use="required"/> </xsd:complexType> <!-- **************************************************** --> <xsd:complexType name="post-remove"> <xsd:annotation> <xsd:documentation> @Target({METHOD}) @Retention(RUNTIME) public @interface PostRemove {} </xsd:documentation> </xsd:annotation> <xsd:sequence> <xsd:element name="description" type="xsd:string" minOccurs="0"/> </xsd:sequence> <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:sequence> <xsd:element name="description" type="xsd:string" minOccurs="0"/> </xsd:sequence> <xsd:attribute name="method-name" type="xsd:string" use="required"/> </xsd:complexType> <!-- **************************************************** --> <xsd:complexType name="pre-persist"> <xsd:annotation> <xsd:documentation> @Target({METHOD}) @Retention(RUNTIME)

JSR-317 Public Review Draft

369

10/31/08

Sun Microsystems, Inc.


XML Object/Relational Mapping Descriptor Java Persistence 2.0, Public Review Draft XML Schema

public @interface PrePersist {} </xsd:documentation> </xsd:annotation> <xsd:sequence> <xsd:element name="description" type="xsd:string" minOccurs="0"/> </xsd:sequence> <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:sequence> <xsd:element name="description" type="xsd:string" minOccurs="0"/> </xsd:sequence> <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:sequence> <xsd:element name="description" type="xsd:string" minOccurs="0"/> </xsd:sequence> <xsd:attribute name="method-name" type="xsd:string" use="required"/> </xsd:complexType> <!-- **************************************************** --> <xsd:complexType name="primary-key-join-column"> <xsd:annotation> <xsd:documentation> @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface PrimaryKeyJoinColumn { String name() default ""; String referencedColumnName() default ""; String columnDefinition() default ""; } </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> <!-- **************************************************** -->

10/31/08

370

JSR-317 Public Review Draft

Sun Microsystems, Inc.


XML Schema Java Persistence 2.0, Public Review Draft XML Object/Relational Mapping Descriptor

<xsd:complexType name="query-hint"> <xsd:annotation> <xsd:documentation> @Target({}) @Retention(RUNTIME) public @interface QueryHint { String name(); String value(); } </xsd:documentation> </xsd:annotation> <xsd:sequence> <xsd:element name="description" type="xsd:string" minOccurs="0"/> </xsd:sequence> <xsd:attribute name="name" type="xsd:string" use="required"/> <xsd:attribute name="value" type="xsd:string" use="required"/> </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="sequence-generator"> <xsd:annotation> <xsd:documentation> @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface SequenceGenerator { String name(); String sequenceName() default ""; String catalog() default ""; String schema() default ""; int initialValue() default 1; int allocationSize() default 50; } </xsd:documentation> </xsd:annotation>

JSR-317 Public Review Draft

371

10/31/08

Sun Microsystems, Inc.


XML Object/Relational Mapping Descriptor Java Persistence 2.0, Public Review Draft XML Schema

<xsd:sequence> <xsd:element name="description" type="xsd:string" minOccurs="0"/> </xsd:sequence> <xsd:attribute name="name" type="xsd:string" use="required"/> <xsd:attribute name="sequence-name" type="xsd:string"/> <xsd:attribute name="catalog" type="xsd:string"/> <xsd:attribute name="schema" type="xsd:string"/> <xsd:attribute name="initial-value" type="xsd:int"/> <xsd:attribute name="allocation-size" type="xsd:int"/> </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="description" type="xsd:string" minOccurs="0"/> <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="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="table-generator"> <xsd:annotation> <xsd:documentation>

10/31/08

372

JSR-317 Public Review Draft

Sun Microsystems, Inc.


XML Schema Java Persistence 2.0, Public Review Draft XML Object/Relational Mapping Descriptor

@Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface TableGenerator { String name(); String table() default ""; String catalog() default ""; String schema() default ""; String pkColumnName() default ""; String valueColumnName() default ""; String pkColumnValue() default ""; int initialValue() default 0; int allocationSize() default 50; UniqueConstraint[] uniqueConstraints() default {}; } </xsd:documentation> </xsd:annotation> <xsd:sequence> <xsd:element name="description" type="xsd:string" minOccurs="0"/> <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:simpleType name="temporal"> <xsd:annotation> <xsd:documentation> @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Temporal { TemporalType value(); } </xsd:documentation> </xsd:annotation> <xsd:restriction base="orm:temporal-type"/> </xsd:simpleType> <!-- **************************************************** --> <xsd:simpleType name="temporal-type"> <xsd:annotation> <xsd:documentation> public enum TemporalType { DATE, // java.sql.Date TIME, // java.sql.Time TIMESTAMP // java.sql.Timestamp } </xsd:documentation> </xsd:annotation> <xsd:restriction base="xsd:token"> <xsd:enumeration value="DATE"/> <xsd:enumeration value="TIME"/>

JSR-317 Public Review Draft

373

10/31/08

Sun Microsystems, Inc.


XML Object/Relational Mapping Descriptor Java Persistence 2.0, Public Review Draft XML Schema

<xsd:enumeration value="TIMESTAMP"/> </xsd:restriction> </xsd:simpleType> <!-- **************************************************** --> <xsd:complexType name="transient"> <xsd:annotation> <xsd:documentation> @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Transient {} </xsd:documentation> </xsd:annotation> <xsd:attribute name="name" type="xsd:string" use="required"/> </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="version"> <xsd:annotation> <xsd:documentation> @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Version {} </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:attribute name="access" type="orm:access-type"/> </xsd:complexType> </xsd:schema>

10/31/08

374

JSR-317 Public Review Draft

Sun Microsystems, Inc.


XML Schema Java Persistence 2.0, Public Review Draft Related Documents

C ha p t e r 1 2

Related Documents

[ 1 ] [ 2 ] [ 3 ]

Enterprise JavaBeans, v. 3.0. Java Persistence API. JSR-250: Common Annotations for the Java Platform. http://jcp.org/en/jsr/detail?id=250. JSR-175: A Metadata Facility for the Java Programming Language. http://jcp.org/en/jsr/detail?id=175. SQL 2003, Part 2, Foundation (SQL/Foundation). ISO/IEC 9075-2:2003. JDBC 4.0 Specification. http://java.sun.com/products/jdbc. JAR File Specification, http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html. Enterprise JavaBeans, v 2.1. http://java.sun.com/products/ejb.

[ 4 ] [ 5 ] [ 6 ] [ 7 ]

JSR-317 Public Review Draft

375

10/31/08

Sun Microsystems, Inc.


Related Documents Java Persistence 2.0, Public Review Draft XML Schema

10/31/08

376

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Early Draft 1 Java Persistence 2.0, Public Review Draft Revision History

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 Persistence 2.0 specification.

A.1 Early Draft 1


Created document from EJB 3.0 Java Persistence API Final Release draft. Added support for collections of embeddables and basic types. Added ElementCollection and CollectionTable annotations. Added support for multiple levels of embeddable classes and embeddable classes. Added support for embeddable classes containing collections of embeddables and basic types. Added support for embeddable classes containing relationships to entities. Cleaned up language for marking a transaction for rollback. Added support for primary keys corresponding to derived identities.

JSR-317 Public Review Draft

377

10/31/08

Sun Microsystems, Inc.


Revision History Java Persistence 2.0, Public Review Draft Early Draft 1

Added MappedById annotation to support derived identities. Clarified that Temporal annotation can be applied to simple primary keys. Added more generalized support for Map collections. Basic, embeddable, and entity types can be map keys and map values. Added MapKeyClass, MapKeyColumn, MapKeyJoinColumn, and MapKeyJoinColumns annotations. Extensions to AttributeOverride annotation to allow it to specify multiple levels of embeddables and to be used with map keys and values and with collections of elements. Extensions to AssociationOverride annotation to allow it to be used to override the mapping of embeddables that contain relationships to entities. Added support for persistently ordered lists using OrderColumn and provider-managed ordering column. Extended OrderBy annotation to handle element collections and ordering by embeddable classes. Added BigInteger and BigDecimal as primary key types. Added catalog and schema to sequence generator. Defined support for combinations of access types within an entity hierarchy and within a managed class. Added Access annotation. 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 context; added CLEAR cascade option. Added orphan removal functionality. Added getEntityManagerFactory method to EntityManager interface. Added getCache to EntityManagerFactory interface. Added Cache interface. Added support for pessimistic locking and new lock mode types. Added PessimisticLockException and LockTimeoutException. Added overloaded find and refresh methods to support locking.

10/31/08

378

JSR-317 Public Review Draft

Sun Microsystems, Inc.


Public Review Draft Java Persistence 2.0, Public Review Draft Revision History

Added support for locking through queries. Added overloaded find and refresh methods added to support locking with standardized and vendor-specific properties and hints. Added standardized hint javax.persistence.lock.timeout for use in locking configuration. Added the standardized properties javax.persistence.jdbc.driver, javax.persistence.jdbc.url, javax.persistence.jdbc.user, javax.persistence.jdbc.password for use in persistence unit and entity manager factory configuration. Added standardized hint javax.persistence.query.timeout for use in query configuration. Added QueryTimeoutException. Updated Query methods getResultList, getSingleResult, executeUpdate to now throw QueryTimeoutException. Added Query getLockMode and setLockMode methods. Added Query getHints and getSupportedHints methods. Added EntityManager getLockMode, getProperties and getSupportedProperties methods. Added EntityManagerFactory getProperties and getSupportedProperties methods. Added Query getNamedParameters and getPositionalParameters methods. Added Query getMaxResults, getFirstResult, and getFlushMode methods. Editorial changes and clarifications.

A.2 Public Review Draft


Added section on naming of database objects. Added EntityManager and Query unwrap methods. Added support for the following to the Java Persistence query language: collections of basic types; collections of embeddable types; nested embeddables; relationships from embeddables; relationships from embeddables in element collections; ordered lists; maps. Added support for operators and functions in query SELECT list. Added support for CASE, NULLIF, COALESCE operations. Added support for date, time, and timestamp literals in queries.

JSR-317 Public Review Draft

379

10/31/08

Sun Microsystems, Inc.


Revision History Java Persistence 2.0, Public Review Draft Public Review Draft

Added support for collection-valued input parameters in query IN expressions. Added use of result variables in SELECT list to support more general ORDER BY functionality. Added entity type expressions to support non-polymorphic queries. Allowed multiple select expressions in subquery result list. Added support for use of identification variables in constructors in SELECT list. Updated XML object/relational mapping schema and overriding rules to reflect mapping functionality available through annotations. Updated persistence.xml. At least one <persistence-unit> element must be supplied. Added Criteria API. Added getQueryBuilder methods to EntityManager and EntityManagerFactory interfaces. Made third argument of Java Persistence query language substring function optional. Added clarification that fetch joins are not supported in subquery FROM clauses. Allowed the use of joins in subquery FROM clauses. Editorial improvements.

10/31/08

380

JSR-317 Public Review Draft