Java Data & Java User Code: EJB with Composite Primary Key in ODBMS

User Code: EJB with Composite Primary Key in ODBMS

As you know, Enterprise Java Beans (EJB) technology provides a format for
highly specialized business logic components, wherein the EJB is just a collection
of java classes and XML files, bundled into a single unit. The Java classes must follow
certain rules and provide certain callback methods. Of the various types of the
EJB, the most commonly used one is the Entity Bean, which always represents the shared,
transactional data in your application. The persistence of an Entity Bean can be
managed by the Bean Programmer (BMP) or by the container itself (CMP). As I
mentioned above, certain Java classes are to be implemented along with the
certain rules for the Entity Bean for any CMP or BMP. One of these is the
Primary Key class. I am going to talk about this class.

Why Primary Key Class

Every Entity Bean has a primary key that represents a unique identity and
must be represented by a class known as primary key class. This class must contain
the information necessary to find that entity in the persistent store. It is
used internally by the EJB container or client to find a particular instance of
the entity. Hence, this class must follow certain rules.

  1. It must have a unique value within the set of all beans of a particular
    type.
  2. It must provide suitable implementation of hashCode() and
    equals() methods.
  3. It must be serializable.

It is possible to implement the above condition as long as there is a unique
primary key available in the database table, but it becomes difficult in a
situation where there is no single primary key available. Hence,
one has to go for the Composite Primary Key.

What Is the Composite Primary Key?

Answer: What you use when there is no unique field
available in the database to represent the
primary key. For example, suppose we have a dabase with the fields named
date, productname, openingstock, production, despatch, and closingstock. In this
case, neither date nor productname can become a primary key to handle the entity,
so in this situation a composite primary key concept has to be used to identify
the bean’s uniqueness. In this case, both fields — date and productname — are both
used to form a composite primary key. I have used a GregorianCalendar object to
represent Date (it can be taken up any userdefine object) and VARCHAR data type
to represent productname (pname) in my sample database. In this situation, the
primary key class would look like the following:


import java.util.*;
import java.io.Serializable;

/**
 * Primary Key class for Product */
public class ProductCPK implements java.io.Serializable {
  public java.util.GregorianCalendar idate;
  public String iproductname;

  public ProductCPK(java.util.GregorianCalendar pdate,String productname) {
	this.idate = pdate;
	this.iproductname=productname;
  }

  public ProductCPK() {
  }

  public String toString() {
	return idate.toString();
  }
  public String getProductname()
  {
  	return iproductname;
  }
  
  public java.util.GregorianCalendar getPdate()
  {
  	return idate;
  }

  public int hashCode() {
  	return (idate+iproductname).hashCode();
  }
  
  public boolean equals(Object product) {
  	 if((product == null) || (product instanceof ProductCPK))
	 	return false;
	ProductCPK cpk= (ProductCPK) product;
	
  	return ((idate.equals(cpk.idate)) && (iproductname.equals(cpk.iproductname)));
  }  

}

You can see that all the required conditions outlined earlier have been
incorporated in forming the class.

Now, we need to implement a finder method in the EJB. This finder
method is as follow (see the comments):


	public ProductCPK ejbFindByPrimaryKey(ProductCPK key) throws FinderException {
		PreparedStatement psmt = null;
		Connection conn = null;
		try {
			System.out.println("ejbFindByPrimaryKey(" + key + ") called");

			/*
			 * Acquire DB connection
			 */
			conn = getConnection();

			/*
			 * Find the Entity in the DB
			 */
			psmt = conn.prepareStatement("select cdate from productA where cdate = ?");
			psmt.setObject(1, key.idate);  // Object Data type
			psmt.setString(2,key.iproductname);
			ResultSet rs = psmt.executeQuery();
			if (!rs.next())
			{
			throw new ObjectNotFoundException();
			}
			rs.close();

			/*
			 * No errors occurred, so return the Primary Key
			 */
			return key;
		}
		catch (Exception e) {
			throw new FinderException(e.toString());
		}
		finally {
			/*
			 * Release DB Connection for other beans
			 */
			try { if (psmt != null) psmt.close(); }
			catch (Exception e) {}
			try { if (conn != null) conn.close(); }
			catch (Exception e) {}
		}
	}

That’s all! I’ve given you the total source code implementing the composite
primary key, along with with the object in the database.
The demo project zip file below contains a prepared .jar file that can be used with
WebLogic server 6.0 sp1 along with a trial Client class.

The source code was tested with WebLogic 6.0 sp1 on a Windows 2000 server.

Downloads

Environment: J2EE 1.2 or J2EE-compliant server, JDK 1.3, Cloudscape (or any other
supporting object database).

This article was contributed by
Yashodhar Desai.

Latest Posts

Related Stories