Platinum Partner
java,eclipse,jpa

Introducing EclipseLink

The Eclipse Persistence Services Project, more commonly known as EclipseLink, is a comprehensive open source persistence solution.  EclipseLink was started by a donation of the full source code and test suites of Oracle's TopLink product. This project brings the experience of over 12 years of commercial usage and feature development to the entire Java community. This evolution into an open source project is now complete and developers will soon have access to the EclipseLink 1.0 release.

We describe EclipseLink as a comprehensive solution because it delivers not one, but a set of persistence services enabling developers to efficiently develop applications that access data in a variety of data sources and formats.  EclipseLink's services currently include object-relational with JPA, object-XML binding in MOXy (with support for JAXB), and a Service Data Objects (SDO) implementation sharing a common mapping core. EclipseLink’s most popular persistence service is dealing with relational databases through JPA. In this article I'll introduce the EclipseLink JPA implementation and some of its advanced features.  We'll delve into the other persistence services in future articles.


JPA and Beyond

EclipseLink 1.0 supports JPA 1.0 and also offers many advanced features. The project's intent is to deliver a standards based solution focussed on JPA but with the abilitity to use advanced features for those applications where they are required. By focusing first on JPA, the EclipseLink project enables broad integration and minimizes coupling. With the recent announcement that EclipseLink will be delivering the reference implementation of JPA 2.0 (JSR 317) the project team will continue to lead the standardization of many of the advanced features. 

Advanced object-relational mappings in EclipseLink JPA offers greater flexibility when dealing with complex or legacy relational schemas. This mapping support has evolved over many years of commercial use dealing with many 'interesting' (i.e., challenging) domain models and relational schemas. The resulting support is supported through JPA where possible and configurable with EclipseLink specific mappings when no cooresponding features exists in JPA.  As mentioned above, some advanced features are making their way into JPA 2.0 and over time you can expect the use of implementation specific features to decline as the specification evolves.


Converters

Converters allow developers to customize how database values are converted into the domain model and how these values are then written back into the database. This supports user-defined types as well as custom conversion logic that can be used with any mapping. Converters are defined once for a persistence unit and can then be used in any entity through their unique name. All converters implement EclipseLink's Converter interface.

@Converter(name="money-converter", converterClass=mypackage.MyMoneyConverter.class)

...

@Convert("money-converter")
private Money balance;

The above example shows how a developer can write their own converter class and then define it under a user provided name.  Once defined, a Converter can be attached to any number of mappings through the @Convert annotation or in an XML mapping file. EclipseLink also provides out of the box converters for handing primitive value and type conversions and some database specific data types.

Caching 

EclipseLink's object caching solution is one of its most unique and powerful features. While most persistence solutions choose to cache data rows and rebuild objects when a cache hit occurs, EclipseLink has gone further and caches entities with all the defined data conversions applied. This approach to caching greatly improves performance and reduces the amount of garbage created when accessing cached objects. The caching is also very flexible, allowing developers complete control over L1 and L2 cache usage, lifecycle, refreshing, cluster coordination and concurrency protection to minimize and handle stale data scenarios. As with all caching solutions the performance and scalability benefits are gained when the solution is tuned with respect to the applications usage of the data and the behavior of the underlying database, which is often shared with other applications in the enterprise.

EclipseLink caching can be configured using annotations or XML. Here is an example of how the @Cache annotation can be used:

@Cache(
    // Cache a number of objects with Hard references
    // and the remainder with Weak references
    type = CacheType.HARD_WEAK, 
    // Number of Hard references to hold
    size = 500, 
    // Store instances in the shared (L2) cache
    shared = true, 
    // When changes are made to an object
    // invalidate (mark dirty) instances in other nodes
    coordinationType =
        CacheCoordinationType.INVALIDATE_CHANGED_OBJECTS)
public class MyEntity 


One of the trade offs when using caching in a persistence solution is dealing with potential for stale data in the cache. While the application specific configuration of the cache can minimize stale data it is strongly recommended that you have a locking strategy using optimistic and/or pessimistic locking. Users of EclipseLink can leverage the standard JPA @Version mechanism for mapping a numeric or timestamp value in their entity to a column. While this is probably the easiest solution to manage from a mapping perspective, it does not always work with pre-existing schemas where additional columns cannot be added or other applications will not honor the optimistic locking semantics when modifying the database. To address these situations, EclipseLink JPA offers additional optimistic locking policies as well as pessimistic locking.

