Tuesday, September 14, 2010

Type-safe JPQL query results with JPA 2.0

If you use the Eclipse IDE or Rational Application Developer (RAD) for your Java development, you probably make an effort to keep an eye out for warnings flagged in your code and spend some amount of time cleaning them up. That is why they are there, right? To help make sure your code is top notch. Warnings are even more prevalent if you have a large amount of pre-Java 5.0 code and have moved to Java 5 or Java 6. If you had a fairly warning-free code base and moved to Java 5 or newer you've probably encountered a barrage of new warnings in your workspace. The introduction of Java generics in Java 5.0 is one of the major culprits for all these new warnings. The use of collection classes (Collection, Set, List, etc.) that you happily used in your code are now all warning flagged as needing to be parameterized/typed.

If you are a user of JPA, normal usage of some of the JPA APIs (primarly those from JPA 1.0) will add to your warning woes. For example, result list processing of JPQL queries returns an untyped result list that will get flagged as needing type information. Let's say you have some code that creates a JPQL query, executes it, and prints out the result.

Query q = em.createQuery("SELECT e FROM Employee e");
List employees = q.getResultList();
if (employees != null) {
  for (int i = 0; i < employees.size(); i++) {
    Employee emp = (Employee)employees.get(i);
    System.out.println("Employee id=" + emp.getId() + ", name=" + e.getName());
  }
}


The Eclipse IDE will flag the 2nd line as a warning, telling you that you need to parameterize the List. A quick and dirty way to get rid of the warning is to wildcard the List definition, informing the compiler the list is untyped.

List<?> employees = q.getResultList(); // Good-bye, warning!

This makes a dent in your warning count, but doesn't really buy you much. You are left with potentially unsafe type casts and result processing is still a bit messy. This is where a new feature/interface of JPA 2.0, TypedQuery shines. The TypedQuery interface provides the ability to operate on query results and parameters in a more type-safe manner. The TypedQuery interface is actually geared more toward the new programmatic Criteria API, but provides benefits for JPQL queries as well. Here's an example of how one might write the original code using a TypedQuery.

TypedQuery<Employee> tq = em.createQuery("SELECT e FROM Employee e",     Employee.class);
for (Employee emp : tq.getResultList()) {
  System.out.println("Employee id=" + emp.getId() + ", name=" + e.getName());
}

The compile time warnings are gone, the casts are gone, and we are able to use the new iterator-based for loop to cleanly process the query result. Looks great, right? Well, there is a caveat. Currently, JPQL-based TypedQuery does not support the use of the JPA 2.0 Tuple to process multi-valued results (for example, returning multiple entity types in a single "row" of the result). However, the JPA 2.0 Criteria API does provide full Tuple support - along with all around true type-safety for query, query result, and query parameters. With any luck the ability to use Tuple with JPQL may make its way in a future version of the JPA specification. But, if your JPQL queries primarily return a single value type, the TypedResult support for JPQL currently provided in JPA 2.0 could go a long way toward writing cleaner code.

-Jeremy

Wednesday, July 7, 2010

Using Bean Validation with the OSGi/JPA 2.0 Feature Pack

Do you have applications littered with layers of inconsistent validation logic or are writing a new application that will require data validation? Bean validation (JSR-303 - part of the Java EE6 family of specifications) defines an API for providing runtime validation of data within Java beans. In addition, other EE6 specifications such as JPA 2.0, JSF, and JCA provide tight integration with bean validation, allowing runtime validation to occur seemlessly with your persistence, resource/connectivity, and UI logic.

