Friday, 13 June 2008

Harnessing Hibernate By James Elliott , Timothy M. O'Brien And Ryan Fowler

Just now i completed reading and practicing examples from Harnessing Hibernate By James Elliott; Timothy M. O'Brien; Ryan Fowler.

I strongly believe if any programmer new to hibernate wants to practice please practice practice practice.Just reading blog articles is not sufficient.All examples provided in the book are great.

Below are the points i wanted to share with readers from this book.

1) You may wonder how Hibernate relates to Enterprise JavaBeans™ (EJBs). Is it a competing solution? When would you use one over the other? In fact, you can use both. Not every application needs the complexity of EJBs; many can simply use Hibernate directly to interact with a database. On the other hand, EJBs are
sometimes indispensable for very complex three-tier application environments. In such cases, Hibernate may be used by an EJB Session bean to persist data, or it might be used to persist BMP entity beans.

2) The Java world owes Gavin King and his intrepid cohorts a huge debt of thanks for making our lives easier.

3) Hibernate is a lightweight O/R mapping service for Java

4) If you have been using JDBC directly, especially if you're pretty new to it, you may be used to relying on the "auto-commit" mode in the database driver rather than always using database transactions. Hibernate is rightly opinionated that this is the wrong way to structure application code; the only place it makes sense is in database console experimentation by humans. So, you'll always need to use transactions around your persistence operations in Hibernate.

5) Once you've got a reference to a persistent object, passing it to the Session's delete() method will remove it from the database:

session.delete(obj);

Another way to delete is to write an HQL deletion query that matches multiple objects.

Query query = session.createQuery("delete from Track");
query.executeUpdate();


6) Named parameters make code easier to understand because the purpose of the parameter is clear both within the query itself and within the Java code that is setting it up. This self-documenting nature is valuable in itself,but it also reduces the potential for error by freeing you from counting commas and question marks, and it can modestly improve efficiency by letting you use the same parameter more than once in a single query.Named queries let you move the queries completely out of the Java code. Keeping queries out of your Java source makes them much easier to read and edit because they aren't giant concatenated series of Java strings spread across multiple lines and interwoven with extraneous quotation marks, backslashes, and other Java punctuation.

Example:


public static List tracksNoLongerThan(Time length, Session session) {
Query query = session.createQuery("from Track as track " + "where track.playTime <= :length");
query.setTime("length", length);
return query.list();
}



Named parameters are identified within the query body by prefixing them with a colon. Here, we've changed the ? to :length. The Session object provides a createQuery() method that gives us back an implementation
of the Query interface with which we can work. Query has a full complement of type-safe methods for setting the values of named parameters

7) Hibernate provides natural ways for mapping database relationships onto Collections, which are usually very convenient.Collections don't provide "bag" semantics, which might frustrate some experienced database designers.

Bags are like sets, except that the same value can appear more than once.

8) When using sets in our mapping file like below example and when we explitly mention inverse="true" then Hibernate understands that when we add an one association to a second object, we're implicitly adding that
second object as an association to the first object at the same time.


<set name="tracks" table="TRACK_ARTISTS" inverse="true">
<meta attribute="field-description">Tracks by this artist</meta>
<key column="artist_id"/>
<many-to-many class="hibernatePractice.businessobjects.Track" column="track_id"/>
</set>



This convenience works only when you make changes to the "primary" mapping, in which case they propagate to the inverse mapping. If you make changes only to the inverse mapping they will not be persisted. This unfortunately means our code must be sensitive to which mapping is the inverse.

9) To save memory The trick is to allow associations to be "lazy," so that associated objects aren't loaded until they're actually referenced.Hibernate will instead make a note of the linked object's identity and put off loading it until you actually try to access it. This is especially important for collections like those we've been using.

10) if we wanted to avoid having to worry about lazy initialization then we need to set lazy="false" in our mapping. For Example


<set name="artists" table="TRACK_ARTISTS" lazy="false">
<key column="TRACK"/>
<many-to-many class="com.oreilly.hh.data.Artist" column="ARTIST_ID"/>
</set>


Again, starting with Hibernate 3, this is enabled by default but you can turn it off by marking an entire persistent class as = (this attribute goes right in the tag of the mapping document).

