I'm interested in getting some feedback on a design decision I have to make relating to a J2EE application I'm putting together. The application is currently being implemented using CMP entity beans to provide access to data held in a database. The CMP approach works well for our application on the target application server (Orion), so no problems there. However we have a design decision to make regarding access to data outside of the tables managed by CMP. A simple example explaining the design decision follows…
We have three entity beans representing the entities Company, Department, and finally Employee, with a hierarchical relationship between them. These entities pass Sun's suggested guidelines for being implemented as individual EJBs rather than dependent objects within a single entity. As the use of CMP suggests, these entities map directly onto single database tables.
The question arises where we need to generate attributes that are not explicitly held in one of these database tables, for example the number of employees assigned to a particular department (e.g. select count (*) from employee where department = ?). It seems logical to us that the number of employees assigned to a department is an attribute of a department, and so we would like to be able to call a method on a department entity to retrieve this value.
It strikes us that the best way to achieve this is to augment the existing CMP implementation of these entities to add additional methods that generate these values dynamically. These additional methods simply retrieve the current data source through a JNDI lookup, and perform the relevant SQL operation via JDBC. (An example snippet of code is appended to this post showing what I mean)
This is an attractive solution as we can continue to use CMP entity beans, and provide a "clean" interface to the rest of the application, which encapsulates all of the attributes "owned" by each entity. It avoids having to create stateless session beans to provide a home for "utility" functions that would otherwise be required to generate this data, and much better than having to generate these values by using finder methods to trawl through the employee rows.
If anyone has any feedback on this approach, positive or negative, I'd be keen to hear it.
// Simple CMP entity example
// CMP managed field
public String name;
// get and set methods for CMP managed fields
public String getName ()
// methods to retrieve data outside of CMP
public int getNumberOfEmployees ()
// JNDI DataSource lookup
// Perform select count (*) from employee where department = ?
// Fetch result
// Release JNDI and JDBC resources
It reminds me "Dual Entity Beans" pattern posted at that site.
Thanks Alex! I obviously didn't look hard enough before posting. The pattern is in the catalog under the title "Map Logical Entities to more than one EnterpriseBean". (At least I assume that's the pattern in question).
I'd still be interested in any further comments on the original post.
In my opinion, depending on the O/R mapping engine, CMP works only for simple cases where there is simple one to one mapping between the entity bean and database. In all other cases, I prefer BMP along with SQL and JDBC.
For most entity beans, I have designed and developed, CMP has not worked well. Because my entity beans represent coarse grained business objects mapping to multiple database
tables, where the mapping between bean attributes and database columns is not necessarily one to one.
When you have your BMP entity beans spanning more than one table and not having a 1:1 correlation between attributs and columns - do you get any use of the containers functionality such as a second user can share your bean instance and avoiding database access or do all users get there own EB ? If they do could SB with JDBC be an alternative ?
I believe the question here is NOT "is my O/R mapping ok?", but "is it correct to add extra behavior to my entity beans beyond simple get/set of attributes and relationships"
I say YES!
As much as possible, in the true OO sense I try and put behaviors where they belong. The J2EE world seems to have forgotten this, and all of the designs I have seen end up putting behavior into helper/utility classes, with entity beans being just dumb data wrappers.
I can't comment on the issue of opening a connection, running a query, etc. within a CMP bean method, but I would guess it would work.