At JBoss World last week in Berlin I presented some advanced Hibernate patterns. Well, I planned to talk longer about the Swing and Hibernate demo app I wrote a few days before but it turned out that although 100% of the audience was using Hibernate, only one poor soul had to work with Hibernate in a two-tier desktop application scenario. So I spent more time on the other patterns and only showed the Swing demo for about 5 minutes at the end of the presentation.
I thought more people would be interested in this, it comes up frequently on forums and the Wiki. Developers who have to access a database from a Swing application with no middle tier always have the same questions:
How do I use the Session? and
How do I get an updated object into a different view?
The answers to these questions are very much interconnected. I don't claim that what I came up with in the demo app is the best possible strategy, although it works nicely as a proof of concept. Also, I'm a terrible Swing programmer, only did two quite small projects about 4 years ago. I actually used Hibernate even back then but if I look at my code now it wasn't really that good. This is now much better.
First, here is a screenshot of the app:
On the left is a frame with a tree and a modal dialog that pops up if you create or edit one of the items in the tree. On the right hand side is a frame with a panel, in that panel is a label and a table. These views are assigned to controllers, which also handle the model for each view. I prefer the hierarchical MVC pattern for this, so you end up with MVC triads:
Now, all of this is independent of the persistence context (think Hibernate Session). I wrote a very small HMVC framework that supports arbitrary scoping of the persistence context (it's always bound to the current thread, this is also an orthogonal concern). The scope of the persistence context depends on what I want for a particular MVC subtree. Do I want to work with a single identity scope in that subtree? Do I want one in-memory representation of a particualr database row? If yes, then I use the same persistence context for all controllers in that subtree. Have a look at the controller superclasses in the download package.
If I don't want the same identity scope, I can pass detached instances between different persistence contexts and reattach them when necessary. In the demo app, I could have easily implemented the list view of items on the right side with a different persistence context and pass the selected category into the ItemListController.
I also need to pass other things between controllers, all kinds of events. So for example, if a user selects a category on the left side, I fire a CategorySelectedEvent. Whatever controller has registered a listener for that event, gets the event. The propagation is done by the controllers, and I can decide if an event is only propagated downwards to subcontrollers, or globally to every controller in the hierarchy tree (an application could have several HMVC trees). I can put a payload into an event as well, for example, to transport a detached object into a different persistence context:
Transaction handling is also an orthogonal concern. Data access might happen behind the scenes, for example, when a user expands the tree nodes. Or, a button is clicked and an action executes. You can't really wrap transaction demarcation (BEGIN and COMMIT) around on-demand data retrieval, when a Swing data model (a TreeModel here) accesses its bound entity objects. So this is a scenario where auto-commit mode for reading makes sense. The persistence context still provides repeatable read for all entity instances. On the other hand, all data access that is done explicitly when an action executes (button was clicked) is wrapped in a regular transaction block. The demo framework also has the code for this.
You can download the demo app here - I will need to find some time to document this better (there is some Javadoc in the source though).
With the release of CR1, we are proud to announce Seam 1.1 to the world. Seam 1.1 brings Ajax, lightweight asynchronicity and the Seam Application Framework to Seam, and brings Seam to the J2EE platform. No matter what application server you use, you can experience the difference made by Seam's unique state and concurrency management architecture. This release is also a huge step forward in maturity, with many bugfixes and minor enhancements.
New features include:
- New concurrency model for AJAX-based applications
- Integration with ICEfaces and Ajax4JSF
- Support for J2EE environments
- The Seam Application Framework for data-oriented applications
- seam-gen, a command line tool for generating seam projects, actions, and reverse engineering existing databases
- Efficient clustering of Seam-managed extended persistence contexts and JavaBean components
- Support for atomic conversations
- Asynchronous methods and events
- Enhanced configuration via components.xml
- Exception handling via annotations or exceptions.xml
- Page fragment caching via <s:cache/>
- Decoration of invalid input via <s:decorate/>
- Page parameters for RESTful applications
- Support for the Sun JSF 1.2 reference implementation
- Many, many bugfixes and other enhancements
Many thanks to everyone who contributed to this release, which was a real team effort.
Download it here:
After an extensive and quite challenging editing period, the 880 pages update to /Hibernate in Action/ is now available. You can get the eBook on the Manning website. The book is currently being printed and should soon (I guess in about two weeks) be shipped to all MEAP subscribers and resellers such as Amazon.
A sample chapter (
Starting a project) can be downloaded here.
The source code of the example application has also been updated and is available on the CaveatEmptor website.
The Hibernate developer team released Hibernate 3.2.0 GA today, this release is now ready for production use. Please read the migration guidelines if you are upgrading from an earlier version.
In addition to Hibernate Core, final releases of the Java Persistence provider are now available with Hibernate Annotations and Hibernate EntityManager. The Hibernate Java Persistence provider has been certified with the Sun TCK. You can use the Java Persistence API and annotation metadata in any Java project, inside or outside any Java EE 5.0 application server. If you are upgrading from an earlier version of the Hibernate Java Persistence provider, please see the migration guidelines.
We'd like to thank all contributors and users for their issue reports!
I heard about FindBugs(tm) while listening to one of the Java Posse podcast. Since Hibernate Annotations and Hibernate EntityManager are very close to their respective final releases, I decided to give it a shot.
FindBugs(tm) is basically a static code analyser that tries to find bugs in your code through some pattern recognition. I have been working in the past with both static and dynamic code analysers and I have been pretty disappointed by their false positive ratios (basically a non-bug considered as a bug), and the complexity of their set up process. FindBugs was a refreshing experience.
The cool stuff about it is, well, there are several cool stuffs:
- it's a no brainer to set up and run
- the amount of false positive is surprisingly low
- it works at the bytecode level, so you don't have to have the source code (more later)
I haven't read the documentation, just downloaded the package and run the .bat file. A couple of clicks and I was analysing Hibernate Annotations and Hibernate EntityManager . No fancy Ant integration required (you can, but you don't have to), no fancy IDE dependency (you can, but you don't have to), no fancy command line requiring you to RTFM (you can, ahem you should, but you don't have to). The provided GUI does the job pretty smoothly, even if a package filtering feature would have been really cool (more later).
THE thing that usually kills such a product is the amount of false positive bug claims. You end up scanning hundreds of warnings without paying attention to them and trash the whole product after 30 minutes. FindBugs has a pretty low false positive ratio, which is very good. And if the warning end up being a false positive, there are usually some good reasons that worth a second look at your code. I must admit I am pretty proud of me ;-) Of course in HAN and HEM, I found some bugs and suboptimal constructs (no worries, I fixed them), but much less than my expectations.
That is probably what makes it easy to use (and hard to develop), FindBugs(tm) works at the bytecode level, not the source level (it highlights the source line if the sources are available). So pointing a jar or a directory containing your compiled classes is enough. Actually what I did, was pointing to my project root directory, and the job was done.
So while analysing Hibernate Annotations and Hibernate EntityManager , I ended up analysing a bunch of jars (Oh Filter, where art thou?), and I can tell you some guys out there should take a look at FindBugs(tm) , this include a bunch of JDBC drivers and well known in-memory Database backed by some big company(ies) ;-)
It's free, it's easy to set up, it's going to take two hours of your time and save you much more.
Had some time to package the Getting Started example code and put it on the CaveatEmptor Website. So all you MEAP readers have something you can actually run without copy/pasting from the PDFs. I should probably mention that the unedited draft you are reading with MEAP is not completely in sync with the code I just packaged. Well, mostly the Ant build files are a little different, so that shouldn't be a big problem.
Working on the CaveatEmptor main application package now, hopefully ready in a week or two.
Finally, the Manning Early Access Program (MEAP) has the PDFs of /Java Persistence with Hibernate/ online. You can get access on the book website. Some caveats:
- Manning used a draft from May/June 2006 to create the MEAP chapters. Since then these chapters went through reviews and edits, quite extensive actually. If you want to provide feedback, please note that any typos, code examples that don't match the illustrations, or even broken code examples are most likely already fixed. This makes this public review less useful than it could have been, but what can you do...
- If you know /Hibernate in Action/ you might be surprised that the first chapters are quite similar to what was in this old edition. This is normal, ORM is still ORM and POJOs are still POJOs, so much of that content hasn't changed (although it was certainly updated whenever necessary). Expect more interesting new stuff after chapter 4, there are 12 more left then.
- Some terms are wrong in these older drafts, for example, I have used
entity beanuntil June when I realized that Sun marketing wants to call these things
entitiesnow in EJB 3.0. Do a mental search and replace.
I want to upload the source code and the examples for the Getting Started chapter as soon as possible, the main CavatEmptor source still needs some work though. Anyway, I will put the Getting Started on the CaveatEmptor website as soon as new releases of Hibernate, HAN, and HEM are out. Which should be any day now, so stay tuned. I'll post again next week.
Hibernate Tools 3.2.0.beta7 (http://tools.hibernate.org) have been made available.
major feature did go into this release (besides bugfixes and minor enhancements).
Namely support for many-to-many tables during reverse engineering; so please go check
that out if you have been waiting for it and give feedback at our forum and
bugreports or enhancement requests at our JIRA .
See screenshots and other noteworthy news here for more information.
I sat down and created a small viewlet of the HQL/JPAQL editing features we added in the previous release. That viewlet can be seen here , and one of the features it illustrates is shown in the following picture:
p.s. to enable this feature, you need an open Hibernate Console configuration and remember to enable Hibernate for you java project in the properties of your project.
I've seen lot's of people writing (or using) third party abstraction frameworks on top of ORM solutions like Hibernate so that they can potentially get rid of one ORM engine to another (or even an other technology). Such frameworks are even considered by some architectsas a must-have.
Praiseworthy, but raising more issues than fixing ones. When you abstract technologies
like Hibernate to make them
portable, you end up sacrificing
lot's of power and functionalities. Simply because semantics are slightly different from
one engine to an other.
Let's play with statistics:
- in 1% of the applications, the need for a switch from one ORM engine to an other arise
- in 99% of the applications, the need for one or several advanced features of ORM arise
You should focus on using and knowing your ORM engine and not on spending time in writing (or using) an abstraction framework.
When using abstraction frameworks you haven't written, other kind of problems actually show up.
When your ORM engine introduce new APIs or new features, you have to wait for the abstraction framework to release accordingly making you dependent on someone else's agenda.
You no longer know (either by heart or at all) the actual method abstraction (or semantic alteration) introduced on top of your ORM engine. This user learnt it the hard way (and he is unfortunately not alone), Spring's /HibernateTemplate/ wraps the Hibernate methods without even giving you a hint about the actual semantic.
The only proper abstraction between an ORM engine and another is a common specification they adhere to. This is one of the reasons why JPA (EJB 3.0) has been introduced. Why is it the only way? Because a specification describes in a very detailed way the common semantic the various ORM engines have to follow.
So please, think twice before using some random proprietary abstraction framework (open source or not). They usually bring no value add but increasing bug areas... Specifications are here to solve the engine abstraction problem (but once again, this is a concern in very few applications).
PS in case someone is misleading, I'm not arguing against DAO layers