When my book on Hiberante was released on amazon a short while ago, I was lucky enough to have Mark Spritzler from the JavaRanch to ask for a copy of the book to go over. To be honest, I was a little surprised when Mark sent me some feedback. I mean, the guys a pretty respected expert on the topic of Hibernate and ORM mapping in general, so I really don't think there was a lick of information that he could learn from the book, but he did read it, and he sent me some great feedback.
He noticed a coulple of little things that have been in thorn in my side since re-reading the original printing. One thorn was the updateAll method that calls saveOrUpdate, but doesn't really need to since the User object is loaded and subsequently changes all within the same open session. If you do that, there's no need to update, because the Hibernate Session is still keeping track of any state changes, and will commit them when the transaction is finished.
He also noticed the change from User u to User user. I made that change after about writing a third of the book, but I was worried that if I went back to the first third and did a find/replace thing, then I'd end up missing a bunch of references and the code would break. :( I do have a line that mentions the change when it first happens, but perhaps it is not enough.
Another thing he notes is that I place the annotation on the getter, not the variable. That's they way my last few project managers have requested it, and that's the way I wrote the book. But it seems the trend is actually to put the annotation on the property, not the getter. :( I'll make a note of that in the next printing of the Hibernate book.
I also think Mark's mention of disagreeing with me on HQL vs. the Criteria API is hugely important. I make a few glib remarks about HQL, but someone like Mark, who has really done alot of work in this area, knows the value of HQL. His opinion on the project should probably hold much more water than mine.
Anyways, here's his feedback. i do hope he doesn't mind me sharing the email he sent me. It's really more embarassing to me than to him. :)
"Hey Cameron, I finished reading your Hibernate book over my vacation, and got a good list for you. I had found 2 spelling errors, but I wanted to read through the book and didn't note the pages. I am also sure I saw somewhere, where you created an instance variable called "user or "u", and then later in the same code switched it around. Something like
User user = new User();
But when I went page by page through the book three times, I couldn't find it again. It might be that I was looking at the code and maybe it was just in the text part. Anyway, it might be nice to consistently use "user" or just "u" in all code that makes Users.
So some notes about my notes. I take it many reasons for things in your book it so show the basics, and just enough to not scare people off. In some cases not show them all options, but just the basic stuff.
OK, so for my notes
Around page 64-65. Basically it is about the @Id annotation. In the case of all your code, you always put the @Id on the getter. But it is also able to go on the actual field/instance variable. And based on where you put your @Id, is where you put your other Annotations, unless you use an special attribute of the annotations. I think something like access="field" or something like that.
Page 67 - In all your code you use addAnnotatedClass(), and in the book never mention that in the config file you can add one setting that will make Hibernate search the classpath for any class that has an @Entity annotation and automatically add it.
Page 76 - default field naming for ids. Correct me if I am wrong, but I was always under the impression that Hibernate will concatenate the class name with the id attribute as the default pk id field. For instance, if I have the User class with the id attribute, it would look for a user_id field as the PK.
Page 109 - JDBC and HQL variable injection with "?" I thought the first "?" in jdbc and Hibernate was the "0" position and not "1", that it was zero based?
page 117 - updateAll() method is calling the update() method in the for loop. But since the data objects were loaded in the session, then changed, that Hibernate is already maintaining those objects, and therefore a call to update() is unneccesary, as they will have update statements run at commit()
page 129 - SessionFactory singleton. Most people implement singletons with static initializers instead of the single check in the "get" method. The code as is could create two instances of the SessionFactory.
Page 190-192 - Do you want to mention @NamedQueries for when you have more than one named query declared?
Mapping Inheritence chapter - a whole big topic here. So I am saving it for last.
Page 323 - Title shows @OneToMany. Did you mean @OneToOne? also look at the text in the first paragraph there for another @OneToMany
Ok the mapping inheritence chapter. As far as exactly what is written, it is fine. But there is another view point, or perspecitve in terms of the object model that the text would not work for, and is one that is used in the JBoss Hibernate class. If you have an object model that has one super class and two direct subclasses. So a parent with two children, instead of your grand-parent/parent/child example. In the case of two children then you would find that for a database the third normal form will be the better data model to map to. Now in one or two cases the polymorphic query would be slower, in other cases the queries will be faster in this model.
I definitely enjoyed the book, and will give it a good review. Although I disagree with you on Criteria versus HQL, but I am more of a whatever will work best for the particular query. So for simple queries, I love Criteria, but once I add more tables/objects/joins, and more complex queries, give me HQL anyday over Criteria. :)
I think your book does a great job in its intention to get someone who is brand new to Hibernate, up and running quickly and understanding the basics to effectively take on the Hibernate learning curve. (I better copy/paste that into my review)
Talk to you later