Skip to main content

skip to main content

developerWorks  >  Open source | Java technology  >

Secrets of lightweight development success, Part 6: Persistence strategies

Finding the right persistence tool for the job

developerWorks
Document options

Document options requiring JavaScript are not displayed


Rate this page

Help us improve this content


Level: Introductory

Bruce Tate (bruce.tate@j2life.com), President, RapidRed

06 Sep 2005

Persistence frameworks are an extremely important part of any Java™ technology application. The choices are daunting. So, too often, developers make the popular choice, whether it's Enterprise JavaBeans or Hibernate. Often, you don't need a full object relational mapping layer. Even if you do, other persistence solutions have much to offer. Hibernate is free and rich. Kodo JDO has excellent management and mapping support. iBATIS is a hybrid solution that maps objects to the result of SQL queries, rather than tables. Even JDO has its place. This article discusses each solution and gives you some ways to choose the best one.

Since my first daughter was born eight years ago, I haven't been able to ski as often. After being away from the sport for nearly four years, I tried the new parabolic skis. They're shorter, and they taper in on the inside, making them turn easier. The new experience was revolutionary.

Choosing the right tool

I've had similar experiences with a mountain bike with i-drive (which puts more energy into the pedal cranks instead of bouncing the shocks), a low-volume kayak (which lets me use the currents under the surface of the river), and frameworks. When my customers deal with persistence, finding the right framework for them can transform a struggling, frustrated team into a well-oiled machine. Still, you have to be careful. Changing frameworks can be expensive. Part 3 of this series showed how Spring can help streamline services like persistence. This article is about finding the right persistence framework. First, let me dispel a few myths.

Myth 1: Technology always matters most.

Persistence relationships are long-term, whether you're talking about an RDBMS or a persistence framework. You need to know that your chosen solution will hold market share over time. If it won't, you risk being forced to move off your given framework at a time not of your choosing.

Myth 2: Object Relational Mappers (ORMs) hide all database issues.

Persistence frameworks simplify some problems and introduce others. If you don't understand the layers underneath, find people who do, or don't use an object-relational framework.

Myth 3: JDBC is always faster than ORM.

True, a perfectly tuned specific Java implementation will always beat a generalized ORM, but you'd be hard-pressed to find a perfectly tuned JDBC application. Frameworks like JDO and Hibernate provide many ways to improve and tune performance.

Myth 4: ORM is always the right tool for the job.

You'll often find problems that require better access to SQL. You'll also find problems that are more batch-oriented than interactive, or that require direct access to database rows, rather than a full object model. These problems won't make full use of ORM. Worse, some solutions may get in the way.

Myth 5: Java's ORM solutions are the only good ways to handle persistence.

Other languages have equally compelling persistence strategies. Microsoft® strategies tend to embrace the relational database and work with row sets. You get applications with a tighter coupling to the relational schema, but you gain the ability to bind row sets to user interface controls and integrate them with caching strategies throughout your application, even out on the edge with your firewalls and caching proxies. Ruby has Rails, which has an active record framework that's much more dynamic and productive than the Java technology solutions for many types of problems.

Notice that these myths are all absolutes. Persistence frameworks have shades of gray. Let's look at the major solution categories.



Back to top


Homegrown JDBC frameworks

JDBC is the basic Java technology API that allows access to databases. It represents the lowest level of all persistence strategies. Homegrown frameworks come in all shapes and sizes, but most have similar characteristics.

Most JDBC solutions wrap all data access in data access objects, which wrap a relational table. From there, you can leave data in result sets or opt to map each row in a result set to an object. Java technology developers tend to map things onto light value objects. An offbeat alternative is Martin Fowler's Active Record design pattern: a design pattern that provides a wrapper around one row in a database table. Each active record has methods to access each column, as well as methods to save, delete, or update the row.

Strengths

JDBC-based solutions offer good control. You'll write more code to solve expected problems, but you have full access to the database, and you can make it do just about whatever you want. Pure JDBC gives you excellent flexibility.

Weaknesses

Relational databases and objects aren't the same -- there's a gap. You have to work to handle object-oriented concepts like inheritance. You must also manage every object yourself, writing queries to do each create, read, update, or delete. If you need to add performance enhancements, you need to supply your own cache.

Bottom line

