7.4 Evaluating Hibernate
We've covered some of the Hibernate basics. To
recap, it's a persistence framework that allows
transparent persistence from Java beans to relational databases over
JDBC. So how does Hibernate stack up against our five principles?
7.4.1 Keep It Simple
It's easy to build simple
if you're solving simple problems. Complicated
problems like persistence demand more thought and effort. If you want
to understand how complex persistence frameworks can be, check out
EJB entity beans. Compare that model with Hibernate.
Hibernate's model code is fully transparent (except
for the need to provide a default, parameter-less constructor).
Configuration is a breeze. The mappings are simple when
you're solving simple problems.It's not just the Hibernate framework that benefits
from a simpler mindset; Hibernate applications also reap the
benefits. It's also easy to get started.
I've learned that most students of my classes are
able to get going in an hour or so, which is about how long it takes
to get your first JDBC application off of the ground. After using
Hibernate for some commercial applications, I've
learned that they are easy to write and easy for my customers to
understand. But simplicity does not mean Hibernate is too basic to
solve difficult problems.
7.4.2 Do One Thing, and Do It Well
When you attack a
problem, it's tempting to just solve some smaller
problems around the perimeter of your domain. With persistence
frameworks, many designers try to build in transaction management,
security, distribution, or other aspects. It's far
better to layer your code, focusing each loosely coupled layer on
just one aspect of the problem.It's tough to solve every aspect of a problem domain
like persistence. In order to focus on a difficult problem, you have
to make simplifying assumptions. Hibernate creators wisely made some
basic assumptions that let them simplify their implementation:Hibernate uses only JDBC. Some persistence frameworks support many
types of data stores. By supporting only relational databases,
Hibernate developers did not need to deal with nonrelational
problems, thus simplifying their query language and focusing on JDBC.While some persistence frameworks support all types of Java classes,
Hibernate supports only Java beans. The developers were therefore
able to make use of the existing reflection API. To be fair, for many
problems, reflection may be too simple. Hibernate has added CGLib in
order to do byte code enhancement to support lazy loading, which may
be a better overall technique for transparency, in this case.Hibernate punts on some of the peripheral problems, using other
frameworks instead. Apache Commons handles logging, JTA provides a
more robust transaction API, and JNDI provides a naming interface to
help locate services.
By leaving these details to others, Hibernate creators were able to
focus on building a fast, light persistence framework. Instead of
wringing their hands over the performance of reflection, they wisely
worked on creating efficient SQL first. That could only be done
through loose coupling at the right places. As
you'll see in
the Hibernate extensions are
loosely coupled and pluggable in the right places.
7.4.3 Strive for Transparency
For the most part, the Java community
had to wait a long time for transparent persistence. For a while,
most of our attention was diverted as we tried to make the EJB
experiment work. For persistence frameworks, transparency affects
productivity more than any other feature. If you
haven't used transparent persistence before, one
look at our application will show you why you should.
You're simply free to deal with the business domain
independently of any other application concerns. This ability lets
you break your programming down into manageable pieces with clearly
defined roles. It also makes your domain easier to write and
7.4.4 Allow for Extension
Too often, simple solutions are dead
They cannot be extended in the appropriate places. When you build
simple software, it's got to be able to grow. The
only constant in software development is change. You must anticipate
the places your users will need to extend your frameworks and
applications. The most successful open source projects are those that
allow for extension. Apache allowed plug-ins to process many
different types of web content. Ant allowed developers to plug in
custom tasks, so they could use Ant for highly customized builds.
Eclipse is an application development environment
that's gathering momentum because of the vast array
of compatible extensions. Hibernate also allows for smart extension
in a number of important places:
Hibernate users can switch
between databases by simply configuring a
different dialect. Users of a given dialect can choose to use
proprietary extensions for added performance, or instead use a more
generic dialect. The interface to create a dialect is open, so you
can create new dialects as you need them in order to support the
databases you need for a project.
The JDBC connection
Much of the OOP community frowns
on the use of stored procedures but in the
real world, they are a fact of life. Hibernate users can access the
JDBC connection directly in order to use features that are not
supported by Hibernate, such as stored procedures. By providing
direct access to the level of abstraction immediately below, the
architects allowed extension to areas completely outside of their
Configurable transaction API
JDBC developers often like to
their own transactions, but many advanced J2EE developers need more.
Hibernate conveniently passes transaction responsibility through to
the database for simple applications with explicit transaction
support, and also lets the user configure the more advanced
transactions through JTA.
I'd like to point out that standards play a role
here, too. While you don't need to support every
open standard, you can get significant leverage from standards in
likely areas of extension. For example, the Hibernate inventors
understood that JTA makes sense for transactions that may have a
scope beyond the basic persistence framework. On the other hand, it
clearly did not make sense to support earlier releases of JDO, since
that specification forced byte code enhancement and had an awkward
query language that might complicate and possibly confuse the API.
7.4.5 You Are What You Eat
Hibernate does a good job of integrating core standards where they
exist, but it rarely forces you to use a complex standard. Instead,
it provides an inexpensive default implementation. A good example is
the JTA integration. You're free to configure JTA if
you need it, but you're not bound to that approach.
Where JTA is overkill, you can easily delegate transaction management
to the database without changing anything but configuration.Hibernate also supports many lightweight solutions
for logging and collections (Apache
Commons), database access (JDBC), and enterprise containers (Spring).
You can deploy with richer J2EE architectures, but Hibernate works
perfectly well with Tomcat and MySQL.
184.108.40.206 Going against the grain
At some point, many of the more revolutionary successful frameworks
reject conventional wisdom. For Hibernate, three crucial decisions
played a significant role in its success:Reflection is too slow
In fact, reflection is much slower than a direct method invocation.
For a persistence framework, it's a price
you're willing to pay because database access is
inherently so expensive.
A query language must be fully object-oriented
Instead of starting with the premise that a query language for an
object-oriented framework must return pure objects, the Hibernate
query language started with SQL. To use a query language as close to
SQL as possible, it needed to support scalars and aggregates.
A persistence model must provide a shared, common object model
Instead of letting each application have a private cache with a
private object model in each session, EJB applications share one
major object model across all applications. This approach is a
shared, common object model. EJB vendors theorize that such a design
leads to better performance. In practice, a smaller, lighter
persistence framework can share a common cache; even with a little
extra object creation and destruction, it blows the doors off of EJB
7.4.6 The Down Side
Of course, no framework is perfect. Hibernate is young
largely unproven. Very few people provide the vision for the
framework, and that's a dangerous, perhaps limiting
model for growth.As I write this book, the Hibernate team has fairly limited
resources. That might be a good thing: such a situation works against
unnecessary bloat. It also may hinder the team's
ability to improve the framework in meaningful ways. As the project
grows, additional programmers will naturally contribute.
That's a double-edged sword; many open source
projects do not manage growth well. Additionally, Hibernate has been
subsumed into the JBoss suite of applications. The JBoss relationship
will probably make better-paid support available, making it more
attractive for some commercial applications.Other commercial frameworks, such as Solarmetric's
Kodo JDO, produce cleaner and faster SQL, if some of my DBA contacts
are to be believed. It makes sense, because that product has been out
longer and has a larger team of full-time programmers to help.Earlier editions of Hibernate had aggressive marketing language
criticizing JDO's use of byte code enhancement.
Ironically, byte code enhancement may turn out to be a better method
than reflection for implementing persistence. Hibernate had early
success with reflection only to hit a wall when adding performance
enhancements like lazy loading. The proven byte code enhancement
techniques common in the JDO marketplace may yet provide a faster,
more flexible means of achieving transparent persistence.
Hibernate's inclusion of CGLib is an early
indication of the limitations of reflection; CGLib provides more
flexible lazy loading through, you guessed it, byte code enhancement.
In addition, although byte code enhancement has taken some hits in
recent years, it's the technology that powers many
of the aspect-oriented frameworks.
Hibernate is not the only framework that supports
persistence. For many projects, it's not even the
best way. If you're willing to pay for a persistence
framework and you like open standards but abhor EJB, explore JDO. A
number of good implementations exist. My favorite is Kodo JDO. It
probably generates the cleanest, prettiest SQL. Even a DBA that I
know was impressed. It's a framework that uses byte
code enhancement to achieve better transparency, supporting more Java
constructs than most other products.Velocity is not a persistence framework, but you can use this code
generator to generate data access objects and transparent models.
Sometimes, persistence frameworks are simply overkill. Template-based
technologies often give you better access to SQL than other
alternatives.OJB is another open source framework, under the umbrella of Apache.
It's got a number of usage models, including ODMG,
EJB, and JDO. I know many developers who use it and like it, although
I haven't had much experience with it. If
you're a pure Oracle shop, you may consider TopLink.
It was once the top object-relational mapping tool. Interest has
waned since the Oracle acquisition.