Section 20.2. Principles of Hibernate


20.2. Principles of Hibernate

Often, programmers tend to skip introductory material and move right to the code. Sometimes we skip the code examples too and just pull up a seat at the keyboard and start hacking. Tempting as it may be to do so, plowing ahead without understanding the principles that Hibernate was built on is a dangerous thing to do. While persistence frameworks are meant to make life easier, they can be your worst nightmare if you don't understand the principles that drive the framework.

20.2.1. Transparency

First and foremost, Hibernate strives to be a transparent service provider. When authoring an application, your customer derives value not from the choice of tools you use to create an implementation but from the domain model you create to solve his real-world problems. That domain model should be as testable, portable, and deployable as possible. Hibernate goes to great lengths to ensure that your application is as minimally dependent on it, its libraries, and its own dependencies as possible.

This means that the domain objects themselves are oblivious to the persistence mechanism you employ. They implement no interfaces, extend no base classes, refer to no APIs, nor even make any design concession to the Hibernate framework. The persistence logic and APIs are encapsulated away in the façade layer, allowing your domain objects to be truly domain-specific.

20.2.2. Reflection

Any ORM framework must provide a way to dynamically generate SQL CRUD (create, read, update, delete) statements to bridge the chasm between the running application and the persistence store. When things change in the domain, the framework has to know about them to persist them to the data store and vice versa. This means that the ORM framework has to have knowledge of the specifics of not only the class definitions but also the runtime instances of those classes.

That kind of dynamic knowledge can come from one (or more) of three sources:


Reflection

The framework can combine mapping files with runtime reflection to generate CRUD statements based on current values.


Bytecode injection

The framework can instrument your compiled domain classes, injecting new code paths that automatically generate CRUD statements or related metadata.


Code generation

The framework can, through a more detailed mapping scheme, allow you to decorate your domain with metadata that will become Java code when run through a preparsing step.

When most Java programmers are asked for their first thoughts about the Reflection API, the word that pops from their mouths is "slow." While it's true that calls made through reflection are necessarily slower than native calls with direct manipulation of Java classes, the difference between the two has been closing with each release of the JVM. The Hibernate team explicitly chose reflection because it has minimal impact on the build process for an application and because the impact of having a few reflective calls will be hidden by any actual access to the database, which is where most applications incur most of their operational cost.

The other two choices, bytecode injection and code generation, change the build process of an application and result in code being inserted into your domain classes. While not inherently bad, the Hibernate team chose instead to keep your domain classes unencumbered with extraneous service code by choosing reflection.

20.2.3. Java, JDBC, and RDBMS

Hibernate is a framework that specifically provides for transparent persistence of Java objects over JDBC[1] to a relational database management system. This specificity allows Hibernate to provide performance optimizations and general ease-of-use features that would otherwise be more difficult.

[1] For more information on JDBC, see Chapter 8.

20.2.4. Pluggability

Hibernate provides a variety of services to an application: transaction management, caching, optimizations, and so on. These services might be adequate for a broad spectrum of applications, but sometimes application requirements call for specific service providers or features from the service that the Hibernate version cannot support. Hibernate allows for almost every service in its libraries to be replaced by a third-party implementation, usually through nothing more than a change to the configuration files.

20.2.5. Performance

Hibernate is designed to provide high-performance access to a relational database. In the most basic sense, the Hibernate API is designed to favor patterns and programming decisions that allow for high concurrency by not holding open JDBC connections for longer than absolutely necessary. Additionally, Hibernate caches SQL statements to be executed as late as possible in large batches and holds prepared statements for faster execution. Through optimization techniques like lazy loading and proxy initialization, Hibernate gives developers still more control over the performance of their applications. Last, through a series of debugging and monitoring features, developers can learn detailed information about how well their application performs both at development and deployment time.



Java Enterprise in a Nutshell
Java Enterprise in a Nutshell (In a Nutshell (OReilly))
ISBN: 0596101422
EAN: 2147483647
Year: 2004
Pages: 269

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net