When your classes are being mapped in a lazy fashion, Hibernate will generate a proxy class that extends (and poses as) your data class. This lazy proxy puts off actually loading the data until it is needed. Any other objects with associations to the lazy class will sneakily be given these proxy objects, rather than references to your actual data object. The first time any of the methods of the proxy object are used, it will load the real data object and delegate the method call to it. Once the data object is loaded, the proxy simply continues delegating all method calls to it.

11) The task of keeping a collection in a particular order is actually quite straightforward.

We need to use java.util.List instead of Set.

For example:


<list name="tracks" table="ALBUM_TRACKS">
<key column="ALBUM_ID"/>
<list-index column="LIST_POS"/>
<many-to-many class="com.oreilly.hh.data.Track" column="TRACK_ID"/>
</list>


It's important to understand why the LIST_POS column is necessary. We need to control the order in which tracks appear in an album, and there aren't any properties of the tracks themselves we can use to keep them sorted in the right order.The LIST_POS column gives Hibernate a value under its control that can be
used to ensure that our list is always sorted in the order in which we created it.

The corollary is also important. If there are values in your data that provide a natural order for traversal, there is no need for you to provide an index column; you don't even have to use a . The set and map collection mappings can be configured to be sorted in Java by providing a attribute, or within the
database itself by providing a SQL attribute. In either case, when you iterate over the contents of the collection, you'll get them in the specified order.

The attribute and SQL sorting of collections is only available if you're using version 1.4 or later of the Java SDK, since it relies
on the LinkedHashSet or LinkedHashMap classes introduced in that release.

12) The attribute tells Hibernate that you want operations performed on a "parent" object to be transitively applied to its "child" or "dependent" objects.It's applicable to all forms of collections and associations. There are several possible values from which to choose. The most common are (the
default), , , and (which combines and ). You can also change the default from to throughout your entire mapping document by supplying a attribute in the tag itself.

13) Reflexive Associations: It's also possible for objects and tables to have associations back to themselves. This supports persistent
recursive data structures like trees, in which nodes link to other nodes.

14) The reference documentation doesn't provide much guidance on this question, but the API documentation confirms the hint contained in the interface names: the
CompositeUserType interface is only needed if your custom type implementation wants to expose internal structure in the form of named properties that can be accessed individually in queries

15) HQL stands for Hibernate Query Language.Just like HQL, expressions are always in terms of object properties, not table columns.

16) If you want to find any objects matching any one of your criteria, rather than requiring them to fit all criteria,you need to explicitly use Restrictions.disjunction ( ) to group them.

17) To print every mapped object in the database use below syntax


List all = session.createQuery("from java.lang.Object").list();
for (Object obj : all) {
System.out.println(obj);
}



About the Authors

James Elliott is a senior software engineer at Berbee, with fifteen years' professional experience as a systems developer. He started designing with objects well before work environments made it convenient, and has a passion for building high-quality Java tools and frameworks to simplify the tasks of other developers

Tim O'Brien
I consult and write from Evanston, IL, about thirteen miles North of the center of Chicago. A maintain a personal blog at www.discursive.com, and I frequently contribute to the OnJava blog.

I've just finished writing, assembling, and editing Maven: The Definitive Guide, a free, green book which is going to be published by O'Reilly in Q3 of 2008. Before that, I had the pleasure to work with Ryan Fowler and James Elliott on the Second Edition of Harnessing Hibernate. A few years ago, Vincent Massol and I collaborated on the first Maven book: Maven: A Developer's Notebook, and prior to that I wrote the Jakarta Commons Cookbook in 2003 and 2004.

I'm committed to the idea that open source documentation is as important to the success of a project as the source code itself - documentation is a primary artifact. This is a lesson most programmers tend to forget after having it hammered into them by Computer Science professors and teaching assistants at The University. In the real world, as in the academy, your coding efforts do suffer that "automatic 30 point reduction in final grading" if fail to supply the required user documentation. Even in the most well-respected open source efforts, documentation remains a governor on adoption and progress. I want to help convince other developers to take the time to get involved in open source documentation. Who said DocBook isn't fun?


Ryan Fowler is a software engineer at Berbee in Madison, WI. He programmed Basic on Apple II machines for a while in elementary school at St. Stephen School in Grand Rapids, MI. He returned to coding in the computer science department at Alma College in Alma, MI while earning his bachelor's degree. Ryan skis, sails and rounds life out with some guitar playing when there's no snow or wind.

Hope you enjoy reading this book.

1 comment:

Anonymous said...

Good post.