The focus of this article is on the creation of Java™ Persistence Architecture (JPA) entities with these characteristics:
- You generate them from pre-existing relational tables (sometimes referred to as a "bottom-up" approach).
- They use database-generated primary key values for the ID attribute.
- They are part of a composition (or aggregation) of one or more other JPA entity beans (for example, one-to-one or many-to-one relationships).
To leverage database-generated primary key values for your JPA entities you will use the IBM® DB2® built-in and convenient Identity Value Generation capability.
Although they are not the focus for this article, the application will use an Enterprise JavaBean™ (EJB) 3.0 Stateless Session Bean and a servlet that uses the Servlet 2.5 specification.
Before you start
You will use the Java™ Enterprise Edition (JEE) 5.0 specifications to develop the application. To construct the application you will use:
- IBM® Rational® Application Developer Version 7.5.5
- IBM® DB2® Server Edition version 9.5.5 for Windows.
- IBM® WebSphere® Application Server 126.96.36.199 (by using the WebSphere Test Environment that is available with Rational Application Developer)
To replicate the steps for this article, you will need to install DB2 Server Edition v9.5.5 on the same Microsoft® Windows® machine as Rational Application Developer v7.5.5.
There are a few resources that you will use to build upon, including a script to create your initial DB2 database and some artifacts for your enterprise Java application.
Extract the resources568.zip file to a location of your choice on your file system. It should contain two files: createMembersDB.sql and AcmeMembershipApplication.ear.
Working with the ACME membership system
Figure 1 represents the physical relational database for Acme's membership subsystem.
Figure 1. The Acme membership data model
To receive Acme Co.'s services and benefits, clients must become members. Clients can choose from Single, Student, or Family memberships (the membership_type field in the Membership table identifies the type of membership). Family memberships provide Acme's services to couples and any children that they have who are under the age of 18. To remain members in "good standing," clients must renew their memberships annually.
All memberships will have, at most, one primary member. The primary member is responsible for keeping the membership in good standing and for paying the annual subscription fees.
In addition to having a primary member, a family membership will normally have one or more dependents. There are two types of dependents in a family membership: the spouse and any children younger than 18.
All correspondence between Acme Co. and its members occurs solely through the primary member. Acme collects the address and other contact information for the primary member for all memberships for this purpose.
Importing the Acme membership database
Acme's membership database is a core piece of its membership submodule. You will begin by importing Acme's membership database schema into DB2.
- From your Windows Start menu, select Start >All Programs > IBM DB2 > DB2Copy1 (Default) > Command Line Tools > Command Editor.
- From the Command Editor menu bar, click Selected > Open, and browse to where you extracted the createMembersDB.sql file.
- Execute the SQL and DDL statements by choosing Selected > Execute from the menu bar of the DB2 Command Editor window.
- Upon successful execution of the SQL and DDL commands, finish by selecting Command Editor > Exit.
Using the DB2 Identity Value Generation capability
Having the database generate values for the primary key for a table (and by extension, any foreign key values for related tables) eliminates the burden from the application from having to do so. That is, not having to generate unique key values for persistent objects within the application allows the focus to remain on core business logic and business rules. This has the positive consequence of enhancing the application's maintainability and readability.
Acme's lead data and application architects want to use the DB2 Identity Value Generation function to remove that burden from the business logic of their various applications. To leverage that capability, JPA can defer assignment of an entity's ID attribute to the relational database.
Configuring the capability
In the previous section, you imported the database by running the supplied SQL script. However, you still need to configure the primary key of the MEMBERSHIP table to use DB2's Identity value generation facility.
- From Windows, select Start >All Programs > IBM DB2 > DB2Copy1 (Default) > General Administration Tools > Control Centre.
- In the left tree view pane of the Control Center, expand All Databases >MEMBERS folder, and select the Tables folder.
- From the corresponding list of tables that show up in the top center view of the Control Center, select the Membership table, right-click, and select Alter to launch the Alter Table dialog window (see Figure 2).
Figure 2. The Alter Table dialog window for changing column attributes
- In the Alter Table dialog window, select the ID column and click the Change button, which will launch the Change Column dialog window.
- In the Change Column dialog window, click the Value generation tab.
- Select the Identity radio button as shown in Figure 3 and click OK.
- Click OK again to close the Alter Table dialog and complete the change to the MEMBERSHIP table
Figure 3. Changing the primary key to use the Identity Value Generation function
Setting the primary key to use the Identity Value Generation function has some other interesting things to be aware of:
- Selecting Identity also makes it impossible for the column to be null. That is, this field will always store a generated value in each row.
- The Initial value and Increment fields (as shown in Figure 3) can set the value of the initial row and each subsequent row.
In Figure 3, you were modifying the primary key of an existing table using the Change Column dialog window. Alternatively, you could define the primary key to use Identity value generation at the time you were defining the table and adding the primary key column itself.
Before you generate the JPA entities, you need to:
- Import the beginnings of a JEE 5.0 Enterprise Application Project that will have an EJB Project and a Web Project
- Create a live connection to your DB2 Membership database
Importing the membership application into Rational Application Developer
- Start RAD 7.5.5 using a workspace location of your choice. Start > IBM Software Delivery Platform > IBM Rational Application Developer 7.5.
- When prompted to enter a workspace location, you can select the default location provided or enter another convenient location.
- If the Welcome window appears, go ahead and close it.
- Import the initial EAR project that you will build upon.
- From the menu bar select File > Import > Java EE > EAR File and then click Next.
- Click the Browse button and navigate to the location where you saved the file AcmeMembershipApplication.ear and select it for import.
- Click Finish. There is no need to proceed to the other pages in the Import wizard.
Upon successful import, you will have a project layout as shown in Figure 4. There will be three projects in all: an Enterprise Application project and a corresponding Web module project and EJB module project.
You will see a number of errors show up in the Problems view that you can safely ignore until you create your JPA entities.
Figure 4. Acme's enterprise application projects
The EJB project has a stateless session EJB that you will use to invoke your JPA entities to create new members and memberships.
The web project has a simple single servlet that you can easily run in your WebSphere Test Environment to invoke your business logic.
Setting up the data connection
To make Rational Application Developer aware of the existing MEMBERS database residing on your local DB2 Server you need to establish a data connection to it with Rational Application Developer.
- Switch from the Java EE Perspective to the Data Perspective. Select Window > Open Perspective > Other > Data
- In the Data Source Explorer view under the Database Connections folder, you should see the MEMBERS database listed there. right-click and select Properties.
- In the Properties window, select the Driver Properties tab and, in that screen, enter the DB2 account user name and password. For convenience, make sure to check the Save password check box.
- Try testing the connection by clicking the Test Connection button. Click OK after you see a message that says Ping succeeded!
- Once again select the MEMBERS database under the Database Connections folder, right-click, and select Connect.
Generating the JPA entities
In this section, you will generate the JPA entities from the MEMBERS database tables that form the heart of the business logic for Acme's membership system.
First, create a JPA project to host your JPA entity beans:
- Switch to the JPA perspective. Select File > New > JPA Project to bring up the New JPA Project wizard.
- For the Project name, enter
AcmeMembershipApplicationDomain, and then click Next.
- From the Connection drop-down menu, select the MEMBERS database connection.
- Select the Override default schema from connection check box and then select the appropriate DB2 schema for your database from the Schema drop-down menu.
- Click Finish.
Now that you have a JPA project created, you can generate your JPA entities:
- Right-click the new JPA project that you created, AcmeMembershipApplicationDomain, and select JPA Tools > Add JPA Manager Beans > Generate Entities.
- The first page of the Generate Entities wizard will prompt you to select the appropriate connection to the DB2 database and the schema. Based on how you created your JPA project, the defaults should list the correct database and schema. If not, select the appropriate DB2 connection and database schema for your database instance and then click the Next button.
- For the Package field, enter
- Check the Synchronize Classes in persistence.xml check box.
- Click the Select All button to select all of the tables listed on this page in the wizard.
- Click Finish.
Although it is not obvious, the entries listed in the Entity Name column (circled in Figure 5) are editable. That is, you can change the default class names of the JPA entitles provided. In Figure 5 demonstrates this for two of the entities by renaming Contactinfo to
ContactInfo and Primarymember to
Figure 5.The relational database tables from which to generate JPA entities
Feel free to browse the generated JPA entities in the AcmeMembershipApplicationDomain project.
Tooling in Rational Application Developer 7.5.5 to generate JPA entity beans relies heavily on the JPA specification for mapping the database table column field type to a suitable type for the corresponding attribute in the JPA entity.
Now that you have JPA entities, you can correct most the errors in your workspace, all originating from the EJB project that refers to your JPA entities.
- Right-click the AcmeMembershipApplicationEJB project from the Project Explorer view, and select Properties.
- Check the box next to the AcmeMembershipApplicationDomain project, as shown in Figure 6, and then click the OK button.
Figure 6. Setting the Java EE module dependencies for the project
Adjusting the JPA entities
The JPA entities generated are only a starting point. They require adjustment and enhancement before elaborating on them with further business logic. Adjustments are required to exploit language conveniences available and to ensure that the entities reflect the business and application domain more accurately.
You will make these adjustments you will make to your generated JPA entities:
- To specify further that the unique key attribute (marked with @Id annotation) will rely on your database to generate its value.
- To leverage the java.util.GregorianCalendar Java type to capture and manipulate dates over the java.sql.Timestamp Java type, which was the default type chosen when the JPA entities were created.
- To override the database interpretation of the relationship of some of your entities to be One-to-One rather than Many-to-One. This will not affect the referential integrity or primary-foreign key relationships between the tables in the membership database. The reason for doing this is to use application logic to better reflect your business rules and constraints that exist between the entities (that represent abstractions of your real-world objects and the relationships between them).
Specifying automatic ID generation for JPA entities
You will adjust your JPA entities to have the ID attributes specified as ones that will have unique values generated for them by your database, using the Identity Generation scheme.
- Open the PrimaryMember class.
- Switch to the JPA perspective and, in the JPA Structure view (usually found on the top-right of the JPA perspective), select the id attribute (see Figure 7). Alternatively, you can select the id attribute in the Java editor.
Figure 7. The JPA entity attributes for the PrimaryMember class
- In the JPA Details editor (normally found on the bottom-right of the JPA perspective), check the Primary Key Generation box and select Identity from the Strategy menu, as shown in Figure 8.
Figure 8.Specifying use of the Identity primary key generation strategy
As Figure 9 shows, notice that your ID attribute now has an additional annotation associated with it because of your previous steps.
Figure 9.Additional annotations for the ID attribute, indicating the Primary Key Generation strategy
- Repeat Steps 1–3 for the other JPA entities in this project (Address, ContactInfo, Dependent, and Membership).
Changing the default types for attributes
The data types that the JPA Specification and the tooling in Rational Application Developer map from DB2 to for the attributes in the JPA classes under most situations work well. From a language and business logic perspective, there may be situations where other Java types might be more convenient to use.
A good example is the java.sql.Timestamp type, which the JPA tooling uses by default for the DB2 TIMESTAMP column type. Java developers and architects have the choice of using that default choice or using other compatible types.
The developers and architects of Acme's membership administration system have chosen to use java.util.GregorianCalendar rather than the default java.sql.Timestamp. Using java.util.GregorianCalendar offers several methods and operations that the developers found convenient for their application.
- Open the PrimaryMember class.
- In the Java editor, refactor the birthdate attribute to make the type java.util.GregorianCalendar instead of java.sql.Timestamp. For this step, you must update two things:
- The classes imported
- The get and set methods (getbirthdate, setbirthdate) to use java.util.gregoriancalendar
- From the JPA perspective, in the JPA Structure view (usually on the top-right of the JPA perspective), select the birthdate attribute.
- In the JPA Details editor (normally on the bottom-right of the JPA perspective), from the Temporal drop-down menu, select Timestamp, as Figure 10 shows.
Figure 10. Setting the temporal attribute to map as a Timestamp column
As Figure 11 shows, the birthdate attribute now has an additional annotation associated with it because of your previous steps.
Figure 11.Annotation for a Timestamp relational database column
- Repeat Steps 1–3 for the birthdate attribute for the Dependent JPA entity, as well as for the lastrenewaldate and membersince attributes for the Membership JPA entity.
The Rational Application Developer tooling for JPA provides powerful views and editors that reduce the need and knowledge necessary to code the annotations in your entities as required by the EJB and JPA specifications.
Adjust Acme's JPA entities to one-to-one, unidirectional relationships
Assume that, to reflect the constraints of the business rules for Acme's membership administration, you would like to make a few adjustments to your JPA entities:
- Tighten the cardinality (from many-to-one to one-to-one) for some of the relationships
- Reduce the navigation flexibility for some of the relationships (from bidirectional to unidirectional)
Both of these changes will make the application more secure and less prone to breaking any of the business rules for Acme's membership application.
Changing the cardinality of the relationship
- Open the JPA PrimaryMember entity.
- In the Java editor, select the address attribute.
- In the JPA Details view, select the many to one hyperlink, as shown in Figure 12.
Figure 12.Changing the cardinality of the relationship
- In the Mapping Type Selection dialog window, select One to One, as shown in Figure 13, and click OK.
Figure 13.The Mapping Type Selection dialog view
- In the JPA Details view, uncheck the Optional check box and check the All check box for the Cascade options, as shown in Figure 12.
In Figure 14, notice that the annotation describing the cardinality of the relationship is now One-to-One.
Figure 14. Annotation indicating a one-to-one cardinality relationship
- Repeat Steps 1 through 5 for these attributes:
- contactInfo attribute in the PrimaryMember JPA entity
- primarymember attribute in the Membership JPA entity
Step 5 is not related to the overall activity of changing the nature of the relationship of your JPA entities. However, it is a necessary step for making a complex object persistent (for example, an object composed of collections and an aggregation of other complex objects).
- For the Membership JPA entity, select the dependentCollection attribute and, in the JPA Details view, select All for the Cascade options.
Changing the relationship navigation options
Acme's membership administration application does not require that Address objects have access to the containing PrimaryMember object. To provide for this enhanced protective constraint:
- Open the Address entity and remove the primaryMemberCollection attribute.
- Remove the corresponding get and set methods for the primaryMemberCollection.
- To constrain other relationships for similar reasons, repeat Steps 1 and 2 for the primarymemberCollection in the ContactInfo entity and for the memberCollection attribute in the PrimaryMember entity.
Finally, after these changes, you should see warnings in your Problems views that you can eliminate by removing any unused imports. (Tip: The Quick Fix function in comes in handy to do this easily in one step.)
Running the Acme membership application
You will now deploy the Acme membership application to the Rational Application Developer WebSphere Test Environment. You will use a servlet to run the Acme membership function to create a new family membership.
- Ensure that you are still in the JPA perspective, and then select the AcmeMembershipApplicationDomain project from the Project Explorer view.
- Right-click and select JPA Tools > Configure Project for JDBC Deployment.
- In the "Set up connections for deployment" dialog window, ensure that the data connection you created earlier is selected in the Connection drop-down menu.
- Also ensure that other check boxes and values match those shown in Figure 15.
- Then click OK.
Figure 15.The "Set up connections for deployment" dialog view
- Switch from the JPA perspective back to the Java EE perspective.
- In the Enterprise Explorer view, expand AcmeMembershipApplicationWeb > Servlets.
- Right-click CreateMembershipServlet and select Run As > Run on Server.
- If the Run On Server dialog wizard appears, check the Always use this server when running this project check box (Figure 16) before clicking Finish.
Figure 16.The Run on Server dialog
- After the WebSphere Test Environment server has started, it will invoke your servlet and open a web page, indicating success in creating a new membership. You will be asked to look at your database tables to see the values in the various tables to confirm the creation.
For this article, we used the Rational Application Developer tooling to rapidly generate and customize JPA entities from a DB2 database that had these characteristics:
- Tables that use the DB2 Identity Value Generation capability to create unique primary keys values
- A nontrivial set of relationships between the tables
By using the Rational Application Developer environment, you increased your productivity by using views and editors that helped you tailor your JPA entities, thus freeing you from hand-coding the required annotations.
Finally, you ran your application by using the WebSphere Application Server conveniently embedded within the Rational Application Developer WebSphere Test Environment.
The author thanks Mike Reid for his thoughtful and thorough review of this article.
|Resources for this article||resources568.zip||15KB|
- Read these articles for more helpful information:
- John O'Connor's blog entry about Retrieving Date Elements (Java.net, 2007)
- Introduction to Spring 2 and JPA: Explore the Spring 2 framework and the Java Persistence API with Eclipse and DB2 Express-C by Sing Li (IBM developerWorks, 2006)
- Dynamic, typesafe queries in JPA 2.0 by Pinaki Poddar (IBM developerWorks, 2009)
- Developing Web applications with the Java Persistence API and JavaServer Faces: How Rational Application Developer Version 7.5 makes it easier to build JPA Web applications by Thomas Mutcosch (developerWorks, 2008)
- Building Java EE applications with IBM Rational Application Developer Version 7.5 and WebSphere Application Server Version 7.0 by Neeraj Agrawal (developerWorks, 2008)
- Browse the Rational Application Developer for WebSphere Software page on developerWorks for links to technical articles and many related resources.
- Explore the Rational Application Developer for WebSphere Software Information Center.
- Learn about other applications in the IBM Rational Software Delivery Platform, including collaboration tools for parallel development and geographically dispersed teams, plus specialized software for architecture management, asset management, change and release management, integrated requirements management, process and portfolio management, and quality management.
- Find product manuals, installation guides, and other documentation in the IBM Rational Online Documentation Center.
- Explore Rational computer-based, Web-based, and instructor-led online courses. Hone your skills and learn more about Rational tools with these courses, which range from introductory to advanced. The courses on this catalog are available for purchase through computer-based training or Web-based training. Some of the "Getting Started" courses are available free of charge.
- Subscribe to the IBM developerWorks newsletter, a weekly update on the best of developerWorks tutorials, articles, downloads, community activities, webcasts and events.
Get products and technologies
- Download a free trial version of Rational Application Developer for WebSphere Software.
- Download free trial versions of other IBM Rational software.
- Download IBM product evaluation versions and get your hands on application development tools and middleware products from DB2®, Lotus®, Tivoli®, and WebSphere®.
- Join the Development Tools forum to ask questions and participate in discussions.
- Check out developerWorks blogs.
- Get involved in the My developerWorks community.