Create applications using ObjectDb and JPA in NetBeans

February 19, 2011

Hibernate, JPA

«»

Step 4: Code the main Method

After adding the controls we can run the program to see whether we have arranged the swing components properly.

Open the Main.java in the main package. There is a public static void main method and inside that we have to call the JFrame frmCity to be displayed. The following code has to be added.

1
2
3
4
5
6
7
8
package main;
import gui.frmCity;
public class Main {
	public static void main(String[] args) {
		frmCity city = new frmCity();
		city.setVisible(true);
	}
}

Line 3 imports the frmCity file as it is inside a different package then the Main.java file.

Line 8 create a new object from the frmCity class and in the next line the form is displayed.

Then press F6, or select Run and Run Project (City) from the menu. It can also be done by clicking the Play button in the Run toolbar.

If the form we designed is not displayed, check whether the Project is the main project. You can right click on the City Project and select Set as the Main Project.

If still the form is not displayed, open the Project Properties and look under Run and check Main.main is
selected as the Main Class.

Step 5: Code user-defined methods

Now we have to add functionality to this project. Although ideally the functionality has to be added as separate manager classes, for the sake of simplicity, all the coding necessary are done within the frmCity itself.

The important functionalities displayed are connecting to a JPA database and then saving, retrieving, updating and removing objects of entity classes.

The existing cities are listed in the lstCity. When it is clicked, the details of the selected city are displayed on the right side. If we want to edit details, we have to click btnEdit. If we want to add a new city, have to click the btnAdd. After clicking btnAdd or btnEdit, can enter name of the city to txtCity and select the country from cmbCountry.
Until we click btnSave or btnCancel, we cannot access lstCity, btnAdd or btnEdit. If btnSave is clicked, the details are saved, and program is again set to the select mode.

If we enter a name of a country to txtCountry and click the btnAddNewCountry, the new country will be saved and appear in the cmbCountry.


btnClose

will close the application when clicked.

There functionalities are coded in to several reusable methods.

Before proceeding, we have to add the following imports. They can be
added later while typing the code which needs the relevant import, but in that
case we have to be very careful to select the appropriate one out of the list.

The Imports are as follows.

1
2
3
4
5
6
7
8
9
10
import bean.City;
	import bean.Country;
	import java.util.List;
	import javax.persistence.EntityManager;
	import javax.persistence.EntityManagerFactory;
	import javax.persistence.Persistence;
	import javax.persistence.TypedQuery;
	import javax.swing.DefaultComboBoxModel;
	import javax.swing.DefaultListModel;
	import javax.swing.JOptionPane;

The JPA database connection is represented by the EntityManager interface. style=’mso-spacerun:yes’> There has to be a database to get a connection. Like vice, we need an instance of EntityManagerFactory to get an instance of EntityManager. EntityManagerFactory represents the database. When we need any modification to the database, we need an EntityTransaction instance.

One EntityManagerFactory can have any number of EntityManagers, that is, there is one-to-many relationship. One EntityManager can have only one EntityTransaction and that is a one to one relationship.

As the program works with a single database, one EntityManagerFactory instance is all that necessary for the whole program. It will efficiently manage all the connections represented by several EntityManager Instances.

Inside the frmCity we need to retrieve saved objects, save new ones, update old ones and delete existing ones. As all these actions have to be inter-related, we have to manage them all through a single EntityManager. If we retrieve objects from one instance of EntityManager and modify them and then save them using another instance of EntityManager, the
objects will not get updated and instead new set of fresh objects will be saved with the modified attributes without modifying the previously retrieved object.

As there is only one EntityManagerFactory for the whole program, it should have an application vide scope. EntityManager should have access by all the methods in the class. In this tutorial, we define both EntityManager and EntityManagerFactory as class level variables.

To start with, we can define an EntityManagerFactory and assign a null value. Then define an EntityManager and assign it also with a null value.

Immediately below the first line of the class, we can define these as below.

1
2
EntityManager em = null;
EntityManagerFactory emf = null;

If you have not already done the importing, the EntityManager and the EntityManagerFactory will be underlined in red. At the start of the line, a light bulb (“Fixable Hint”) appears and if we take the mouse over that, it says as “Cannot find symbol”. If we click on the hint, select “Add Import for Javax.persistence.EntityManager”.

When the program starts we have to check whether there is an existing EntityManagerFactory instance, and if not, we can create one instance. Then we check whether the instance of an EntityManager, and if not available, we create new one
from the EntityManagerFactory.

Java persistence requires a name of a Persistence unit as a parameter when an EntityManagerFactory is created. But if we are developing an Embedded ObjectDB application, we can simple use a relative or absolute path of a database with *.odb extension instead of a name of a Persistence Unit. This is coded under a method called “connectDatabase”.

1
2
3
4
5
6
7
8
private void connectDatabase(){
	if (emf == null) {
		emf = Persistence.createEntityManagerFactory("city.odb");
	}
	if (em == null) {
		em = emf.createEntityManager();
	}
}

