EclipseLink JPA Deployed on GlassFish 2.1 using Eclipse WTP

Note: This tutorial' is under construction for the next week as of 20091207 as part of JPA 2.0 compliance for the Glassfish V3 server in enhancement #296269 .

If you want to get a small web application running quickly on GlassFish - the services provided by the Web Tools Project plugin in the Eclipse IDE can take care of the deployment details and set the server into debug mode for you.

This basic example details how to use Eclipse to run/debug a minimum J2EE web application servlet using EclipseLink JPA as the persistence provider. The goal of this example is to detail the minimum steps needed to run EclipseLink inside SUN GlassFish using the Eclipse IDE - at this point no presentation/controller layer such as JSF, Spring or Struts will be used beyond a basic HttpServlet so we can concentrate on the the integration layer JPA setup.

The DALI project was used to generate Entities from a schema with sequences already populated.

The details described here are valid for both GlassFish V2 2.1.1 and the SUN Java System Application Server 9

After EAR project creation - reference the org.eclipse.peristence.core and jpa projects or include a reference to eclipselink.jar in your EJB project and reference the EJB project from your WAR project.

If you don't reference the eclipselink.* projects then include a classpath reference to persistence.jar and an Oracle (or other Database) JDBC driver jar for your DB - You will need to put this JDBC driver jar in your /domains/domain1/lib directory as well.

UML Data Model

The following single entity Cell has a @ManyToMany bidirectional relationship to itself.

Tutorial Design

The goal of the tutorial is to demonstrate a quick start end-to-end deployment on a specific application server of an EclipseLink JPA application.
To accomplish this...

The web framework is a simple servlet so we avoid container specific issues around JSF implementation.

The data model is very simple (@ManyToMany) - as the other tutorials get into more advanced JPA entity concepts and annoations

The datasource is globally defined (by the user) on the server - with the only configuration setting being the jta-data-source element in persistence.xml

DDL/Schema Generation

The database schema for this example can be automatically generated using the DDL generation capability of EclipseLink (normally only used by development or for demos). The following project in SVN can be run as an application managed stand-alone JPA project that has ddl-generation turned on in the persistence.xml.

Note: DDL Generation is not possible on a container managed entity manager connected to a JTA datasource - hence the use of a separate project that is server agnostic and sharable by all the JPA Web application tutorials in this section of the Wiki.

JPA Entity Configuration

For all other application servers that support JPA 1.0 profiled so far (WebLogic, OC4J, Tomcat and JBoss) - I was able to use BigDecimal as the @Id for entity classes. In GlassFish 2 I had to switch to using BigInteger (or Long) as the entity @Id.

Perform CRUD operations: JPQL insert and query

Browser Output

Troubleshooting

EJBException on valid JPA 2.0 API

The following exception will occur if you are running the default JPA 1.0 API that ships with Glassfish V2 because it is JEE5 compliant - you will need the JPA 2.0 API specification jar higher in your server classpath.

javax.ejb.EJBException
at com.sun.ejb.containers.BaseContainer.processSystemException(BaseContainer.java:3903)
at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:3803)
at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:3605)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1388)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1325)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:205)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:127)
at $Proxy32.getMetamodel(Unknown Source