Skip to content

What’s wrong with Hibernate, #4

Hibernate is supposed to allow you to write queries and manipulate data in the normal Java idiom. Which is true up to a point, and that point is almost five years in the past, when Java introduced generics.

Generics are absolutely standard practice in Java these days, and have been for two (nearly three) versions. But Hibernate still doesn’t support them, despite lead developer Gavin King saying at the time:

We will also need to support Java generics, which basically boils down to allowing typesafe collections (which is very trivial).

Nearly five years later, this still hasn’t happened, and you still need to manually cast the results of queries and liberally add @SuppressWarnings("unchecked") to demonstrate that you’re aware you’re doing things a bit wrong.

Andrew.

There are several other posts in this series. Please read the disclaimer before you write an angry reply.

Share/save this page:
  • email
  • Google Bookmarks
  • Twitter
  • FriendFeed
  • del.icio.us
  • Digg
  • Reddit
  • StumbleUpon
  • Technorati
  • DZone
  • Slashdot
  • Fark
  • Facebook
  • MySpace
  • LinkedIn
  • Live
  • connotea

{ 10 } Comments

  1. stanasic | December 26, 2008 at 9:04 pm | Permalink

    What you observed is certainly a nuisance, but one solved easily by wrapping typed entity access into a DAO pattern. Details are here:

    http://www.hibernate.org/328.html

    In the implementation, @SuppressWarnings is used, but only at that one place.

    Session.load(), Session.get() and Criterias all use Class references, so making them type-safe would indeed be trivial.

    Queries are somewhat harder to crack, as they can return mapped entities, scalars, Object[]s or any other POJO constructed in select statement. So you would need to repeat the type of expected result when invoking a query, which in my opinion is quite more cumbersome then using @SupressWarnings.

  2. Max | December 27, 2008 at 8:26 am | Permalink

    Use JPA ?

  3. Gavin | December 27, 2008 at 12:14 pm | Permalink

    Ahem, typesafe collections doesn’t have anything to do with queries AFAICT.

    I’m not sure how you think the Query API could support generics, you’ll have to explain that one to me. Whenever we or the JPA EG has looked into this, we’ve concluded that there is no reasonable way to do get rid of the typecast for HQL/JPA-QL. However, my proposal for the new JPA criteria API *does* use generics.

    So it looks like you just misinterpreted something I said.

  4. Andrew | December 27, 2008 at 12:53 pm | Permalink

    Maybe I did Gavin, in which case I apologize! I kind of assumed you were referring to things like the list() methods on Query and Criteria, which return, err, non-typesafe-collections. My bad.

  5. philip andrew | December 28, 2008 at 11:52 am | Permalink

    Consider using Hibernate from JPA within JBoss SEAM.
    You can auto-generate most of the application using JBoss SEAM seamgen from the database and the UI and all pages are generated. SEAM solves a lot of issues you might be finding with Hibernate since it uses JPA to use Hibernate and uses EJB3.

  6. Andrew | December 28, 2008 at 12:30 pm | Permalink

    Philip, thanks for the tip — does SEAM play well with web services though? I’m (currently) a services guy 100% and don’t do any end user applications. I’m using Hibernate for back-ending SOAP services in CXF.

    A couple of other people have mentioned JPA too, I got the impression from Harnessing Hibernate that it was noticeably more restrictive than using Hibernate directly. Maybe that’s not often an issue though.

  7. philip andrew | December 28, 2008 at 1:20 pm | Permalink

    SEAM uses JPA and EJB, the main idea is that these things should be close to the user interface, it SEAM’s (joins) EJB, JPA and UI.

    One thing it has is the concept of a conversation, which is a long running context for database access (not long running transaction). What it allows is that if the user navigates a Hibernate objects relationships, it can still load the lazy loading relationships because of this long running context.

    If your server just does logic and database and its off somewhere giving services, the client will normally ask for some objects and get them back. Then the client would like to navigate the relationships, so the server then needs to reload these objects – in the SOA architecture you will most likely come across the lazy loading exception problem! as client calls back, you can’t navigate the hibernate objects anymore as they have gone away. You have to reload them from database or if lucky from cache.

    In the SEAM architecture the client can navigate relationships of Hibernate objects easily. There much more to it.

    If your only going to do services, fine – if it is the requirement, but from a overall perspective I find SEAM best from client to server for HTML website and Adobe FLEX (I use both), for FLEX I use Granite DS as it integrates with SEAM.

    I don’t know – but I guess that SEAM can treat the EJB’s as remote EJB’s and there-by integrate with remote EJB’s over some communications.

    Since you are doing Hibernate server side with web services hope your aware of the hibernate lazy loading issues which are a real hassle.

    From the SEAM book “Lazy loading of entity associations has unfortunately established a bad reputation. The first thing that comes to mind in most developers’
    minds when you talk about lazy loading is Hibernate’s
    LazyInitializationException. The culprit is the detached entity instance…
    If the persistence manager is closed after the action method is invoked, the Course instance is detached when the view is rendered.

    A call to the method getHoles() triggers an exception because the EntityManager that loaded the Course instance is no longer available to further communicate with the database. The same problem arises on postback, even if a lazy association wasn’t hit in the view.”

    Anyway… aside, there are a lot of good reasons to use JPA.

    JPA has a number of implementations available for an intermediate cache to improve performance.

    JPA supports locking of objects for read and write.

    Do flexible joins between large graphs of objects.

    Here

  8. Eirik | December 28, 2008 at 8:27 pm | Permalink

    Seems to ma that all your problems stem from the fact that, despite choosing a persistence framework for domain-driven design, you are still using the (dare I say legacy) text-based api for looking up the entities. If you dropped HQL in favour of the Criteria API all your problems would go away.

    The problem with java 1.4 is that it will be around in enterprise environments for at least 5 more years. IBM didn’t manage to provide a simple upgrade path to java 5 for their customers. Most appliactions written for for java 1.3 and 1.4 versions of WebSphere will stay on that platform for the remaining 4-12 years of their (expected) lifespan. Nobody like this but the alternatives are just too expensive. If Hibernate drops java 1.4 support, a significant number of these applications will no longer have any maintenance options. You just don’t treat your users that way.

  9. Roy | June 23, 2009 at 5:07 pm | Permalink

    Hi Guys,

    Not sure if this is the right place to post this qustion but I have posted on hibernate forum and did not receive any replies ..

    If I have the following class how does Hibernate map it? Is it possible to map abstract generic classes.

    abstract class AbstractBase
    {
    public string Name
    {
    get { return typeof(T).Name; }
    }

    }

  10. Andrew | June 24, 2009 at 10:34 am | Permalink

    The Hibernate forum is really hard to get useful information out of, that’s one of the things that annoys me about it.

    I’m not sure how it would handle that, you’d have to try it, but AFAIK it doesn’t understand generics *at all* for compatibility with all the big crappy organizations still using JDK 1.4.

Post a Comment

Your email is never published nor shared. Required fields are marked *