If there is an already existing valid
style=’font-family:”Verdana”,”sans-serif”;mso-fareast-font-family:”Times New Roman”; mso-bidi-font-family:”Times New Roman”‘>ObjectDB
file in the location, the program will use it. style=’mso-spacerun:yes’> If no such database is available, one will be created at the location. When simply the name of the database is given, the database is created in the NetBeans project folder. style=’mso-tab-count:1′> As we are using an Embedded database, one connection at a time is allowed. If we want to
use multiple simultaneous connections over TCP/IP connection, we can easily define a Persistence Unit and add that functionality as described in another tutorial.

All the countries have to be listed in the cmbCountry. When the form is first displayed and when a new country is added, this JCombo has to be refilled. Filling this JCombo with the countries is done in a method called fillCountries. This code will fill the JCombo with objects retrieved from JPA. Make sure you add the correct imports at the beginning, namely javax.persistence.Query
and javax.swing.DefaultComboBoxModel.

The items already added to the JCombo can be cleared with cmbCountry.removeAllItems() method.

We first create an instance of TypedQuery from the EntityManager. style=’mso-spacerun:yes’> When creating an instance of a query, we can give one of several parameters including a String type JPAQuery which is used in this example. JPA query is very similar to SQL, but is more flexible.The query, “SELECT cu FROM Country cu ORDER BY cu.name”, can retrieve all the Country type objects from the database ordered by the name attribute. The results can be assigned to a List( java.util.List), which in turn converted to an array of Country type objects. A new instance of a DefaultComboBoxModel is created with these objects and it is assigned as the model of the JComboBox.This will fill the cmbCountry with all the saved country objects.

1
2
3
4
5
6
7
8
9
10
11
12
private void fillCountries() {
	cmbCountry.removeAllItems();
	try {
		TypedQuery query = em.createQuery("SELECT cu FROM Country cu ORDER BY cu.name", Country.class);
		List countryList = query.getResultList();
		Object[] countries = countryList.toArray();
		DefaultComboBoxModel dcm = new DefaultComboBoxModel(countries);
		cmbCountry.setModel(dcm);
	} catch (Exception e) {
		JOptionPane.showMessageDialog(rootPane, e);
	}
}

All the cities are listed in lstCity and it is done inside a method called fillCities. As described previously, JPA Query will retrieve all the city type objects. We can directly pass these objects to the JList using lstCity.setListData(cities)
method.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private void fillCities() {
	DefaultListModel dlm = new DefaultListModel();
	dlm.removeAllElements();
	lstCity.setModel(dlm);
	try {
		TypedQuery query = em.createQuery("SELECT ci FROM City ci ORDER BY ci.name" , City.class);
		List cityList = query.getResultList();
		Object[] cities = cityList.toArray();
		lstCity.setListData(cities);
	} catch (Exception e) {
		JOptionPane.showMessageDialog(rootPane, e);
	}
 
}

When a city is selected from the lstCity, the details of the selected city are displayed on the right side and the method to call is listed below. Cities are stored in the JList and we select the user selection and display the details. We could have retrieved the object directly from the database, but it is not necessary in this example.

1
2
3
4
5
6
7
private void displayCityDetails() {
	City city = (City) lstCity.getSelectedValue();
	if (city != null) {
		txtCity.setText(city.getName());
		cmbCountry.setSelectedItem(city.getCountry());
	}
}

When a city is deselected, the details of the previously selected city have to be cleared from the right side and the method to call is listed below.

1
2
3
4
private void clearCityDetails() {
	txtCity.setText(null);
	cmbCountry.setSelectedItem(null);
}

When the window is first displayed, we can select any city, but we must not be able to edit it or add a new one until we purposely click the “Edit” button or “Add” button respectively. The controls are prepared to such an editable stated from the following method.

1
2
3
4
5
6
7
8
9
10
11
12
13
private void setToEdit() {
	btnAdd.setEnabled(false);
	btnEdit.setEnabled(false);
	btnDelete.setEnabled(false);
 
	lstCity.setEnabled(true);
 
	btnSave.setEnabled(true);
	btnCancel.setEnabled(true);
 
	txtCity.setEditable(true);
	cmbCountry.setEnabled(true);
}

After editing or adding a new city, we can save the changes by clicking “Save” button or ignore the changes by clicking “Cancel” button. After that the window goes to a state where we can select a city, but cannot edit it. That is achieved by the following set of codes.

1
2
3
4
5
6
7
8
9
10
11
12
13
private void setToSelect() {
	btnAdd.setEnabled(true);
	btnEdit.setEnabled(true);
	btnDelete.setEnabled(true);
 
	lstCity.setEnabled(true);
 
	btnSave.setEnabled(false);
	btnCancel.setEnabled(false);
 
	txtCity.setEditable(false);
	cmbCountry.setEnabled(false);
}
email

«»

Comments

comments

,