Developing JPA 2.1 applications in WebSphere Developer Tools (WDT) for Liberty can greatly benefit from using the WebSphere Developer Tools (WDT) database connectivity tools with its JPA tooling. I’ll show some examples of configuring data sources for Liberty in a JPA application, taking advantage of the new schema generation feature in JPA 2.1 to create tables based on entities, and finally the auto-generation of JPA entities based on a database schema.

Getting started

For the purposes of this post, let’s use an embedded Derby database as an example and assume it’s in the C:databasesderbysample directory. And let’s also assume the database’s JDBC driver .jar file is located at C:jdbcderby.jar.

Firstly, a connection to the database needs to be created in WDT in the Data Source Explorer view:

  1. On the Database Connections node, click New or click File > New > Connection Profiles > Connection Profile.
  2. Choose Derby as the database type, and name your connection.
  3. On the Specify a Driver and Connection Details page, specify C:databasesderbysample as the database location.
  4. On the Drivers drop-down list, ensure Derby Embedded JDBC Driver is selected and click the triangle icon to the right of it to edit and specify the location of the JDBC derby.jar driver.


dbconnection

After the connection is created you can associate it with your application project (that has the JPA facet enabled) by going to the JPA section in the project’s properties and choosing the connection. Once this is done, WDT will now perform extra validation in your application against the database, such as for example ensuring that any table or column referred to in your JPA entity @Table or @Column annotations match what’s in the database, etc.

Configuring a data source

There are two types of data sources that can be used in JPA applications running on Liberty: JTA and Resource Local. A JTA type of data source is needed when using container-managed persistence. A Resource Local type data source is typically used when the application manages the persistence.

For our example, let’s first create a JTA data source:

  1. In the Liberty server configuration editor for server.xml, add a Shared Library for the Derby JDBC driver. You can browse to the base directory where the driver .jars are, and then choose the applicable jar files for the include pattern, which in this case is derby.jar


    ds_serverconfig_sharedlib

  2. Add a Data Source element to the server configuration node, with a JNDI name of your choice; for example jdbc/sampleDerbyDS. And then add a JDBC Driver child element to the Data Source node, choosing the shared library created above for the Shared library reference field. Add a second child element to specify the database properties, in this case Derby Embedded Properties where the physical location of the database C:databasesderbysample is specified.


    ds_serverconfig_jdbcdriver


    ds_serverconfig_derbyprops

  3. Finally, we need to create a reference to this new data source in the persistence.xml deployment descriptor. To do this, open the editor and switch to the Connection tab, and specify the JNDI name of the data source in the JTA data source field:


    ds_jta_persistencexml

The following XML is the equivalent of the XML that WDT configures in server.xml when you have finished the above steps:

<server description="new server">

    <!-- Enable features -->
    <featureManager>
    
        <feature>localConnector-1.0</feature>
        <feature>jsf-2.2</feature>
        <feature>jpa-2.1</feature>
    </featureManager>

    <!-- To access this server from a remote client add a host attribute to the following element, e.g. host="*" -->
    <httpEndpoint httpPort="9080" httpsPort="9443" id="defaultHttpEndpoint"/>


    <applicationMonitor updateTrigger="mbean"/>

	<dataSource jndiName="jdbc/sampleDerbyDS" id="SampleDerbyDS">
		<jdbcDriver libraryRef="DerbyLib"/>
		<properties.derby.embedded databaseName="c:/databases/derbysample" createDatabase="false"/>
	</dataSource>
	<library id="DerbyLib">
		<fileset dir="c:/jdbc" includes="derby.jar"/>
	</library>

</server>

For more information about configuring data sources in Liberty, refer to the IBM Knowledge Center

Now, let’s create a Resource Local data source:

  1. Open the persistence.xml editor and switch to the Connections tab.
  2. For Transaction type, choose Resource Local from the drop-down list.
  3. After naming the data source, click on Populate from Connection…
  4. WDT now examines the database connection associated to your JPA project and fills in the appropriate JDBC properties. It’s as easy as that!


    ds_resourcelocal_persistencexml

The updated persistence.xml looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.1"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> 
        <persistence-unit name="SamplePU" transaction-type="RESOURCE_LOCAL">
            <non-jta-data-source>localDS</non-jta-data-source>
            <class>com.test.SampleEntity</class>
            <exclude-unlisted-classes>true</exclude-unlisted-classes>
            <properties>
               <property name="javax.persistence.jdbc.url" value="jdbc:derby:c:databasesderbysample"/>
               <property name="javax.persistence.jdbc.user" value=""/>
               <property name="javax.persistence.jdbc.password" value=""/>
               <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver"/>
            </properties>
        </persistence-unit>
</persistence>

Using schema generation in JPA 2.1 to generate database tables from entities

JPA 2.1 introduces schema generation facilities which enable generating database tables, columns, and other schema in a standard and portable way. In addition to this, the latest specification also provides a way to load data into your database schema at startup.

With these new features, you can now create your schema and prepare the database with startup data for your application when the server starts. For prototyping and testing, this can be a valuable feature. Liberty and WDT now support this and all the other new features of JPA 2.1 based on the EclipseLink JPA implementation.