@Entity
@OptimitisticLocking(CHANGED_COLUMNS)
public class MyEntity

As shown here, an EclipseLink @OptimisticLocking policy can be specified on entities where no version column exists in the database and adding one is simply not an option.  The CHANGED_COLUMNS policy in the example ensures that all columns changed in a transaction  still have the same values in the database as when they were read.  If any of the columns that are to be updated have been changed by another application, an optimistic lock exception is thrown.   This is just one of a number of optimistic locking policies that are available to deal with different schemas and concurrent update scenarios.
 
 

Using Stored Procs

There are times when users need to override the SQL EclipseLink JPA generates from JPQL and and mappings. JPA supports native queries where the resulting rows are mapped onto an Entity based on the resulting column names or through the provided result set mapping.  EclipseLink goes further and allows stored procedures to be used for any database operation and as named queries. In the example below, a named query is defined that uses a stored procedure to query for an Address entity. 

    @NamedStoredProcedureQuery(
        name="Address.findById",
        resultClass=Address.class,
        procedureName="SProc_Read_Address",
        parameters={
            @StoredProcedureParameter(name="address_id_v",
                    queryParam="ADDRESS_ID", direction=IN_OUT),
            @StoredProcedureParameter(name="street_v",
                    queryParameter="STREET",  direction=OUT),
            @StoredProcedureParameter(name="city_v",
                    queryParameter="CITY", direction=OUT),
            @StoredProcedureParameter(name="country_v",
                    queryParameter="COUNTRY", direction=OUT),
            @StoredProcedureParameter(name="province_v",
                    queryParameter="PROVINCE", direction=OUT),
            @StoredProcedureParameter(name="p_code_v",
                    queryParameter="P_CODE",  direction=OUT)
        })  


 
This stored procedure can then be excuted using the standard named query API.

Address address = (Address) em.createNamedQuery("Address.findById").
                                            setParameter("ADDRESS_ID", 1).
                                            getSingleResult();  
 

As this example illustrates, defining a named query with a stored procedure is straight forward and its execution can be invoked using the standard API. The intent is to allow users to replace the definition of a NamedQuery with a NamedStoredProcedureQuery where necessary for performance reasons or to leverage exisiting stored procedures.  The implementation of a NamedQuery is opaque to callers which means this kind of switch can be done without affecting the application's usage code. In addition to using stored procedures for named queries it is also possible to customize an entity's default queries (select, insert, update, delete) to use stored procedures as well.

Joining and Batching of Relationships

A common problem faced by many applications is excessive SQL generated as graphs of related entities are loaded. This is typically addressed through joined reading of entities to increase the amount of data retrieved in a single query.  JPA currently offers support in its query language for 'JOIN FETCH' to indicate relationships which should be joined and loaded when a query is executed. 

