Thursday, February 23, 2006

More EJB 3.0

For the past few days I have been working on a number of things. I shall blog about them in more detail when I have some time, but in the meantime, here is a summary:

1. Packaging issues. EJB 3.0 brings hassle-free packaging, however, it is still not easy to understand what the rules are. A discussion on packaging issues can be found here and here.

2. Semantics of merge() and persist() and how they are implemented in Glassfish is being discussed here.

3. Does EJB live up to its promise to bring POJO style programming to J2EE? I previously blogged about the fact that EJB 3.0 Entities are not really POJOs because they contain hidden semantics. See here for a discussion of dependency injection of EJBs and whether it is possible to implement Business Logic as POJOs.

Monday, February 20, 2006

Tuple Manager implementation is feature complete

Recently completed the implementation of Tuple Scans. Unlike Index Scans which use next key locking to avoid phantom reads, the Tuple Scan implementation does not protect the gap between one tuple and the next. This means that Tuple Scans cannot provide strictly Serializable behaviour. I wonder if this will be an issue later on.

Wednesday, February 15, 2006

Sharing attributes across Entities

One way to share common attributes across entities is to use inheritance, and put the common attributes in a super class. Another way is to abstract the common attributes into a separate Embeddable class and then embed it within the regular Entity classes. The latter approach has been used for some of the entities in the EJB3Demo project.

The entities Customer, District and Warehouse all contain some very similar columns for storing address information. I created a new class called Address to hold this common data. The Address class is marked as @Embeddable and contains the getters/setters for the attributes. Here is an extract:
@Embeddable public class Address implements Serializable {
String street1;
String city;
@Column(length=20)
public String getCity() {
return city;
}
@Column(length=20)
public String getStreet1() {
return street1;
}
}
Note that the getters have been annotated using @Column - this is useful for capturing the bits that are shared across the entities.

When you embed the Address object within an Entity, you can fine-tune the column mapping. Example:
@Entity
public class Customer {
Address address;
@Embedded
@AttributeOverrides({
@AttributeOverride(name="street1", column=@Column(name="C_STREET_1")),
@AttributeOverride(name="city", column=@Column(name="C_CITY")),
})
public Address getAddress() {
return address;
}
}
The getter for the Address object is decorated with the @Embedded annotation. The address object can be shared amongst multiple entities, and each entity can define its own column names, etc.

When you access embedded objects in EJBQL, you use the property name in the Query statement. For example, to access the city field in Customer, you would write:
SELECT c.address.city FROM Customer c
This syntax is also used when you have relationship mappings. For example, a District belongs to a Warehouse, and hence the District object contains an instance of the Warehouse object. To access the fields within Warehouse, you would write:
SELECT d.warehouse.name FROM District d
Although one could use inheritance to model above, I prefer to use the Embeddable class option as it more accurately reflects what is happening here. A Customer is not an instance of Address - a Customer has an Address. In this situation, Has-A relationship is more natural than Is-A relationship.

EJB3Demo project

I have started a new project at www.java.net. The goal of this project is to try out various features of Java EE 50, such as EJB 3.0, JAX-WS, JAXB, etc., and identify design/code patterns that result in:
  1. Improved portability and reusability of code, in particular, allow Business Logic and Data Access logic to be deployed inside and outside J2EE containers.
  2. Better separation of concerns while exploiting new persistence features of EJB 3.0.

I hope to blog about some of this stuff soon - stay tuned. In the meantime, I would welcome anyone who would like to contribute to the project.

The source code for the project is available for download from https://ejb3demo.dev.java.net/servlets/ProjectDocumentList.

Monday, February 06, 2006

Reusability of Code

I have given up trying to get the TPCC schema work as defined, i.e., using composite keys. Glassfish at present does not support Id Generators with composite keys, which poses a problem, as it means writing extra code for generating keys. As a workaround to this issue, I have modified the schema to use surrogate primary keys.

EJB persistence design favours Entity Relationships based upon surrogate primary keys.

One of the great benefits of EJB 3.0 is that it gets rid of all the boiler plate EJB code, allowing you to code Entity and Session beans as if they were POJOs. This raises the expectation that in this new world, it should be possible to write reusable code that is environment agnostic. By this I mean that I should be able to reuse my J2EE Business Logic classes and the Persistent classes in a J2SE or Servlet Container (Tomcat) environment without having to change any code.

There is an immediate stumbling block to achieving this, however. The unfortunate decision to introduce a new abstraction for Transaction Management for J2SE environment means that tranaction management code is not portable. The first rule for writing reusable code therefore is to avoid transaction management code in your classes. I will report on other pitfalls as I progress with my attempts to create reusable code.