This morning I’m live blogging from TheServerSide Java Symposium 2011 at the breakout “Anti-Patterns and Best Practices for Hibernate” presented by Patrycja Wegrzynowicz.
Making Good Software
Patrycja’s primary goal is to “understand what makes good software good and bad software bad” and she is working to formalize these concepts. She would like to develop automated code tools that can detect ahead of time whether or not code contains anti-patterns and potential performance issues.
For those not familiar with the concept, an anti-pattern is an obvious or common strategy which leads to degraded or counter-intuitive performance.
Is Java Fat
Patrycja asks the question “Is Java fat/slow?”. She claims the language is not, in fact, slow, but that some of the ways in which we program objects is slow, which I agree with strongly. For example, I have seen computational entensive code that improved in memory/speed by large degrees by relying on primitive variables, rather than more complex objects, in part because “new” is considered expensive in Java.
Automated Code Analysis
Requires large knowledge base. Patrycja has been researching semantic code query system which focusses on behavior, not just structure.
Patrycja says that proper usage of hibernate is tricky. Transactional issues and correctness of code under various scenarios. Best solution may be combination of Hibernate and JDBC.
I liked that fact that she stepped back and indicate Hibernate, by itself, isn’t perfect. I agree with her take that the best systems are often hybrid systems that take advantage of the ‘low hanging fruit’ of both worlds, and avoid the pitfalls of each.
I was disappointed with this speaker’s previous session so I wasn’t sure whether to attend this one. I did like parts of this session better. It was interactive and presented alternate options. There was also a SQL/hsql puzzle to practice spotting errors. Similarly for java.
Race condition if don’t have right transaction settings. Could solve with proper isolation level of serializable, but slows performance a lot. Repeatable read would not be ok because new row created in this example that not included in max so range query. Hibernate versioning also doesn’t help because on different table. Recommends reordering code so get Lock.UPGRADE first Note this is not a hibernate specific problem. The solution sounds like “for update” mode in Oracle. The speaker also noted an object should not be passing around internal state. Also not Hibernate specific, a query should be done in one step where possible.
- track everything in Java, but then lose benefit of database
- denormalize database
- Use custom mappings with custom queries, laziness and order or where clause
Object oriented issues
Returning the raw list lets callers modify it, encapsulation matters, do not want inconsistent object state
- Write business methods before accessors
- Hibernate can work with private, protected and package access
- Date and Collections are the most likely causes of mutable internal state. Note that defensive copying requires retrieving all objects from thedatabase. Also Collections.unmodifiableList() is a problem because the dirty read check looks at the identity of objects.
There was some reuse in this section from the presenter’s other breakout.
Hibernate can be slow depending on usage. Having a getter return an unmodifiable list when cascade all is on, Hibernate deletes the whole collection and recreates if. The reason is that Hibernate sees the list as having a different identity. Thus can happen when calling get under certain conditions.
We got to hear content from the static analysis talk again. I didn’t like it any better this time because it is still vague.
Other things one could do wrong
Remember where clause criteria
Remember order of args in compareTo()
Conclusion – hibernate is hard, there will be a solution to make it easier one day