These sections describe recommended development processes:
This section describes the general development stages for EclipseLink applications. Figure 3-1 illustrates the development process.
Define your application requirements, select an architecture, and determine the target platform. EclipseLink works with any architecture and any platform.
When designing the application, you should also create an object model for the application. It is important to create the object model before mapping objects, because defining persistent mappings for an incorrect or rapidly changing model can be very difficult. See Section 3.5, "About Persisting Objects" for more information.
Create the Java classes and decide how the classes should be implemented by the data source. When working with a legacy system, decide how the classes relate to the existing data. If there is no legacy data source to integrate, decide how to store each class in the data source and create the required schema. Alternatively, you can use EclipseLink to create your initial tables.
Using a development tool such as JDeveloper, create descriptors and mappings for the persistent classes. Use sessions to manipulate the persistent classes, including querying and changing data. See Section 1.6, "Key Tools" for more information.
Avoid building all your model's descriptors in a single iteration. Start with a small subset of your classes. Build and test their descriptors, then gradually add new descriptors and relationships. This lets you catch common problems before they proliferate through your entire design.
Write Java code to use database sessions. Sessions are used to query for database objects and write objects to the database.
Generate, package, then deploy the necessary files to your application server. The required information will vary, depending on your environment and architecture.
EclipseLink includes many options that can enhance application performance. You can customize most aspects of EclipseLink to suit your requirements. Use advanced EclipseLink features or write custom querying routines to access the database in specific ways, and to optimize performance.
When you design your application, you must choose how and where to use EclipseLink. You can perform a variety of persistence and data transformation functions on a variety of Java-supported platforms. When you design your application architecture, keep these capabilities in mind.
EclipseLink supports any enterprise architecture that uses Java, including the following:
Java Web servers such as Tomcat
Java clients such as Java SE and Web browsers
Server Java platforms
Application packaging requirements of the specific target platform (for deployment in the host Java or Java EE environment) influence how you use and configure EclipseLink. For example, you package a Java EE application in an Enterprise Archive (EAR) file. Within the EAR file, there are several ways to package persistent entities within Web Archive (WAR) and Java Archive (JAR) files. How you configure EclipseLink depends, in part, on how you package the application and how you use the host application server class loader.
For detailed information about supported application server versions, custom integration, and configuration requirements, see Section 5.1, "Integrating with an Application Server.".
EclipseLink requires that classes must meet certain minimum requirements before they can become persistent. EclipseLink also provides alternatives to most requirements. EclipseLink uses a nonintrusive approach by employing a metadata architecture that allows for minimal object model intrusions.
This section includes the following information:
When implementing your persistence layer using EclipseLink, consider the following options:
When using JPA, you can specify persistence layer components using any combination of standard JPA annotations and
persistence.xml, EclipseLink JPA annotation extensions, and EclipseLink JPA
For more information, see Section 2.1.3, "About Configuration Basics".
Persistence layer components may be coded or generated as Java. To use Java code, you must manually write code for each element of the project including: project, login, platform, descriptors, and mappings. This may be more efficient if your application is model-based and relies heavily on code generation.
You can access the fields (data members) of a class by using a getter/setter method (also known as property access) or by accessing the field itself directly.
When to use method or direct field access depends on your application design. Consider the following guidelines:
Use method access outside of a class.
This is the natural public API of the class. The getter/setter methods handle any necessary side-effects and the client need not know anything about those details.
Use direct field access within a class to improve performance.
In this case, you are responsible for taking into consideration any side-effects not invoked by bypassing the getter/setter methods.
When considering using method or direct field access, consider the following limitations.
If you enable change tracking on a getter/setter method (for example, you decorate method
@ChangeTracking), then EclipseLink tracks changes accordingly when a client modifies the field (
phone) using the getter/setter methods.
Similarly, if you enable change tracking on a field (for example, you decorate field
@ChangeTracking), then EclipseLink tracks changes accordingly when a client modifies the field (
However, if you enable change tracking on a getter/setter method (for example, you decorate method
@ChangeTracking) and a client accesses the field (
phone) directly, EclipseLink does not detect the change. If you choose to code in this style of field access within a class for performance and method access outside of a class, then be aware of this limitation.
For more information, see the description of the
@ChangeTracking annotation in Oracle Fusion Middleware Java Persistence API (JPA) Extensions Reference for Oracle TopLink
Weaving is a technique of manipulating the byte-code of compiled Java classes.
Weaving is used to enhance both JPA entities and Plain Old Java Object (POJO) classes for such things as lazy loading, change tracking, fetch groups, and internal optimizations.
For more information, see Section 3.7, "About Weaving".
When you create persistent Java objects, use direct access on private or protected attributes.
If you are using weaving, the
ValueHolderInterface is not required. For more information, see Section 3.7, "About Weaving." See Section 7.2.1, "Indirection (Lazy Loading)" for more information on indirection and transparent indirection.
The purpose of your application's persistence layer is to use a session at run time to associate mapping metadata and a data source (see Chapter 8, "Understanding Data Access") to create, read, update, and delete persistent objects using the EclipseLink cache, queries and expressions, and transactions.
Typically, the EclipseLink persistence layer contains the following components:
The EclipseLink application metadata model is based on the project. The project includes descriptors, mappings, and various policies that customize the run-time capabilities. You associate this mapping and configuration information with a particular data source and application by referencing the project from a session.
For more information, see the following:
By default, EclipseLink sessions provide an object-level cache that guarantees object identity and enhances performance by reducing the number of times the application needs to access the data source. EclipseLink provides a variety of cache options, including locking, refresh, invalidation, isolation, and coordination. Using cache coordination, you can configure EclipseLink to synchronize changes with other instances of the deployed application. You configure most cache options at the persistence unit or entity level. You can also configure cache options on a per-query basis or on a descriptor to apply to all queries on the reference class.
For more information, see Chapter 9, "Understanding Caching."
For Object-relational architectures, EclipseLink provides several object and data query types, and offers flexible options for query selection criteria, including the following:
JPQL (Java Persistence Query Language)
Query by example
With these options, you can build any type of query. Oracle recommends using named queries to define application queries. Named queries are held in the project metadata and referenced by name. This simplifies application development and encapsulates the queries to reduce maintenance costs.
For Object-relational architectures, you are free to use any of the query options regardless of the persistent entity type. Alternatively, you can build queries in code, using the EclipseLink API.
These query techniques cannot be used with Object-XML (OXM, JAXB) mapping. However you can perform queries when using legacy EIS XML projects.
For more information, see Chapter 10, "Understanding Queries" and Chapter 11, "Understanding EclipseLink Expressions."
Application packaging (for deployment in the host Java or Java EE environment) influences EclipseLink use and configuration. For example, you package a Java EE application in an EAR file. Within the EAR file, there are several ways to package persistent entities within WAR and JAR files. How you configure EclipseLink depends, in part, on how you package the application and how you use the class loader of the host application server.
The EclipseLink approach to deployment involves packaging application files into a single file, such as a JAR or an EAR file. This approach lets you create clean and self-contained deployments that do not require significant file management. After creating these files, deploy the project.
For more information, see Chapter 5, "Understanding Application Deployment."
This section includes a brief description of relational mapping and provides information and restrictions to guide object and relational modeling. This information is useful when building applications.
This section includes information on the following:
Object modeling refers to the design of the Java classes that represent your application objects. You can use your favorite integrated development environment (IDE) or Unified Modeling Language (UML) modeling tool to define and create your application object model.
Any class that registers a descriptor with EclipseLink database sessions is called a persistent class. EclipseLink does not require that persistent classes provide public accessor methods for any private or protected attributes stored in the database. Refer to Section 3.3.2, "Persistent Class Requirements" for more information.
Your data storage schema refers to the design that you implement to organize the persistent data in your application. This schema refers to the data itself—not the actual data source (such as a relational database or nonrelational legacy system).
During the design phase of the application development process, you should decide how to implement the classes in the data source. When integrating existing data source information, you must determine how the classes relate to the existing data. If no legacy information exists to integrate, decide how you will store each class, then create the necessary schema. For more information, see Section 3.1, "Typical Development Stages."
When making objects persistent, each object requires an identity to uniquely identify it for storage and retrieval. Object identity is typically implemented using a unique primary key. This key is used internally by EclipseLink to identify each object, and to create and manage references. Violating object identity can corrupt the object model.
In a Java application, object identity is preserved if each object in memory is represented by one, and only one, object instance. Multiple retrievals of the same object return references to the same object instance—not multiple copies of the same object.
EclipseLink supports multiple identity maps to maintain object identity (including composite primary keys). See Section 9.2, "About Cache Type and Size" for additional information.
EclipseLink uses metadata to describe how objects and beans map to the data source. This approach isolates persistence information from the object model—you are free to design their ideal object model, and DBAs are free to design their ideal schema. For more information, see Section 3.6, "About Metadata".
At run time, EclipseLink uses the metadata to seamlessly and dynamically interact with the data source, as required by the application.
EclipseLink provides an extensive mapping hierarchy that supports the wide variety of data types and references that an object model might contain. For more information, see Chapter 7, "Understanding Mappings."
A foreign key can be one or more columns that reference a unique key, usually the primary key, in another table. Foreign keys can be any number of fields (similar to primary key), all of which are treated as a unit. A foreign key and the primary parent key it references must have the same number and type of fields.
Foreign keys represents relationships from a column or columns in one table to a column or columns in another table. For example, if every
Employee has an attribute
address that contains an instance of
Address (which has its own descriptor and table), the one-to-one mapping for the
address attribute would specify foreign key information to find an address for a particular
Object-oriented systems allow classes to be defined in terms of other classes. For example: motorcycles, sedans, and vans are all kinds of vehicles. Each of the vehicle types is a subclass of the
Vehicle class. Similarly, the
Vehicle class is the superclass of each specific vehicle type. Each subclass inherits attributes and methods from its superclass (in addition to having its own attributes and methods).
Inheritance provides several application benefits, including the following:
Using subclasses to provide specialized behaviors from the basis of common elements provided by the superclass. By using inheritance, you can reuse the code in the superclass many times.
Implementing abstract superclasses that define generic behaviors. This abstract superclass may define and partially implement behavior, while allowing you to complete the details with specialized subclasses.
To have concurrent clients logged in at the same time, the server must spawn a dedicated thread of execution for each client. Java EE application servers do this automatically. Dedicated threads enable each client to work without having to wait for the completion of other clients. EclipseLink ensures that these threads do not interfere with each other when they make changes to the identity map or perform database transactions. Your client can make transactional changes in an isolated and thread safe manner. EclipseLink manages clones for the objects you modify to isolate each client's work from other concurrent clients and threads. This is essentially an object-level transaction mechanism that maintains all of the ACID (Atomicity, Consistency, Isolation, Durability) transaction principles as a database transaction.
EclipseLink supports configurable optimistic and pessimistic locking strategies to let you customize the type of locking that the EclipseLink concurrency manager uses. For more information, see Section 6.2.4, "Descriptors and Locking."
EclipseLink caching improves application performance by automatically storing data returned as objects from the database for future use. This caching provides several advantages:
Reusing Java objects that have been previously read from the database minimizes database access
Minimizing SQL calls to the database when objects already exist in the cache
Minimizing network access to the database
Setting caching policies a class-by-class and bean-by-bean basis
Basing caching options and behavior on Java garbage collection
EclipseLink supports several caching polices to provide extensive flexibility. You can fine-tune the cache for maximum performance, based on individual application performance. Refer to Chapter 9, "Understanding Caching" for more information.
The EclipseLink nonintrusive approach of achieving persistence through a metadata architecture means that there are almost no object model intrusions.
To persist Java objects, EclipseLink does not require any of the following:
Persistent superclass or implementation of persistent interfaces
Store, delete, or load methods required in the object model
Special persistence methods
Generating source code into or wrapping the object model
See Section 3.3, "Building and Using the Persistence Layer" for additional information on this nonintrusive approach. See also Section 3.6, "About Metadata."
An indirection object takes the place of an application object so the application object is not read from the database until it is needed. Using indirection, or lazy loading in JPA, allows EclipseLink to create stand-ins for related objects. This results in significant performance improvements, especially when the application requires the contents of only the retrieved object rather than all related objects.
Without indirection, each time the application retrieves a persistent object, it also retrieves all the objects referenced by that object. This may result in lower performance for some applications.
Oracle strongly recommends that you always use indirection.
EclipseLink provides several indirection models, such as proxy indirection, transparent indirection, and value holder indirection.
Mutability is a property of a complex field that specifies whether the field value may be changed or not changed as opposed to replaced.
An immutable mapping is one in which the mapped object value cannot change unless the object ID of the object changes: that is, unless the object value is replaced by another object value altogether.
A mutable mapping is one in which the mapped object value can change without changing the object ID of the object.
By default, EclipseLink assumes the following:
TransformationMapping instances are mutable
@Basic mapping types, except
Serializable types, are immutable (including
Serializable types are mutable
Whether a value is immutable or mutable largely depends on how your application uses your persistent classes. For example, by default, EclipseLink assumes that a persistent field of type
Date is immutable: this means that as long as the value of the field has the same object ID, EclipseLink assumes that the value has not changed. If your application uses the set methods of the
Date class, you can change the state of the
Date object value without changing its object ID. This prevents EclipseLink from detecting the change. To avoid this, you can configure a mapping as mutable: this tells EclipseLink to examine the state of the persistent value, not just its object ID.
You can configure the mutability of the following:
@Basic mapping type (including
Calendar types) individually;
Mutability can affect change tracking performance. For example, if a transformation mapping maps a mutable value, EclipseLink must clone and compare the value in a unit of work. If the mapping maps a simple immutable value, you can improve unit of work performance by configuring the mapping as immutable.
Mutability also affects weaving. EclipseLink can only weave an attribute change tracking policy for immutable mappings.
For more information, see Section 3.7, "About Weaving". See also the description of the
@Mutable annotation in Oracle Fusion Middleware Java Persistence API (JPA) Extensions Reference for Oracle TopLink.
The EclipseLink metadata is the bridge between the development of an application and its deployed run-time environment. Capture the metadata using the following:
eclipselink-oxm.xml, and annotation and
persistence.xml property extensions. The persistence provider interprets all these sources of metadata to create an in-memory session and project at run time.
Java and the EclipseLink API (this approach is the most labor-intensive).
The metadata lets you pass configuration information into the run-time environment. The run-time environment uses the information in conjunction with the persistent classes (Java objects or entities) and the code written with the EclipseLink API, to complete the application.
For more information, see "Overriding and Merging" in Oracle Fusion Middleware Java Persistence API (JPA) Extensions Reference for Oracle TopLink.
This section describes the following:
The EclipseLink metadata architecture provides many important benefits, including the following:
Stores mapping information in XML—not in the domain model objects
By using the metadata, EclipseLink does not intrude in the object model or the database schema
Allows you to design the object model as needed, without forcing any specific design
Allows DBAs to design the database as needed, without forcing any specific design
Does not rely on code-generation (which can cause serious design, implementation, and maintenance issues)
Is unobtrusive: adapts to the object model and database schema, rather than requiring you to design their object model or database schema to suit EclipseLink
Using EclipseLink JPA, you have the flexibility of expressing persistence metadata using standard JPA annotations, deployment XML, or both and you can optionally take advantage of EclipseLink JPA annotation and
persistence.xml property extensions.
A project contains the mapping metadata that the EclipseLink runtime uses to map objects to a data source. The project is the primary object used by the EclipseLink runtime.
This section describes the principal contents of project metadata, including the following:
For Object-relational mapping, the EclipseLink runtime constructs an in-memory project based on any combination of JPA annotations,
orm.xml, and EclipseLink JPA annotation and
persistence.xml property extensions.
For Object-XML mapping, the EclipseLink runtime uses a combination of JAXB annotations and
eclipselink-oxm bindings. See "Overriding and Merging" in Oracle Fusion Middleware Java Persistence API (JPA) Extensions Reference for Oracle TopLink.
EclipseLink maps persistent entities to the database in the application, using the descriptors and mappings you build with JDeveloper. These tools support several approaches to project development, including the following:
Importing classes and tables for mapping
Importing classes and generating tables and mappings
Importing tables and generating classes and mappings
Creating both class and table definitions
The most common solution is to develop the persistent entities using a development tool, such as a modeling tool or an integrated development environment (IDE) like JDeveloper, and to develop the relational model through appropriate relational design tools. You then use JDeveloper to construct mappings that relate these two models.
Although JDeveloper offers the ability to generate persistent entities or the relational model components for an application, these utilities are intended only to assist in rapid initial development strategies–not complete round-trip application development.
For POJO projects, you configure a session login in the session metadata that specifies the information required to access the data source.
For more information, see Section 3.6.3, "Creating Session Metadata."
A EclipseLink session contains the information required to access the data source. The session is the primary object used by your application to access the features of the EclipseLink runtime.
Using EclipseLink JPA, the EclipseLink runtime constructs an in-memory session based on any combination of JPA annotations,
orm.xml, and EclipseLink JPA annotation and
persistence.xml property extensions. The use of a
sessions.xml file is optional. See "Overriding and Merging" in Oracle Fusion Middleware Java Persistence API (JPA) Extensions Reference for Oracle TopLink.
Weaving is a technique of manipulating the byte-code of compiled Java classes. The EclipseLink JPA persistence provider uses weaving to enhance both JPA entities and Plain Old Java Object (POJO) classes for such things as lazy loading, change tracking, fetch groups, and internal optimizations.
Weaving can be performed either dynamically at runtime, when entities are loaded, or statically at compile time by post-processing the entity
.class files. By default, EclipseLink uses dynamic weaving whenever possible, including inside a Java EE application server and in Java SE when the EclipseLink agent is configured. Dynamic weaving is recommended as it is easy to configure and does not require any changes to a project's build process.
This section describes the following:
Use dynamic weaving to weave application class files one at a time, as they are loaded at run time. Consider this option when the number of classes to weave is few or when the time taken to weave the classes is short.
If the number of classes to weave is large or the time required to weave the classes is long, consider using static weaving.
Use static weaving to weave all application class files at build time so that you can deliver prewoven class files. Consider this option to weave all applicable class files at build time so that you can deliver prewoven class files. By doing so, you can improve application performance by eliminating the runtime weaving step required by dynamic weaving.
In addition, consider using static weaving to weave in Java environments where you cannot configure an agent.
EclipseLink uses weaving to enable the following for POJO classes:
EclipseLink weaves all the POJO classes in the JAR you create when you package a POJO application for weaving.
EclipseLink weaves all the classes defined in the
persistence.xml file, that is:
All the classes you list in the persistence.xml file.
All classes relative to the JAR containing the
persistence.xml file if element
<exclude-unlisted-classes> is false.
The default EclipseLink weaving behavior applies in any Java EE JPA-compliant application server using the EclipseLink JPA persistence provider.To change this behavior, modify your persistence.xml file (for your JPA entities or POJO classes) to use EclipseLink JPA properties, EclipseLink JPA annotations, or both.
To disable weaving using EclipseLink persistence unit properties, configure your
persistence.xml file with one or more of the following properties set to false:
eclipse.weaving; disables all weaving
eclipselink.weaving.lazy; disables weaving for lazy loading (indirection)
eclipselink.weaving.changetracking; disables weaving for change tracking
eclipselink.weaving.fetchgroups; disables weaving for fetch groups
eclipselink.weaving.internal; disables weaving for internal optimization
eclipselink.weaving.eager; disables weaving for indirection on eager relationships