List<Employee> emps = em.createQuery("SELECT e FROM Employee e JOIN FETCH
                                        e.address").getResultList();

This does address many situations but it lacks support for multi-level joining and does not allow batch loading of relationships in separate joined queries. EclipseLink addresses these current limitations with query hints that can be placed on dynamic or named queries to efficiently load deep graphs using join and batch reading capabilities. In the following example, query hints are used to optimize the graph loading of a set of Employee entities using joining on the M:1 and 1:1 relationships and batching on the 1:M relationships.

List<Employee> emps = em.createQuery(
                        "SELECT e FROM Employee e ORDER BY e.lastName ASC,
                         e.firstName ASC")
                .setHint(QueryHints.FETCH, "e.address")
                .setHint(QueryHints.FETCH, "e.manager")
                .setHint(QueryHints.FETCH, "e.manager.address")
                .setHint(QueryHints.BATCH, "e.phoneNumbers")
                .getResultList();

This approach addresses the need for deep object graph loading at the query level. When users require that joining or batching be used on all queries for a specific entity's mappings they can specify these on the mappings as well. In this example the joining is configured on the mappings directly and it is specified to be outer joining as well.

    @OneToOne
    @JoinColumn(name="ADDR_ID")
    @JoinFetch(JoinFetchType.OUTER)
    private Address address;

 

EclipseLink JPA and Tooling

One of the most common misconceptions is that all open source projects at the Eclipse Foundation are focussed on the Eclipse IDE. While the Eclipse IDE is what Eclipse may be best known for, it is definitely not the only type of project being developed and maintained at Eclipse. EclipseLink is a runtime persistence solution for Java EE, Java SE, Web, and OSGi environments. While it does offer useful development utilities it is a runtime solution and is not dependent on the Eclipse IDE. 

However, developers who do use the Eclipse IDE can take advantage of the JPA tooling support offered by the Dali Java Persistence Tools project.  Beyond Eclipse, Oracle JDeveloper and Sun's NetBeansTM will both be offering extended support for EclipseLink's advanced features in upcoming releases.

Within the Eclipse Ganymede release users of the Dali tooling will find both standard JPA support as well as support for EclipseLink specific features.  When you use the New JPA Project wizard 

[img_assist|nid=3816|title=|desc=|link=none|align=undefined|width=171|height=226] 

you can specify which JPA runtime platform you wish to use.

[img_assist|nid=3817|title=|desc=|link=none|align=undefined|width=500|height=176]
  
By selecting EclipseLink you enable rich editors for configuring many of EclipseLink's advanced features including:

  • Connection Pooling
  • Logging
  • Schema Generation
  • Weaving ConfigurationC
  • Customizers and Event Listeners


EclipseLink and OSGi

OSGi has a growing presence in the Java community. However, one of the challenges to OSGi development is lack of commercial and open source frameworks that are fully OSGi compatible.  EclipseLink 1.0 is fully compatible with OSGi.  Unlike other persistence frameworks, EclipseLink is packaged as a set of OSGi bundles ready for use on any OSGi runtime. Among those using EclipseLink in OSGi is Sun Microsystems in the GlassFish V3 application server which is based on the Apache Felix OSGi runtime.  While running on all OSGi runtimes, EclipseLink is able to leverage runtime specific features.  For example, in Equinox, EclipseLink JPA integrates with the advanced class loading infrastructure to enable byte code weaving of Entities.


How to get started with EclipseLink?

Those wanting to use EclipseLink in their projects have a number of options available. The EclipseLink project's home at the Eclipse Foundation (www.eclipse.org/eclipselink ) provides access to official releases, monthly milestones, nightly builds and direct access to the project's Subversion code repository. Also available are developer and user mailing lists, newsgroup, complete documentation hosted on the wiki, and examples illustrating how to use EclipseLink in a variety of situations.

In addition to direct access to EclipseLink from the project's home at Eclipse.org, developers can also find EclipseLink in a number of commercial products and open source projects. EclipseLink will be included with Oracle TopLink so it will be available in future versions of Oracle's Application Server. Sun Microsystems' selection of EclipseLink as the JPA 2.0 reference implementation means that  EclipseLink is included with both GlassFish and the Sun Application Server. As of version 2.5.2, the Spring Framework ships EclipseLink and includes the necessary code to allow it to be used as an integrated JPA provider. This initial list is substantial in terms of the number of Java developers who have or will have access to EclipseLink through the other products and open source projects they already use.

For developers currently using Oracle TopLink or TopLink Essentials, EclipseLink is a natural upgrade.  EclipseLink is Oracle's strategic Java persistence implementation within Oracle Fusion Middleware going forward. How-to guides focused on migration to EclipseLink from previous versions as well as migration utilities to simplify the slight metadata and package naming changes are provided.

Summary

The EclipseLink project's emergence in the open source Java community is intended to change the landscape in this space. We currently have dedicated group of 28 committers from Oracle and Sun as well as additional contributions from a growing community. Our challenge is to continue what we started with TopLink where we evolved the product based on the changes in Java technology and the feedback of our users. Now we need to grow as an open source community consisting of committers, contributors and users where open communication channels enable feedback and ongoing evolution of the project. We invite you to download EclipseLink for yourself and participate in the growing community around the project.


Authors:

    Doug Clarke - douglas.clarke@oracle.com
        Director of Product Management - Oracle TopLink
        EclipseLink Project co-lead
        Eclipse RT Project PMC
        Eclipse Architecture Council

    Shaun Smith - shaun.smith@oracle.com
        Principal Product Manager - Oracle TopLink
        EclipseLink Eco-System Development Lead
        Eclipse Dali and Teneo Projects Committer

{{ tag }}, {{tag}},

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}
{{ parent.authors[0].realName || parent.author}}

{{ parent.authors[0].tagline || parent.tagline }}

{{ parent.views }} ViewsClicks
Tweet

{{parent.nComments}}