I recently had a JPA related issue and decided that it was high time to purchase a good book on the subject; particularly as JPA/Hibernate tend to play a very important role of course.
I ended up discovering "Java Persistance with Hibernate" (Bauer, King). This book is a revision of "Hibernate in Action" and it certainly reads as a complete reference to all things ORM. What attracted me to this book in particular was its coverage of JPA. I prefer to use JPA over Hibernate interfaces so that my ORM implementation choice is left open as much as possible. Having said that Hibernate gives me no reason to move to another ORM.
I must have been using Hibernate/JPA for the past 18 months. When I started I recall wanting to skim over the ORM subject as much possible in order to get things done i.e. I did not think deeply about the implications of some of my decisions; or rather I misinterpreted the way things worked e.g. the 2nd level cache. To this end here is a list of things that I found myself re-visiting:
* property annotations instead of field annotations;
* using the Collection interface instead of the Set interface;
* cache annotations;
* bi-directional one-to-many relationships;
* immutable entities
Using property access can boost performance when performing operations on a collection (also as opposed to a set). For example if you want to add to the collection Hibernate does not have to load the existing collection from the database. If you use a Set then it does in order to guarantee Set semantics.
Understanding the second level cache is very important and if you don't have time to learn it then disable it. It is also a good idea to understand whether you have immutable entities so that you can use the Hibernate @Entity(mutable=false) annotation and flag to the cache that the object is read only. This permits Hibernate a few optimisations including a minimisation on the number of update statements that require preparing at startup.
I always wondered why my bi-directional relationships were generating a join table. It finally sunk in that the mappedBy attribute on an association describes the foreign key. No more join tables for bi-directional relationships.
There's no excuse; just buy the book if you're doing any ORM. Having said that even before I made these changes Hibernate was performing exceptionally well!