| By Charles Lee | Article Rating: |
|
| April 26, 2007 03:00 PM EDT | Reads: |
11,836 |
Migrating EJB 2.0 entity beans to Hibernate POJOs is pretty straightforward. Like many applications, all of the data for HQ is stored in the database, and we need to map from the underlying data store to an object-oriented view. In EJB 2.0, you would model that data with entity beans. An entity bean is created and found through the Home interface, and its fields are modified through its Local/Remote interface. These interface classes are automatically generated when we use XDoclet to annotate our entity bean implementations. We define the actual implementations in *EJBImpl classes. For example, for each getter/setter, we annotate the following:
/**
* @ejb:interface-method
* @ejb:persistent-field
* @ejb:transaction type="SUPPORTS"
*/
public abstract String getName();
/**
* @ejb:interface-method
* @ejb:transaction type="MANDATORY"
*/
public abstract void setName(String name);
For all getters, we mark the transaction type as SUPPORTS so that it won't necessarily require a transaction. For all setters, the transaction type is MANDATORY, since modifications should be involved in a transaction. The same class file defines the create and finder methods, as well. The create method is a function body appropriately annotated with @ejb:create-method; and the finders are in EJBQL and written in pure annotation in this class file. In EJB 2.0, the concept of Local/Remote interfaces was introduced. We decided to go with only local interfaces for the entity beans so that they would not be accessible remotely, and thus bypass the permission checking that we do when they are accessed or modified. When we compile our code, out of each EJBImpl class, we automatically generate these additional classes:
- LocalHome: The local home interface that contains the create and finder methods
- Local: The local interface that contains the getter/setter methods
- Util: The utility class that fetches the home interface with the appropriate JNDI name
The problem with entity beans has been termed the "N+1 database problem", and it's referring to the number of database calls to access entity beans. If a finder was invoked on the LocalHome interface, it will execute a query equivalent to the following:
select pk from table where column = value
PK is the primary key of the object, and most often it's the ID column. When you load each entity bean into memory by accessing its fields, the container will then issue another query:
select * from table where id = pk
If you do the math, for N rows found, you will end up issuing N + 1 queries to the database, henceforth the "N+1 database problem". Wait, there's more. We find that EJBs have a nasty habit of aggressively locking up database rows or tables no matter how much we tried to mark methods read-only, setting the container to lock optimistically, or even marking transaction type as NOTSUPPORTED. Maybe we didn't try hard enough, but we definitely pulled a fair amount of hair out over this. In fact, we found ourselves replacing getId() calls with getPrimaryKey().getId(), because while the ID has already been fetched into the primary key, the container would still do a database lookup when we ask for the ID. We needed to avoid the extra table lookups and reduce the duration of transactions to a minimum.
The Value Objects
XDoclet provides the facilities for implementing the Value Object pattern. The motivation for the pattern is to avoid calls through the entity bean's interface for each method call, which can be either local or remote. We took it a step further: we create a Value object (sometimes more than one so that we can have "light" objects that would incur the additional burden of loading up the relationships, etc.) for each entity bean and make sure to convert any lookups of entity beans to Value objects, and then cache the Value objects. Now, when the system is properly cached, we should be able to drop the "N" part of the "N+1" lookups. We augmented XDoclet a bit to account for this caching functionality. In our EJBImpl class, we also annotate the following for the generation of Value objects:
@ejb:value-object
name="Resource"
match="*"
instantiation="eager"
cacheable="true"
cacheDuration="300000"
XDoclet will not only generate the Value object class, it will also generate an extension to our EJBImpl class to get/set its Value objects. Now this is starting to look a bit untidy. Take ResourceEBJImpl.java, for example; when we compile it, we get the following classes from one single file:
- ResourceUtil
- ResourceLocalHome
- ResourceLocal
- ResourceEJBImpl
- ResourceValue
- ResourceCMP
Published April 26, 2007 Reads 11,836
Copyright © 2007 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Charles Lee
Charles Lee is co-founder and vice-president of engineering of Hyperic. Prior to co-founding Hyperic, Lee was a senior software engineer at Covalent. There, he built Covalent's configuration management product for Apache (CMP), and he spearheaded and architected the application management software (CAM). Before Covalent, Lee developed a document management system for retail store build-outs based on open-source technology at WiseConnect. Lee also held senior engineering position at Hewlett-Packard, where he was instrumental in developing print drivers for network LaserJets for the Asian market, as well as developing the UI framework used for LaserJets for all markets. Lee also developed the first GUI printer configuration framework for AutoCAD while a senior engineer at Autodesk. Lee was an early engineer at Backflip, where he created the document publishing system for the website based on mod_perl.
Lee received his BS in Computer Science and BA in Chemistry with honors from the University of Washington.
- Book Excerpt: Introducing HTML5
- It's the Java vs. C++ Shootout Revisited!
- Patterns for Building High Performance Applications
- OpenXava 4.3: Rapid Java Web Development
- Asynchronous Logging Using Spring
- Java for Programmers (2nd Edition)
- Cross-Platform Mobile Website Development – a Tool Comparison
- Write Once Run Anywhere or Cross Platform Mobile Development Tools
- Three Buzzwords That Every CIO Hears but One They Should Listen To
- Immersing into JavaScript Frameworks
- Workday Reportedly Prepping to Go Public
- Book Review: Sams Teach Yourself Java in 24 Hours
- Book Excerpt: Introducing HTML5
- Adobe Sends Flex to the Apache Foundation
- Five Years Waiting for JRE 7: Is It Justified? (Part 1)
- Book Excerpt: Java Application Profiling Tips and Tricks
- i-Technology in 2012: Five Industry Predictions
- It's the Java vs. C++ Shootout Revisited!
- Patterns for Building High Performance Applications
- OpenXava 4.3: Rapid Java Web Development
- The Next Web Architecture
- Asynchronous Logging Using Spring
- Java for Programmers (2nd Edition)
- Is Write Once Run Anywhere Ever Going to Be a Reality?
- A Cup of AJAX? Nay, Just Regular Java Please
- Java Developer's Journal Exclusive: 2006 "JDJ Editors' Choice" Awards
- JavaServer Faces (JSF) vs Struts
- The i-Technology Right Stuff
- Rich Internet Applications with Adobe Flex 2 and Java
- Java vs C++ "Shootout" Revisited
- Bean-Managed Persistence Using a Proxy List
- Reporting Made Easy with JasperReports and Hibernate
- Creating a Pet Store Application with JavaServer Faces, Spring, and Hibernate
- Why Do 'Cool Kids' Choose Ruby or PHP to Build Websites Instead of Java?
- What's New in Eclipse?
- i-Technology Predictions for 2007: Where's It All Headed?