Let’s look at how we can configure schema generation for our example:

  1. In the persistence.xml editor, switch to the Schema Generation tab.
  2. To both delete and create the database tables on server startup, choose Drop and Create from the Database action drop-down list.
  3. Similar to the Database action, the Scripts generation field specifies the action for DDL scripts on server startup.
  4. The fields Metadata and script creation and Metadata and script dropping enable you to specify the order that, and what exactly happens when, the database and the DDL files are dropped or created. For example, choosing Metadata then Script means that the database will be modified first, and then the DDL script files generated.
  5. The Create database schemas check box enables you to enable or disable any schema creation actions that you have already set up.
  6. You can fill in the fields Scripts create target and Scripts drop target with the filenames of the DDL files in URI format.


    schemagen_persistencexml

The updated persistence.xml looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.1"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> 
        <persistence-unit name="SamplePU">
               <jta-data-source>jdbc/sampleDerbyDS</jta-data-source>
               <class>com.test.SampleEntity</class>
               <exclude-unlisted-classes>true</exclude-unlisted-classes>
               <properties>
           			<property name="javax.persistence.schema-generation.create-source" value="metadata-then-script"/>
           			<property name="javax.persistence.schema-generation.drop-source" value="metadata-then-script"/>
           			<property name="javax.persistence.schema-generation.scripts.create-target" value="file:///c:/temp/createSample.sql"/>
           			<property name="javax.persistence.schema-generation.scripts.drop-target" value="file:///c:/temp/dropSample.sql"/>
           			<property name="javax.persistence.schema-generation.scripts.action" value="drop-and-create"/>
           			<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
           			<property name="javax.persistence.schema-generation.create-database-schemas" value="true"/>
               </properties>
        </persistence-unit>
</persistence>

With this configuration, when the Liberty server is started, it first drops the relevant tables for your entity beans from the database, then creates them afresh, then generates two DDL script files in C:tempcreateSample.sql and C:tempdropSample.sql. These two DDL script files contain the SQL statements to create and drop the tables.

Generating JPA entities from database tables

The previous section showed how to use WDT and Liberty to generate schema automatically based on JPA entities in an application. In this section, let’s do the reverse and generate JPA entities based on existing database schema. This is useful to get a head-start on developing your entities modeled on an existing database schema, which can then be modified and further customized by hand to suit your application needs.

WDT provides a convenient wizard that walks you through the process of choosing the tables from a schema and setting up further preferences for how exactly the generated entity beans will look.

Assuming our sample Derby database has three tables for a simple relational model of employees and departments, and a JPA enabled project that is already connected to this database, here are the steps to generate JPA entities for the schema:

  1. From the project’s context menu, click on JPA Tools > Generate Entities from Tables….
  2. On the first page of the wizard, select the tables you want to generate tables for. In this case, let’s choose all three:


    entitygen_wiz1

  3. On the second page, WDT discovers all the existing relationships between the tables you have chosen, and displays a graphical view of the entity relationships that is generated, so that you can further edit and customize them as necessary.


    entitygen_wiz2

  4. The third and fourth pages give you further customization options as to how the entity data will be accessed (as fields or properties), default mapping options, Java package options, and so on:


    entitygen_wiz3


    entitygen_wiz4

When the wizard finishes, it generates the entity Java code in your project’s source folder. For this example, here’s the generated entity bean for the Employee table:

package model;

import java.io.Serializable;
import javax.persistence.*;
import java.sql.Timestamp;


/**
 * The persistent class for the EMPLOYEE database table.
 * 
 */
@Entity
@NamedQuery(name="Employee.findAll", query="SELECT e FROM Employee e")
public class Employee implements Serializable {
	private static final long serialVersionUID = 1L;

	@EmbeddedId
	private EmployeePK id;

	private String firstname;

	private Timestamp hiredate;

	private String lastname;

	private float salary;

	//bi-directional many-to-one association to Address
	@ManyToOne
	private Address address;

	//bi-directional many-to-one association to Department
	@ManyToOne
	private Department department;

	public Employee() {
	}

	public EmployeePK getId() {
		return this.id;
	}

	public void setId(EmployeePK id) {
		this.id = id;
	}

	public String getFirstname() {
		return this.firstname;
	}

	public void setFirstname(String firstname) {
		this.firstname = firstname;
	}

	public Timestamp getHiredate() {
		return this.hiredate;
	}

	public void setHiredate(Timestamp hiredate) {
		this.hiredate = hiredate;
	}

	public String getLastname() {
		return this.lastname;
	}

	public void setLastname(String lastname) {
		this.lastname = lastname;
	}

	public float getSalary() {
		return this.salary;
	}

	public void setSalary(float salary) {
		this.salary = salary;
	}

	public Address getAddress() {
		return this.address;
	}

	public void setAddress(Address address) {
		this.address = address;
	}

	public Department getDepartment() {
		return this.department;
	}

	public void setDepartment(Department department) {
		this.department = department;
	}

}

And there you have it. You’ve now configured data sources for Liberty in a JPA application, you’ve created tables based on entities using the schema generation feature, and you’ve generated JPA entities from a database schema.

Join The Discussion

Your email address will not be published. Required fields are marked *