Compound Theory

v2.0

Categories

  1. Transfer
  2. ColdFusion
  3. JRuby
  4. Java
  5. ColdSpring
  6. Squabble
  7. JavaLoader
  8. ColdDoc
  9. 2ddu
  10. AsyncHTTP
  11. OO Analysis and Design
  12. Flex
  13. Railo
  14. XML / XSL
  15. Hibernate
  16. ColdFusion Builder
  17. Fall
  18. Ubuntu
  19. XHTML / CSS
  20. Eclipse
  21. Git
  22. Oracle Database
  23. Usability / UI Design
  24. webDU
  25. cf.Objective()
  26. LWJGL
  27. cf.Objective(ANZ)
  28. Captcha
  29. MAX
  30. Melbourne CFUG
  31. Martial Arts
  32. Random Things
  33. Conduit

Recent Posts

Projects

Recent Comments

15 July 2009 11:26 AM

ColdFusion 9 ORM - Explaining Hibernate Sessions

Now that ColdFusion 9 is in public beta, I wanted to write some articles explaining how Hibernate is actually working under the hood of the nice ORM integration we now have.  Like all powerful tools, they can do a great many things - but only if you really understand how they work.  Otherwise, they are potential for disaster if you don't know what you are doing.

Hibernate Sessions

The first thing we need to cover is the concept of Hibernate Sessions, which has been nicely hidden away from ColdFusion developers by the Adobe Engineering team, but is still something that you need to really understand to be able to leverage Hibernate in CF9 properly. (At least IMHO).

First things first - don't confuse this with ColdFusion Sessions, or any sort of browser session.  Hibernate is built as a generic solution to ORM, so it has no specific ties to web state. A Hibernate Session is a lightweight object that is used to delineate when Hibernate is meant to start working, and when it is meant to stop, which is often referred to as a unit of work. This may span several transactions and/or INSERT, UPDATE, DELETE and SELECT statements as the Session gets used.

This is very much like the start and stop of a conversation, we say hello at the beginning, and say goodbye at the end, and whatever we need to discuss goes on in between, except we just tell the Session to open() and close(), rather than "hello" and "goodbye".

Actual Hibernate Java code would look something like this:

//open the session from the SessionFactory (which is where sessions come from)
Session session = sessionFactory.openSession();

//get fred, our caveman
Caveman fred = session.get("Caveman", 2);

//change his age to 32
fred.age(32);

//close the session, which will update fred.
session.close();

I'm not going to get into where the SessionFactory comes from, as all you really need to know is: it's where Hibernate Sessions come from.

So what we are doing here is:
  1. opening a Session, i.e. we tell Hibernate 'Hi', which starts our conversation.
  2. Tell Hibernate to retrieve our Caveman fred, through our session.
  3. We change the age of fred to 32.
  4. We close our session, and say 'GoodBye' to Hibernate for now.
There are several things that happen here that are worth noting at this point, even in this relatively simple piece of code.

The first is, by doing session.get("Caveman", 2), we have effectively told our Session to track this object, and make note of any changes that happen to it. 

We have also cached a copy of fred in the Session itself, so that if we were to attempt to retrieve fred again, we would get the same copy.  This is both for performance, and also so that the Hibernate Session only has to deal with one object that represents the data behind fred, which will be a fairly important concept as we continue in this article series.

Since our Session is tracking fred, any change we make to fred will be persisted to the database when we close our Session.  In that way, Hibernate is quite transparent in the way it implements persistence.

It should also be noted at this point: Unless you specify otherwise, Hibernate will only run INSERT, UPDATE and DELETE when the session is closed, generally as a batch.  This is so that, for example, multiple changes happen to fred during the length of our Session, there only needs to be one UPDATE statement when we are finished.  This is an important thing to note, as it is possible to get confused as to why your changes to your objects aren't appearing in your database during your Session, but do appear afterwards. 

Hibernate Sessions and Web Applications

In web applications, it is usual to manage Hibernate Sessions by opening one up at the beginning of a HTTP request, and then closing at the end of the request.  The length of a single HTTP request is a good size to carry on a nice conversation with Hibernate.

Strangely enough, this is exactly what ColdFusion is doing for you behind the scenes.  It starts a Hibernate Session when your request starts, and ties it to that particular request, and then closes it at the end of the request.  (It is quite likely that the Session actually only gets created when first requested, but for the sake of argument it is easier to explain it as it gets opened at the start of the request)

From there, each of the ORM functions, EntityLoad, EntitySave, EntityDelete, etc, all interact with that Session that exists behind the scenes, for that request.

This means that changes to your objects will also not be persisted to your database, until the end of your ColdFusion request, as that is when the Hibernate Session is closed. In later articles, I'm going to cover some ways this can cause some trouble, and how to work around them.

 

You are actually able to flush the Session, which forces it to persist any changes to the database right then and there, and not wait until the end of the request, which can sometimes be very useful. 
To do this in Java, you could go:

session.flush();

But in ColdFusion you write:

ORMFlush();

UPDATE: You can read more about Session Flushing here, which outlines that there are times in which Hibernate will flush a Session in the middle of Session, however, there is often no guarantee except in specific circumstances.

It's also interesting to note you have direct access to the Hibernate Session if you so desire through ORMGetSession(), which gives you access to that request's Hibernate Session object, so you can interact with it directly.

There is much more to Hibernate Sessions and how they relate to the objects that they manage, but this will give us a good start to build upon for now.

You can read more about ColdFusion and Hibernate Sessions in the documentation Hibernate Session Management.



Comments

Posted by Matt Williams on 15 July 2009 11:54 PM

Thanks for this overview Mark. Very helpful to folks familiar with Transfer/Reactor, but Hibernate newbies.

Any idea what happens to the Hibernate Session if an error is thrown before being closed? I would guess the db changes don't get persisted unless you did a flush before the error.

Posted by Mark on 16 July 2009 06:49 AM

@Matt
Well that's another place where CF does the heavy lifting for you with the Hibernate integration.

You don't need to close or flush the session, it will close it, even if an error is thrown. You never need to worry about closing a session, CF manages that for you.

But the same rule applies, DB changes will get persisted at the end of the request, even if it is an error, because that is when the session.close() will be called.

The changes you made to your objects will still be there, but the details will probably not be in the database at that stage.

Posted by Leigh on 22 July 2009 12:31 AM

> The changes you made to your objects will still be there,
> but the details will probably not be in the database at that stage.

@Mark,

Is that something you are going to elaborate on in later articles?

-Leigh

Posted by Mark on 22 July 2009 08:53 AM

@Leigh,

Check out my next blog post where I discuss exactly that:
http://www.compoundtheory.com/?action=displayPost&ID=416

Posted by Leigh on 22 July 2009 10:05 AM

@Mark,

Perfect. Thanks!

Add Comment