Don’t Get Caught Hibernating

Hibernate is a great ORM and influenced most of the jpa standardisation. But a lot of his magic power can turn into malediction if you don’t follow some best practices.Some features in the tool are just there to answer ‘yes we can’ but are in my eyes not production ready. After more than 6 years of use on large application development… I could figure it out what works well or not.

Model best practices

  • use and abuse of components
  • avoid smart getter/setter
    • they may break lazy loading or batch-size mechanism (for eg parent-child relationship, firepropertyChange) or trigger undesired update (trim or rounding)
    • if you really need them switch to access=”field”
  • Use custom usertypes for example to trim/uppercase/unaccent automatically, convert db date types to jodatime equivalent
  • implements wisely hashCode and equals(and follow the contract)
    • the db id is can be null
    • use getter/setter (proxy issues)
    • don’t use reflection
    • prefer hashCode/EqualsBuilder
    • avoid depending on other entities (breaks lazy loading)
  • avoid inheritence, prefer composition
    • polymorphism and the different hierachy strategies are awesome… but they will bite you one day or another (performance, or “impossibility” to change “type”)
    • prefer a cluster safe id generation like identity column or similar (sequence)

Fetch mode, hibernate mappings

  • the default should lazy=true in mapping and initialize by navigation or using query fetchmode in your DAO
  • avoid lazy=false like the pest, once they are in… it’s hard to get them out !
  • Avoid Select N plus 1 :
    • one of the plague in most application I’ve seen not only for hibernate powered application (rails,raw jdbc)
    • with 2 attributes batch-size at class and collection level you can gain in performance and stability
  • join isn’t always the better option (cartesian product, db engine aren’t always good at it).
  • Too much data loaded : sometimes it’s better to use hibernate projections or named queries
  • Avoid not-found=”ignore”
    • ignore not-found on manyToOne relationship force hibernate to check if the records exists… and breaks any lazy load mechanism
      “many-to-zero or one” can be re-implemented by a set for one-to-many

Hibernate query api

  • prefer load/get/DetachedCriteria over other hibernate query apis !
  • avoid direct sql, prefer externalized named-query for advanced sql query, stored proc calls or legacy table mapping
  • avoid “dynamic” hql : concatenation issues (should I close the parenthesis, append “end”, risk of non prepared statement)

Extreme hibernate

some features are available…. but use them wisely, or don’t use them 😉

  • Avoid Property-ref : they force hibernate to lookup the database… even if you know that it’s an alternate key
  • Avoid Caching ever changing query/entities:
    • cache your metamodel (postal code,…)
    • Don’t use Hibernate default cache implementation
    • be carefull with temporal queries : give me the TVA% at this date: it’s perhaps smarter to do give me all tva indexation events and will find it through java iteration.
  • Avoid Composite key
    • use them only for legacy table mappings and be aware that the performance won’t be good for example when doing batch loading

In the end it’s a db under the hood

  • display the sql logs in development mode(it will show you the effect of one click in your ui)
    • sessionfactory settings
    • log4j : org.hibernate.SQL
  • use jamon ( to measure first (in production also !)
  • don’t return 100000 records to your user : use paging !
  • Avoid casting in SQL:
    • preserve sql types for exampl 0 vs ‘0’ may prevent your sql engine to use the correct index
  • Avoid sql with like “ends with” clause
  • Avoid duplicating indexes
  • Don’t use Hibernate built-in connection pool

Benefits from metadata

Through the session factory metadata you can :

  • create a tool to enforce some rules : use identity column for id, don’t use property-ref,…
  • impact analysis : who is using this table/stored procedure,…
  • you can generate your model documentation with a tool like linguin maps

  1. #1 by mymail on March 27, 2012 - 6:24 am

    Hibernate sucks, dont use it.

    • #2 by mestachs on March 27, 2012 - 4:34 pm

      @ really constructive thanks but feel free to don’t use it.
      but from my perspective it solves more issues than it introduce… so I will keep it.

  2. #3 by Alex Stoisavljevic (@staleksit) on March 27, 2012 - 9:33 am

    I was wondering …

    You say that:
    ” – don’t use reflection
    – prefer hashCode/EqualsBuilder”

    I am using apache-commons, ToStringBuilder, HashCodeBuilder and EqualsBuilder, but if you take a look at their implementation, they heavily use reflection.

    So the real question is to use or not builders since they use reflection by default?

    • #4 by mestachs on March 27, 2012 - 4:30 pm

      for example this use case of ToStringBuilder isn’t based on reflection : (the one I am encouraging in this article)

      return new ToStringBuilder(this).
      append(“name”, getName()).
      append(“age”, getAge()).
      append(“smoker”, getSmoker()).

      and this one does :

      return ToStringBuilder.reflectionToString(this);

      Note also the usage of the getters and not the fields of the person.
      Hibernate may extend your class dynamically via cglib or javassist to enable lazy loading
      and will delegate the getters call to another instance.

  3. #5 by Alex Stoisavljevic (@staleksit) on March 28, 2012 - 12:21 pm

    ok, I’ve got your point, but I usually use one extra method that I call String[] getExcludedAttributes(),
    where I define all possible pitfalls of proxies in object graph. So reflection is used on this but with excluded attributes that belongs to object graph.

    What do you think about such solution?

  1. Performance : when average is not enough ? « Don't Make the Same Mistake Twice
  2. Performance : when average is not enough ? « Don't Make the Same Mistake Twice
  3. hibernate reviewer : graphviz, hibernate cfg to review jbpm 5.2 « Don't Make the Same Mistake Twice
  4. Don’t Get Caught Hibernating (again) « Don't Make the Same Mistake Twice
  5. Buenas prácticas usando Hibernate « Java Mania

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: