Here are a few of my Hibernate tips and tricks that I documented a long the way:
inverse=”true”
Use this as much as possible in a one-to-many parent-child association (to another entity or value-type that is used as an entity).
This property is set on the collection tag like “set” and mean that the many-to-one owns the association and is responsible for all db inserts/updates/deletes. It makes the association part of the child.
It will save an db update for the foreign key as it will occur directly when inserting the child.
Especially when using “set” as mapping type, it can gains performance as the child don’t need to be added to the parent collection which can save the loading of the complete collection. That is: due to the nature of a set-mapping, the whole collection must always be loaded when adding a new child as that’s the only way hibernate can guarantee that the new entry isn’t a duplicate which is a feature of the JRE Set interface.
In case it concerns a component collection (= collection containing only pure value types), inverse=true is ignored and makes no sense as Hibernate has full control of the objects and will choose the best way to perform his crud actions.
If it concern detached DTO objects (not containing any hibernate objects), hibernate will delete all value-type child’s and then insert them as it doesn’t know which object is new or existent because it was completely detached. Hibernate treats it as it is a new collection.
lazy Set.getChilds() is evil
Be careful using getChilds() that returns a Set and will lazy load all child’s.
Don’t use this when you want to add or remove just a child as it will first
always implement equals/hashcode
Make sure to always implement the equals/hashcode for every object that is managed by Hibernate, even if it doesn’t seem important. This counts also for Value type objects.
If the object doesn’t contain properties that are candidates for the equals/hashcode, use a surrogate key, that consists of a UUID for example.
Hibernate uses the equals/hashcode to find out if an object is already present in the db. If it concerns an existing object but Hibernate thinks that it’s a new object because the equals/hashcode isn’t implemented correctly, Hibernate will perform an insert and possible a delete of the old value.
Especially for value types in Set’s is important and must be tested as it saves db traffic.
The idea: you are giving Hibernate more knowledge such it can use it to optimize his actions.
use of version
Always use the version property with an entity or a value type that is used as an entity.
This results in less db traffic as Hibernate uses this information to discover if it concerns a new or existing object. If this property isn’t present, it will have to hit the db to find out if it concerns a new or existing object.
eager fetching
Not-lazy collections (child’s) are by default loaded through an extra select query that is just performed just after the parent is loaded from the db.
The child’s can be loaded in the same query as loading the parent by enabling eager fetching which is done by setting the attribute “fetch=join” on the collection mapping tag. If enabled, the child’s are loaded through a left outer join.
Test if this improves the performance. In case many join’s occur or if it concerns a table with many columns the performance will get worse instead of better.
use surrogate key in value type child object
Hibernate will construct the primary key in a value-type child of a parent-child relation that consists of all not-null columns. This can lead to strange primary key combinations, especially when a date column is involved. A date column shouldn’t be part of a primary key as it’s millisecond part will result to primary key’s that are almost never the same. This results in strange and probably poor performance db indexes.
To improve this we use a surrogate key in all child value-type objects, that is the only not-null property. Hibernate will then construct a primary key that consists of the foreign key and surrogate key, which is logic and performs well.
Note that the surrogate key is only used for database optimization and it’s not required to be used in the equals/hashcode which should consists of business logic if possible.