Summary
A new article by Shine Technologies examines some real-world lessons learned using Hibernate.
Advertisement
The folks at Shine Technology used Hibernate in several production projects, and wrote up the lessons learned in Real-World Experiences With Hibernate.
Most of the experiences in the article are also mentioned at various places in Hibernate's online documentation and tutorial. Still, many developers new to Hibernate start out by learning Hibernate's O/R mapping techniques, and only later realize that Hibernate is basically just a clever layer that connects an object model to a relational database.
For instance, the article mentions that Hibernate can easily pervade an architecture, imposing its idiosyncrasies on an entire application. However, designing a purely Hibernate-based persistence layer is often the result of a decision one must make when using any framework that provides a fairly well-rounded solution to a problem domain. The article does a good job of highlighting such trade-offs when using Hibernate.
One such example is whether to use only Hibernate to access the database, or permit database access via non-Hibernate means as well, such as via a direct JDBC connection. The Hibernate tutorial itself mentions that at times it may be appropriate to directly access the database via JDBC (a JDBC connection can be obtained from Hibernate's session). However, if you access the database via any means other than the Hibernate session and Hibernate's O/R mapping, then database objects you create or query will not show up in Hibernate's cache. In other words, if you were to obtain a database connection from the Hibernate session, and then use that to insert a new database record, that new record will have no corresponding cached representation. A similar issue exists in any caching framework, and is also the case with Hibernate because of Hibernate's tight integration with caching.
Additional areas covered in the article include performance, testing, and tools support.
> via any means other than the Hibernate session and > Hibernate's O/R mapping, then database objects you create > or query
or, more importantly, update
> will not show up in Hibernate's cache. In other > words, if you were to obtain a database connection from > the Hibernate session, and then use that to insert a new > database record, that new record will have no > corresponding cached representation. A similar issue > exists in any caching framework, and is also the case with > Hibernate because of Hibernate's tight integration with > caching. </p>
What are the Hibernate specific issues WRT caching? Does Hibernate perform Optimistic Locking for updates?
Actually, I don't like Hibernate. First: it is just to big. I always have to look up the stuff I try to do. Then, that is not really a problem. But it also restricts me very much in that what I try to accomplish. We have a legacy database and some of the stuff is a bit weird, but still Hibernate should have support for it, if it is supposed to be mature.
I can't use the keys I like, within the mappings, lazy loading doesn't work on components, I don't have access to all properties on the component if I try to do my own sql statements. I can't have keys which have a fix part and a autogenerated part, and it also doesn't work to use depending on context to use one time one key and other times a different key (resulting from our "interesting" database design).
The I tried iBatis and it just worked as I expected. I haven't tried it extensivly so far, but it just did what I needed, and I was up an running in no time.
For now I have to do with Hibernate, but if I had to decide, I would go with iBatis.
One other thing, which bugs me, is the arrogance of the hibernate community. They don't answer on questions, and if, it isn't much of a help at all. Just have a look at the unassigned tickets as well.
What are your experiences, especially with legacy databases?
performance is fine, it's just running standard queries. you should consider using Hibernate.initialize to load those items when you need them.
the tricky issue is that hibernate seems to promise you a complete domain object (for the object employee which houses employee preferences, employee groups, employee address, friends) with something as simple as : "from Employee emp where emp.empId = :empId". It just isn't the case, or if it is, i've missed it.
i think the arrogance cmoes from people who have spent 6 weeks trying to master hibernate only to realize they'll have to put mastery on hold, in the meantime they know enough. thus when someones asks for help they say "JUST RTFM". "like i did!" is ommited of course ;)
Frankly, I don't think I don't like lazy loading in a database access layer, it seems to have added a large complication where it used to be a lot cleaner. query for what i want/need damnit.
I don't talk about performance, which doesn't matter for me as long as it is just ok.
Actually Hibernate promises the complete domain object - as far as I understand it - and thats exactly where the lazy loading comes into the play, and where I need it. In our database we have only three large relations, but there is a whole bunch of other tables connected to the entities in those, mostly via 1:1 references. Therefore my actual objects are composed by lot of other subobjects. And I want to have them loaded automatically and only if needed. If I have to do that manually, then why I should need Hibernate?
The promise of Hibernate IS a tranparent persistence of the objects into the database (and back). So far so good. But if I can't describe the model I need in the mapping files, then it is apparently of no use for me. I can't do a major change to our database - which would be required to make it work with hibernate - because we have another application running ontop of it. But if you have a closer look at the hibernate documentation there are a lot of implicit assumption about the design of the database, which is in many cases not given with a legacy application.