Download (direct link):
¦¦ The solution assumes that a clerk will be only be logged in to the system at one location. If, in the scenario, Todd is the manager and logs in to all of the client workstations at the beginning of the day, this could increase the possibility of name collisions.
¦¦ This solution assumes that all client workstations have a way to synchronize date and time. A company policy must be written to specify how time synchronization must work on each store basis. Even if the Web container in this solution generated the system date and time, it is possible that many Web containers at remote locations may be communicating with the EJB tier, and time there must be synchronized.
¦¦ The solution assumes that each branch of the video store has a unique name. This requires the assignment of unique store names at a central location, and when new stores are added and removed, just the control of unique store names causes much management overhead.
¦¦ The format of the primary key identifier is dependent on the database schema, making one more constraint between the client/Web tier and the EJB tier.
362 Item 42
This scenario should demonstrate that allowing the client application to choose the primary key from a certain "recipe" can cause an administrative nightmare. For one, it puts more of a burden on the logic of the client and end users. Second, the burden for creating and enforcing policy that fits into the primary "recipe" will put a huge burden on the manager of the system. Finally, each J2EE system may have a large number of entity beans, and even if you have a great recipe for generating primary keys for one entity bean, you will probably run out of ideas. This is something that may work great for username account generation on a Web site, but you will eventually find that you will need a solution on the server side.
ASSESSMENT: This approach can become unmanageable and burdensome, and it is not recommended.
The Singleton Approach
After the software designers for the video store applications decided that the "Client Control" solution was too unmanageable, they decided that the use of the Singleton design pattern (discussed in Item 15) could be helpful. They decided to create a Singleton that implements a counter, so that it would be the central place to generate primary keys. The team made a simple Singleton called UIDSingleton, with a synchronized getNextKey() method to generate the key, shown in Figure 42.3.
Satisfied that this would solve the EJB primary key problem, the solution was deployed. Unfortunately, what they didn't understand is that the use of "pure Singletons" in J2EE is not recommended. A Singleton ensures that there is one instance of a class per virtual machine. With most J2EE servers, there are multiple VMs involved. As a result, the result is primary key chaos, resulting in primary key collisions—and one very flawed system.
ASSESSMENT: Don't do it.
Figure 42.3 Attempting to use a Singleton for PK generation.
Generating Primary Keys for EJB 363
The Networked Singleton Approach
Convinced that they were on the right track with the Singleton approach, the team decides to ensure that there is one Singleton for the J2EE system by giving it a network identifier. In this approach, the software developers decided to create a Singleton that is callable via RMI and found by using JNDI. This Singleton implements a synchronized counter and ensures that there are no primary key collisions.
Satisfied that this solution was better than the earlier solution, the software team quickly implemented it. This was easy because each entity bean calls it via RMI and calls getNextKey(). In functionality testing, the system worked wonderfully. When it was load-tested with thousands of users, however, the system slowed to a crawl. What happened?
The solution here—and the problem—revolves around the nature of a Singleton. Because a unique network identifier ensures that there is a single object that generates primary keys, this is also a single point of failure. Every entity bean in the system must make a JNDI lookup and then must call the Singleton over the network. While this may work in small-scale solutions, this approach will not scale.
ASSESSMENT: It works, but performance will not scale on large projects.
An Application Server-Specific Approach
At this point, the developers writing the video store application notice that their J2EE application server provides an easy solution to the entity bean/primary key problem. It is a proprietary solution, but it seems to work great. The team develops the entire application, and it works beautifully. However, when it is mandated that they need to change application servers, the team is in trouble. Their entire video store application is now tied to their app server vendor, and it will take a long time to rewrite everything.
In many cases, application servers provide a simple solution to create primary keys for your entity beans. A danger here is nonportability. When you tie your solution to a particular application server with features like these, your solution will undoubtedly work great. Unfortunately, porting your J2EE application to other application servers will be a real headache. Keep in mind that when you go down this route, you may be stuck with the app server you use.