Using bean validation within the app server requires a JSR-303 spec API library, the bean validation provider library(ies), and any supporting libraries. If you'd like to test drive bean validation with JPA 2.0, the
WebSphere Application Server V7 Feature Pack for OSGi Applications and Java Persistence API 2.0 does not include a bean validation API or provider, but it does include a provision for wiring one in yourself. The wiring is pretty simple and is briefly explained in this IBM Infocenter document Using Bean Validation with JPA. With the information provided in the article, I was able to configure WebSphere Application Server to use Apache's Bean Validation provider using these steps.
  1. Install WebSphere Application Server V7 with the Fixpack required for the feature pack (currently 7.0.0.9). There is a free Developer's Edition if you don't have the V7 test server for RAD 7.5 or an extra license lying about. :-)
  2. Install the WebSphere Application Server V7 Feature Pack for OSGi Applications and Java Persistence API 2.0.
  3. Download the Apache Bean Validation Spec API jar. Save to a location such as:
    /opt/apache/specs/geronimo-validation_1.0_spec-1.1.jar
  4. Download the Apache Bean Validation Core jar. Save to a location such as:
    /opt/apache/bval/bval-core-0.1-incubating.jar
  5. Download the Apache Bean Valdation JSR-303 jar. Save to a location such as:
    /opt/apache/bval/bval-jsr303-0.1-incubating.jar
  6. Download Apache Commons Bean Utils. Extract the distribution and locate commons-beanutils-1.8.3.jar. Copy the jar to a location such as:
    /opt/apache/commons/commons-beanutils-1.8.3.jar
  7. Download Apache Commons Lang 2.4. Extract the distribution and locate commons-lang-2.4.jar. Copy the jar to a location such as:
    /opt/apache/commons/commons-lang-2.4.jar
  8. Start the app server.
  9. Open the WebSphere Integrated Solutions Console in your browser (http://<server:port>/admin).
  10. In the navigation pane expand Servers -> Server Types and click on WebSphere application servers.
  11. Select the server profile to configure. Typically server1 in a default single server environment.
  12. Under the Server Infrastructure section, select Process Definition.
  13. Under the Additional Properties section, select Java Virtual Machine.
  14. Under the Additional Properties section of the JVM settings, select Custom properties.
  15. Click New and add a property named com.ibm.websphere.validation.api.jar.path and set the value to the location of the bean validation API jar. (ex. /opt/apache/specs/geronimo-validation_1.0_spec-1.1.jar)
  16. Restart the application server.

The application server is now configured to locate and load the bean validation spec API jar. The spec API classes are now available, but the application server (being an EE5 app server) does include a bean validation provider. You need to make a provider available to your application by either bundling it with your application archive (in the proper location within a war or ear) or via a shared library. Include the bean validation core, bean validation jsr-303 component, commons bean utils, and commons lang 2.4 jars within the application or shared library and you'll be off to the races.

That's all there is to configuring the application server. To actually build applications which take advantage of bean validation constraints, you'll need to specify the spec API library in the build path of your tooling. The examples in Apache Bean Validation Primer will help you get started. The example in the primer is targeted for a JSE environment (I'm working on a JEE version -- no ETA), but the JPA entities, constraints, validators, and logic can be easily ported to an EE environment. One additional very important item to note is that your persistence.xml must be updated to version 2.0 in order for bean validation to be enabled by the JPA provider (OpenJPA). Since the 2.0 schema is backward compatible, it is typically a simple one line XML change. The JPA Integration section of the primer contains the rationale for this requirement and an example.

-Jeremy

Wednesday, June 23, 2010

OpenJPA OpenBooks sample available for WebSphere Application Server

A JEE version of OpenJPA's OpenBooks sample is now available for WebSphere Application Server with the WebSphere Application Server V7 Feature Pack for OSGi Applications and Java Persistence API 2.0. OpenBooks is a sample application that highlights many of the new features of JPA 2.0. The sample can be built from source obtained from the Apache's OpenJPA svn repository. If you are not familiar with svn, don't let it deter you from getting the sample. Use of svn for basic functions, like checking out a source tree, is a piece of cake. If you are in a single server environment, the OpenBooks build scripts (run with WebSphere's ws_ant) will compile, package, install, and configure OpenBooks. The OpenBooks instructions will help you get going. In particular, take a look at the section Deploy OpenBooks in an Application Server. This section contains some WebSphere-specific instructions.

The build scripts are primarily targeted for a single server environment, but may work in an ND environment as well. By default, OpenBooks is installed to the default server and port and the script assumes admin security is disabled. If you need to target a specific server and/or have security enabled, there are command line variables you can use to specify these details. The script is currently all or nothing, so if you specify one, you must specify all. For example:

$ /opt/WebSphere/AppServer/bin/ws_ant -Dbuild.mode=jee -Dappserver=was -Dwas.home=/opt/WebSphere/AppServer -Dwas.server=localhost -Dwas.port=8880 -Dwas.conntype=SOAP -Dwas.user=myuser -Dwas.password=mypassword

This invocation will install OpenBooks on the local machine with the profile serviced by SOAP admin port 8880 with the specified credentials. The script creates a new Derby data source (which is also configured to create a new database if it doesn't exist) by default, but if you are data source savvy you can easily configure the OpenBooks Data Source and OpenBooks Non-transactional Data Source to point at your own database. Assuming your build and install was successful, point your browser at http://<server>:<port>/OpenBooks to run the sample. Enjoy!!

-Jeremy

Monday, April 26, 2010

Apache OpenJPA 2.0.0 Now Available!

I am proud to announce the availability of Apache OpenJPA 2.0.0!

This distribution is based on the final JSR 317 Java Persistence API, Version 2.0 specification and passes the JPA 2.0 TCK, while remaining backwards compatible with prior releases based on the Java Persistence API (JPA 1.0) part of Java Community Process JSR-220 (Enterprise JavaBeans 3.0).

The WebSphere JPA solution is based on the Apache OpenJPA project.

Check it out!

Kevin

Thursday, March 4, 2010

Beta 2 of Apache OpenJPA now available!

As we continue to march towards a 2.0.0 release of OpenJPA, we recently announced a Beta 2 of the OpenJPA 2.0.0 deliverable. This release contains additional bug fixes and performance improvements in addition to continuing our TCK compliance.

Enjoy! Let us know your views and comments either via this forum or the OpenJPA mailing lists.

Thanks,
Kevin

Friday, February 12, 2010

WebSphere V7 Feature Pack for OSGi Applications and Java Persistence API (JPA) 2.0 Open Beta now Available!

I actually have two announcements to make. From a WebSphere perspective, I am pleased to announce the availability of the IBM WebSphere Application Server V7 Feature Pack for OSGi Applications and Java Persistence API (JPA) 2.0 Open Beta.

I know that's a mouth full, but this announcement clearly demonstrates IBM's commitment to both the OSGi and JPA programming models. Each of these features can be individually installed on a WebSphere v7 system (specifically, 7.0.0.7). More details on the specifics can be found on the official announcement page above.

The other item I would like to announce is the availability of the Apache OpenJPA 2.0.0-beta release. This beta release is 100% compatible with the JPA 2.0 TCK, plus it contains several other improvements outlined on the announcement. This OpenJPA 2.0.0-beta has been available for a couple of weeks, but I was waiting to announce it in conjunction with the WebSphere Open Beta. (Apache OpenJPA provides the basis for the WebSphere JPA solution.)

So, whether you are a WebSphere customer or just interested in experimenting with the latest JPA 2.0 feature set, one of these two offerings should fit the bill. Enjoy!

Friday, January 22, 2010

Basic tutorial for OpenJPA

Take a look at this new tutorial on the Apache site.

Begin using OpenJPA - The Basics
This sample and tutorial steps through the requirements, setup, code and deployment of an OpenJPA implementation with a JSP web application on Geronimo. It is geared for those that are just beginning with OpenJPA. Users will be given detailed instructions for each part of the setup including the setup of Eclipse, Geronimo and the Derby database. For those developers that have been wanting to explore the power of OpenJPA, this is where you begin.

This will get someone going in OpenJPA even if they are new to Geronimo, Derby and OpenJPA