JDBC is a good choice for Java programmers of less than normal skill with good knowledge of SQL. JDBC also works well if you need better access to SQL or you're doing batch computing or reporting.

Variations

Several frameworks and tools can help you extend JDBC. Some, like Velocity and MiddleGen, generate data access objects, given a description of the database tables. Spring provides dependency injection and aspect-oriented programming to make it easier to integrate services and dependencies. Overall, though, the structure of your application and your strategy will remain the same.



Back to top


Object Relational Mappers

OOP and relational databases are based on radically different foundations. It's often difficult to mix the two. If you have an existing relational schema or one that's likely to change frequently, an ORM framework may be what you need. Most ORMs seek to let you deal with an object transparently. You provide a POJO, and the framework attaches persistence after the fact by using code generation (EJB), byte code manipulation (JDO), or reflection (Hibernate). Each of these techniques has strengths and weaknesses, so most frameworks use more than one approach to get the job done.

You need to tell your application how to map your database tables to the classes in your application. You can do so with a separate XML file or with notes in your application code. These notes can take the form of Java 5 annotations or comments (using a tool like XDoclet). I generally keep code and configuration separate if my schema and object model don't evolve together.

The persistence framework lets you load a series of objects from the database. You can then present them, or manipulate them and save them back to the relational database. Most ORM frameworks provide extensions, such as two layers of caching. Generally, the first cache ensures transactional integrity, and the second ensures consistency across machines in the cluster. Implementations vary, though, so you should be careful to understand the caching strategy.

You need a strategy for managing your configuration and dependencies. Your application will probably need to choose a transaction strategy and use data sources and connection pools. Spring works well with ORM by handling these issues for you, as you learned in the previous article. These are some of the available ORM.

EJB

Enterprise JavaBeans provide standardized persistence in two families, for the EJB 1.x standard and the 2.x standard. The second standard is more capable, but still more complex than it had to be. The EJB expert group recognized this fact and will provide a third standard under the umbrella of the EJB 3 JSR; but the standard will be available to all Java Enterprise Edition (JEE) users, not just EJB users. The EJB persistence standard is, therefore, effectively a dead end because new applications will want to target solutions closer to the expected JSR 220 standard.

Hibernate

Hibernate is rapidly becoming the de facto standard for persistence. It's fast, efficient, and free. Because Hibernate lets you make an arbitrary POJO persistent, it must have a way to attach persistence to an object without forcing you to make code changes. Hibernate provides transparency primarily through reflection, but it mixes in some run-time byte-code manipulation through dynamic proxies. With reflection, Hibernate can look at the state of an object before and after a transaction. If the state has changed, Hibernate can then save it to the database. Proxies help Hibernate implement other features, like lazy loading. (Think of a dynamic proxy as an object that sits in front of a target, with an identical interface to the target. The proxy is free to call persistence layers whenever you call certain methods or touch instance variables.)

Hibernate supports only relational databases, and it's more tightly coupled to SQL than most other persistence frameworks. Hibernate uses a query language similar to SQL, and that similarity has served users well. If you need to, you can also use SQL directly with Hibernate.

Hibernate, like JDO, has a two-level cache. The first-level cache, called the session, gives you a holding area for persistent objects. You can load objects into the cache and manipulate them. You can then decide when to persist changes in the database by calling flush or commit on the session.

Hibernate helps you manage relationships. If you define a relationship, such as employees belonging to a department, Hibernate manages it. You can decide whether to load all the employees if you load a department (eager loading) or wait to load employees (lazy loading).

Strengths

Hibernate has flexible mapping. Some scenarios take more effort to map than others, but if you can represent it in a relational schema, there's probably a way to map to it in Hibernate. The performance of Hibernate is better than that of most frameworks and continually improving. The documentation is excellent, and support is improving with the JBoss acquisition. The JBoss group also places Hibernate in a good place to implement JSR 220 persistence before competitors.

Integration with other open source frameworks and commercial frameworks is better with Hibernate than with alternatives. In general, Spring's integration with Hibernate is better than its integration with any other persistence framework.

Hibernate is an innovative framework. It pushed integration with SQL farther than most other frameworks. It has features like session filters that other frameworks don't support. It also has a strong team of public and commercial developers working on it.

Weaknesses

