Results 1 to 5 of 5

Thread: HibernateTemplate.load

Hybrid View

  1. #1
    Join Date
    Jun 2005
    Posts
    23

    Default HibernateTemplate.load

    Hi,

    I've seen more or less similar posts around on this forum. Yet I would like to add one thing to the following 'problem'.

    In Hibernate 3 by default association objects to a class are loaded lazily, thus a CGLIB proxy is used.

    If you use the hibernate3 template and then use the hibernateTemplate.load(..) to get a single object, using a primary key that does not exist (hibernate would throw ObjectNotFoundException in case without proxies).

    The "let us transform the ugly hibernate exception into a nice spring exception" code doesn't work. That is because a proxy is returned by session.load from Hibernate and it is never ever touched again by the HibernateTemplate's load method. Resulting a non-existing object as proxy is returned. Touching it later in one of the Dao's would result in the above-mentioned hibernate exception.. (or later in the front-end causing lazy exceptions). Not something for instance the front-end web-app. is expecting normally.

    I must add that this is the case in an inheritance relation, where one class inherits another and I am loading the subclass (maybe not relevant, but just that you know).

    Anyway in the execute(HibernateCallback ...) method the following code is used:
    Code:
    Session sessionToExpose = (exposeNativeSession ? session : createSessionProxy(session));
    Object result = action.doInHibernate(sessionToExpose);
    flushIfNecessary(session, existingTransaction);
    return result;
    Touching the result object in any way, would still cause the expected hibernate exception to be thrown, so that it is nicely wrapped inside a spring exception.

    Let me know what you think,
    Martijn

  2. #2
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    Indeed but not everybody wants that.Touching lazy objects after they are loaded contradicts the whole idea of laziness. A better way to avoid your problem is to stop using load() and start using get() which returns null if the object is not found.
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

  3. #3
    Join Date
    Jun 2005
    Posts
    23

    Default

    Hi Costin,

    Thanks for the reply and yes, that's another way to do it. But I liked the idea of Spring wrapping up the ObjectNotFoundException nicely - which I hoped it did when I did a load of a single object (that did not exist), so it could be caught in the front-end by exception resolvers (assuming you don't want to catch hibernate things). With a get I explicitly need to check myself (somewhere either in the service or in the controller).

    Anyway as I agree with your statement and don't want to break the lazy loading for all objects, we can just overload the load( ) method and have the behavior I had hoped for.

    Martijn

  4. #4
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    Another idea that was discussed some time ago on the forums (not sure what keywords to use to find it) was to use some interceptor that could touch the objects returned and then apply the exception wrapping.
    There is something similar in Spring Modules in the AOP module and inside the sandbox if I'm not mistaken. However, note that in general, after throwing an exception a session should not be used anymore (another con of using load()).
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

  5. #5
    Join Date
    Jun 2005
    Posts
    23

    Default

    Hi Costin,

    Thanks again for your quick reply. That sounds interesting what you suggest. I'll see if I can find it somewhere.

    And yeah you're right, the session should not be used anymore. But that's not gonna happen anyway, as this trouble was all about getting the load exception wrapped in a spring runtime exception to the front-end. In most cases one should always rollback failed transactions, so that should do the trick - or actually Spring does the rollback trick.

    Regards,
    Martijn

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •