The Java Persistence API (JPA) is a new programming model under EJB3.0 specification (JSR220) for the management of persistence and object/relational mapping with Java EE and Java SE. With JPA, developers can easily develop java applications that perform operations on relational database management systems using java objects and mapping. In that way, java applications developed using JPA are not only portable across different platforms, but also applications can be easily developed using simple yet powerful programming model provided by JPA. This greatly improves application maintainability against ever changing database world. JPA insulates applications from all the complexity and non-portable boilerplate code involved in database connectivity and operations.
Apache geronimo Geronimo uses Apache OpenJPA for providing Java Persistence API implementation to Java EE applications deployed in the server. Even though JPA is a part of EJB3 .0 spec, it is independent of it. Hence, JPA can be used in JavaSE, web and ejb applications in the same uniform way. Think of a JPA implementation, e.g. Apache OpenJPA as a driver for JPA (JPA driver) similarly to what a JDBC driver is for JDBC.
The below section illustrates developing and deploying a JEE application client that uses JPA to access and manipulate database data residing in an embedded derby database.
...
- Setting up Eclipse for Application development
- Developing Entities and Client
- Preparing Deployment Descriptors and Deployment Plans
- Deploying the application client
- Running the application client
To download the complete application, click on link
Setting Eclipse for Application development
1. Start the Eclipse IDE and create a Java project by name ApplicationClientJPA
as follows ApplicationClientJPA
java project.
Right click on the Project Explorer Window and click on New = > Java Project.
Provide ApplicationClientJPA
as the name for the Java Project.
Click on Next and Finish.
Right click on the Project and click on the Properties option which is the last option in the menu.
...
Click on Add External JARs button and browse for geronimo-jpa_3.0_spec-1.1.1.jar
file in the geronimo
server repository. This file will be available at{{<geronimo_home>/repository/which should be in <geronimo_home>/repository/org/apache/geronimo/specs/
}}geronimo-jpa_3.0_spec/1.1.1
folder. The JPA annotations used in Account.java
and some of the JPA
classes used in AccountClient.java
requires this library at compile time. Click jar file is only to compile entity and entity client classes you're about to create. Geronimo provides the jar at runtime.
Select the file and click on the Open button.
This will add the library to the build path. Click on OK.
...
2. Create META-INF
folder in the project. Right click on the project and click on New = > Folder
Provide META-INF
for the folder name and click on Finish.
...
1.Right click on the project and create a Account
java class by name Account.java
as follows.as follows.
Provide name for the class as Account.java
and with a package name as sample.jpa.appclient
and click . Click on
Finish.
2. Copy the below contents to the Account.java
.
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
package sample.jpa.appclient; import java.io.Serializable; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="Account1") public class Account implements Serializable{ private static final long serialVersionUID = 1L; @Id public int accountNo; public String name; public String address; public int branchCode; public double balance; public Account(){ this.accountNo = 0; this.name = "DUMMY"; this.address = "DUMMY"; this.branchCode = 0; } public int getAccountNo() { return accountNo; } public void setAccountNo(int accountNo) { this.accountNo = accountNo; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public int getBranchCode() { return branchCode; } public void setBranchCode(int branchCode) { this.branchCode = branchCode; } public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; } } |
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
package sample.jpa.appclient; import java.util.ArrayList; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import javax.persistence.PersistenceContextQuery; import javax.persistence.QueryEntityTransaction; public class AccountClient { //@PersistenceContext(unitName="JPA-App-Client") private EntityManager em; public AccountClient() { EntityManagerFactory emf = EntityManagerFactory emf = Persistence.createEntityManagerFactory("JPA-App-Client"); if (emf == null) { throw new System.out.printlnIllegalStateException("emfEntityManagerFactory is null!!!unavailable"); } em = emf.createEntityManager(); if (em == null) { System.out.println("em throw new IllegalStateException("EntityManager is null!!!unavailable"); } } public static void main(String[] args) { AccountClient client = new AccountClient(); String opt = args[0]; if (opt"create".equals("create"opt)) { if (args.length != 6) { System.outerr.println("EnterNo values for accountNo, name, address, branchCode and balance;. Exiting."); System.exit(0); } else else{ int accNo = Integer.parseInt(args[1]); String name = String name = args[2]; String address = args[3]; int branchCode = Integer.parseInt(args[4]); double balance = Double.parseDouble(args[5]); client.createAccount(accNo, name, address, branchCode, balance); } } else if (opt"list".equals("list"opt)) { ListList<Account> accListaccounts = client.listAccounts(); for(int i = 0; i <for accList.size(); i++)(Account account: accounts) { System.out.println("_________________________________"); Account acc = (Account)accList.get(i); System.out.println(accaccount.getAccountNo()); System.out.println(accaccount.getName()); System.out.println(accaccount.getAddress()); System.out.println(accaccount.getBranchCode()); System.out.println(accaccount.getBalance()); System.out.println("____________________________________________"); System.out.println(""); } } else if (opt"update".equals("update"opt)) { if ( if (args.length != 3) { System.out.println("EnterNo values for accountNo and new balace value. ;Exiting."); System.exit(0); } else{ } else { int accNo = Integer.parseInt(args[1]); double newbalance double newbalance = Double.parseDouble(args[2]); client.updateAccountBalance(accNo, newbalance); } } else if (opt.equals("delete")) { if (args.length != 2) { System.out. System.out.println("EnterNo values for accountNo for delete. Exiting."); System.exit(0); } else { int accNo = Integer.parseInt(args[1]); client.deleteAccount(accNo); } else { System.out.println("Unknown option selected...!!"); } } public Account createAccount } (int accNo, String name,else { String address, int branchCode, double balance){ Account acc1 = emSystem.err.find(Account.class, accNo); if(acc1 != null) throw new println("Unknown option (" + opt + ") selected"); IllegalArgumentException ("Account already exists: Account Number ("+accNo+")"); } } Account acc =public newAccount AccountcreateAccount(); int acc.setAccountNo(accNo); acc.setAddress(address); acc.setBalance(balance); acc.setBranchCode(branchCode); acc.setName(nameaccNo, String name, String address, int branchCode, double balance) { Account acc1 = em.find(Account.class, accNo); System.out.println("Persisting account entity (accNo = "+accNo+")"); em.persist(acc); System.out.println("Persisted successfully account entity (accNo = "+accNo+ if (acc1 != null) { throw new IllegalArgumentException("Account already exists - account Number (" + accNo + ")"); return acc; } public List listAccounts(){ if(em == null) System.out.println("em is null!!!" Account acc = new Account(); Query q = em.createQuery("SELECT a FROM Account a" acc.setAccountNo(accNo); List currList = qacc.getResultListsetAddress(address); return currList; } public Account updateAccountBalance acc.setBalance(balance); (int accNo, double newBalance){ Account acc = em.find(Account.class, accNo); if(acc == null) throw new IllegalArgumentException ("Account not found : Account Number ("+accNo+acc.setBranchCode(branchCode); acc.setName(name); System.out.println("Persisting account entity (accNo = " + accNo + ")"); acc.setBalance(newBalance); em.merge(acc EntityTransaction et = em.getTransaction(); return acc; } public void deleteAccount(int accNo){et.begin(); Account acc = em.find(Account.class, accNopersist(acc); if(acc == null) throw new IllegalArgumentException ("Account not found : Account Number ("+accNo+ et.commit(); System.out.println("Persisted successfully account entity (accNo = " + accNo + ")"); em.remove(acc) return acc; } } |
Preparing Deployment Descriptors and Deployment Plans
1. Create persistence.xml
file in the META-INF
folder as follows.
Right click on the META-INF
folder and click on New => File.
Provide persistence.xml
as the file name and click on Finish.
Copy the below contents to the persistence.xml
.
...
<?xml version="1.0" encoding="UTF-8"?>
<persistence
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="1.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="JPA-App-Client">
<description>JPA Application Client</description>
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<class>sample.jpa.appclient.Account</class>
<properties>
<property name="openjpa.ConnectionURL" value="jdbc:derby://localhost/AccountDB" />
<property name="openjpa.ConnectionDriverName" value="org.apache.derby.jdbc.ClientDriver" />
<property name="ConnectionUserName" value="app" />
<property name="openjpa.jdbc.SynchronizeMappings" value="false" />
</properties>
</persistence-unit>
</persistence>
@SuppressWarnings("unchecked")
public List<Account> listAccounts() {
Query q = em.createQuery("SELECT a FROM Account a");
List<Account> currList = q.getResultList();
return currList;
}
public Account updateAccountBalance(int accNo, double newBalance) {
Account acc = em.find(Account.class, accNo);
if (acc == null) {
throw new IllegalArgumentException("Account not found : Account Number (" + accNo + ")");
}
EntityTransaction et = em.getTransaction();
et.begin();
acc.setBalance(newBalance);
et.commit();
return acc;
}
public void deleteAccount(int accNo) {
EntityTransaction et = em.getTransaction();
et.begin();
em.remove(em.getReference(Account.class, accNo));
et.commit();
}
}
|
Note |
---|
The |
Preparing Deployment Descriptors and Deployment Plans
1. Create persistence.xml
file in the META-INF
folder as follows.
Right click on the META-INF
folder and click on New => File.
Provide persistence.xml
as the file name and click on Finish.
Copy the below contents to the persistence.xml
.
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0" >
<persistence-unit name="JPA-App-Client">
<description>JPA Application Client</description>
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<class>sample.jpa.appclient.Account</class>
<properties>
<property name="openjpa.ConnectionURL" value="jdbc:derby://localhost/AccountDB" />
<property name="openjpa.ConnectionDriverName" value="org.apache.derby.jdbc.ClientDriver" />
<property name="ConnectionUserName" value="app" />
<property name="openjpa.jdbc.SynchronizeMappings" value="false" />
</properties>
</persistence-unit>
</persistence>
|
2. Similarly, create application-client.xml
file in the META-INF
folder as given the previous step and copy the below contents into the file.
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
<?xml version="1.0" encoding="UTF-8"?>
<application-client xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application-client_5.xsd"
version="5">
</application-client>
|
Since we are using JPA annotations to declare the resources, we do not require any entries in the file.
3. Similarly, create geronimo-application-client.xml
file under META-INF
file and copy the below contents2. Similarly, create application-client.xml
file in the META-INF
folder as given the previous step and copy the below contents into the file.
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
<?xml version="1.0" encoding="UTF-8"?> <application-client xmlns="http://javageronimo.sunapache.comorg/xml/ns/javaee/j2ee/application-client-2.0" xmlns:xsisys="http://wwwgeronimo.w3apache.org/xml/2001ns/XMLSchemadeployment-instance1.2" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee xmlns:naming="http://javageronimo.sunapache.comorg/xml/ns/javaee/application-client_5.xsd" version="5"> </application-client> |
Since we are using JPA annotations to declare the resources, we do not require any entries in the file.
3. Similarly, create geronimo-application-client.xml
file under META-INF
file and copy the below contents.
Code Block | |
---|---|
XML | XML |
borderStyle | solid |
title | geronimo-application-client.xml | <?xml version="1.0" encoding="UTF-8"?> <application-client xmlns="http://geronimo.apache.org/xml/ns/j2ee/application-client-2.0" xmlns:sys="http://geronimo.apache.org/xml/ns/deployment-1.2" xmlns:naming="http://geronimo.apache.org/xml/ns/naming-1.2" xmlns:security="http://geronimo.apache.org/xml/ns/security-2.0" xmlns:connector="http://geronimo.apache.org/xml/ns/j2ee/connector-1.2"> <sys:client-environment> naming-1.2" xmlns:security="http://geronimo.apache.org/xml/ns/security-2.0" xmlns:connector="http://geronimo.apache.org/xml/ns/j2ee/connector-1.2"> <sys:client-environment> <sys:moduleId> <sys:groupId>AccountJPA</sys:groupId> <sys:artifactId>AccountJPA-app-client</sys:artifactId> <sys:version>3.0</sys:version> <sys:type>jar</sys:type> </sys:moduleId> <sys:dependencies> <sys:dependency> <sys:groupId>org.apache.geronimo.configs</sys:groupId> <sys:artifactId>transaction</sys:artifactId> <sys:version>2.1</sys:version> <sys:type>car</sys:type> </sys:dependency> </sys:dependencies> </sys:client-environment> <sys:server-environment> <sys:moduleId> <sys:groupId>AccountJPA</sys:groupId> <sys:artifactId>AccountJPA-app-client<client-server</sys:artifactId> <sys:version>3.0</sys:version> <sys:type>jar</sys:type> </sys:moduleId> <sys:dependencies> <sys:dependency> <sys:groupId>org.apache.geronimo.configs</sys:groupId> <sys:artifactId>transaction</sys:artifactId> <sys:version>2.1</sys:version> <sys:type>car</sys:type> </sys:dependency> </sys:dependencies> </sys:client-environment> <sys:server-environment> <sys:moduleId> <sys:groupId>AccountJPA</sys:groupId> <sys:artifactId>AccountJPA-app-client-server</sys:artifactId> <sys:version>3.0</sys:version> <sys:type>jar</sys:type> </sys:moduleId> </sys:server-environment> </application-client> |
Deploying the application client
</sys:server-environment>
</application-client>
|
Deploying the application client
1. Export the Java Project to a jar file Start the geronimo server and open the admin console http://localhost:8080/console
.
Click on Embedded DB => DB Manager on the Console Navigation portlet. This will open up DB Viewer and Run SQL portlets on the right hand side as follows.
Enter AccountDB in the Create DB text box and click on Create button. This will create a new Database AccountDB and will be listed in the DB Viewer portlet.
In the textarea SQL Command/s: which is on the Run SQL portlet, enter the below SQL command, and select AccountDB in the Use DB combo box, and click on Run SQL button. This creates the Account1 table in the AccountDB database.
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
create table ACCOUNT1 (ACCOUNTNO integer, NAME varchar(50), ADDRESS varchar(225), BRANCHCODE integer, BALANCE decimal(15,2));
|
Insert some sample rows in the table using the below SQL statements by following the same outlined procedure above.
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
insert into Account1 values (1111, 'Joe', 'NewYork', 10, 30000.0);
insert into Account1 values (2222, 'John', 'NewJersy', 11, 31000.0);
insert into Account1 values (3333, 'Jane', 'Raleigh', 13, 32000.0);
|
2. Export the Java project 1. Export the Java Project to a jar file by name ApplicationClientJPA.jar
as follows.
Right click on the java project and export it as jar file.
...
In the next screen click Next. In the Jar Manifest Specification wizard, select sample.jpa.appclient.AccountClient
using Browse button. This is the class that has public static void main(String[] args)
method which is the application entry point.
Click Finish.
32. Deploy the application client as follows.
Change the directory to <geronimo_home>\bin
.
Submit the below command
deploy
exported_jar_file> No Format bgColor #000000 borderStyle solid
<geronimo_home>/bin>deploy.bat --user system --password manager deploy <location_of_the_
ApplicationClientJPA.jar>/ApplicationClientJPA.jar
Running the application client
1. Run the application client as follows.. Run the application client as follows.
The application performs the following operations. Use the script client
(.bat or .sh) to run the application clientThe application performs the following operations.
- List : This option lists the accounts curently in the database. The command to list is as follows.
No Format bgColor #000000 borderStyle solid <geronimo_home>/bin>java -Djava.endorsed.dirs="<geronimo_home>/lib/endorsed" -jar <geronimo_home>/bin/client.jar bin>client AccountJPA/AccountJPA-app-client/3.0/jar list
- Create : This option creates an account in the database. The command to create is as follows.
No Format bgColor #000000 borderStyle solid <geronimo_home>/bin>java -Djava.endorsed.dirs="<geronimo_home>/lib/endorsed" -jar <geronimo_home>/bin/client.jarbin>client AccountJPA/AccountJPA-app-client/3.0/jar create 2222 Joe NewYork BranchX 20000.0
- Update : This option updates an account with a new balance in the database.
The command to update is as follows.
No Format bgColor #000000 borderStyle solid <geronimo_home>/bin>java -Djava.endorsed.dirs="<geronimo_home>/lib/endorsed" -jar <geronimo_home>/bin/client.jar bin>client AccountJPA/AccountJPA-app-client/3.0/jar update 2222 30000.00
- Delete : This option deletes an account in the database. The command to delete is as follows.
No Format bgColor #000000 borderStyle solid <geronimo_home>/bin>java -Djava.endorsed.dirs="<geronimo_home>/lib/endorsed" -jar <geronimo_home>/bin/client.jar bin>client AccountJPA/AccountJPA-app-client/3.0/jar delete 2222.