If you're a large shop, then what you don't pay in license fees you're likely to make up for in support. Hibernate is also more difficult to manage than alternatives. You don't have the rich management consoles that, for example, SolarMetric's Kodo JDO product provides. You also don't have the rich user interface tools that, for example, Versant's JDP product provides.

Finally, Hibernate isn't as professional as some of the persistence frameworks. For example, Kodo JDO has far better error messages and more predictable behavior around some of the edge cases, like managing lazy loading.

JDO

If you want the Betamax of persistence frameworks, look no further than JDO 1.x -- although fortunes seem to be turning for JDO 2 and still more with JSR 220 persistence. For the past three years or so, the best technical persistence frameworks have come from the JDO community. JDO achieves transparency through byte code enhancement; JDO 2 will relax this constraint somewhat.

JDO provides a query language called JDO QL. It has formalized performance extensions for caching and fetch groups that define lazy/eager fetch scenarios you can define on a per-query basis. JDO also provides a model for detached processing, so you can detach an object from a JDO session (called a PersistenceManager), change it, and reattach it. The database can then apply all changes to the database.

JDO also provides transparent persistence on arbitrary data stores. Most of the data in the world isn't relational, and JDO alone is well positioned to provide solutions for this community.

Strengths

JDO has a variety of vendors with varying strengths. The Kodo product sells into niche markets calling for extreme persistence scenarios. Kodo is fast, and it's broadly recognized as having the best mapping support of any JDO product. (I'd go one step further and say that its mapping support is the best in the industry, period.) Kodo also leads the field in manageability. (The Versant product also has excellent speed.) By far its biggest advantage is its user interface for mapping support.

Weaknesses

Any treatment of JDO weaknesses must begin with market share. JDO should get better protection by being a standard, but so far, the standard hasn't been very successful. Ironically, JDO will probably get a shot in the arm because of the JSR 220 persistence standard. Many JDO vendors work on that standards body, and most JDO vendors have announced support for the standard within their products. You'll see a stronger standard, and the better JDO vendors will be able to participate in those markets. The JSR 220 standard will open the door; and where the new standard comes up short, you'll see customers use the same products to try JDO. With weak market presence, JDO needs better presence in the open source community. Versant's donation of its product to the Eclipse group is a step in the right direction.

Others

Top Link, OJB, and Cayenne are chasing Hibernate, but they aren't likely to catch it (for a variety of reasons). In the months to come, I'll explore a few frameworks in other languages like Ruby or Python.



Back to top


Hybrid approaches

This article wouldn't be complete without introducing a hybrid approach. Whereas most ORM solutions map a class to a relational database schema, hybrid frameworks like iBATIS map classes to the result of an SQL query.

With iBATIS, you provide an XML file that specifies queries and mappings from those queries to objects. You get some of the benefits of ORM, like a consistent caching strategy, separated SQL from your code base, and limited relationship management.

Strengths

iBATIS also provides benefits you don't get from other ORM frameworks. You get tighter control of SQL, you don't have to worry about the object/relational mismatch as much, and you don't have to invest months to learn an object/relational framework.

Weaknesses

iBATIS doesn't give you everything ORM does. You need to code queries to do each database access, rather than doing them yourself. You couple yourself more tightly to the database. You're also dependent on the SQL dialect you choose. These aren't direct limitations of iBATIS; they're inherent in the nature of this type of solution.



Back to top


Conclusion

You don't have to automatically reach for EJB or Hibernate the next time you're doing an enterprise solution that requires persistence. You have a number of approaches. If there's any question, try the solutions that you like with something nontrivial. If you still aren't sure, get help.



Resources

Learn

Get products and technologies
  • Innovate your next open source development project with IBM trial software, available for download or on DVD.


Discuss


About the author

Bruce Tate

Bruce Tate is a father, mountain biker, and kayaker in Austin, Texas. He's the author of three best-selling Java books, including the Jolt winner Better, Faster, Lighter Java. He recently released Spring: A Developer's Notebook. He spent 13 years at IBM and is now the founder of the J2Life, LLC, consultancy, where he specializes in lightweight development strategies and architectures based on Java technology and Ruby.




Rate this page


Please take a moment to complete this form to help us better serve you.



 


 


Not
useful
Extremely
useful
 


Share this....

digg Digg this story del.icio.us del.icio.us Slashdot Slashdot it!



Back to top