I get it now! ThreadLocal that is, i've given up on the filters for now :)
Anyway what I mean is that I now understand the usage of ThreadLocal.
I did as you sugested Steve, and opend a session in each of my CRUD type methods. At first it seemed just fine, but then I ran into use cases where I did have to have some objects loaded and saved in the scope of the same session/transaction. It seemed silly and wastefull to be opening a session to open or save a single object, which is fine if that is all you want to do, and in some cases that is all. However, once I started implementing my more complicated (if you can call them that) use cases, for example a user creating a new article, that I noticed that I need to create a user object, a category object, and finaly a news object.
Those 3 steps are a valid use case in my application, and it started to bother me that I was opening a session for each of those steps, when they really are part of the same "transaction".
So first I thought, ok i'll create a session using my ThreadLocalSession class, and pass the instance as a parameter into my CRUD methods. Well that looked pretty ugly. Then I finally figured it out (call me slow), I can just call ThreadLocalSession.currentSession() iINSIDE my CRUD method and it will use the same exact session that my "use case" method started. To explain it in code (totally made up and wont compile):
Code:
public void buildNews(NewsCommand command) {
try {
Session session = ThreadLocalSession.currentSession(); //start here
Transaction tx = session.beginTransaction();
User user = (User)findEntity(userid); // crud method
... other crud methods ...
session.saveOrUpdate(news);
tx.commit();
} catch (HibernateException e) {
tx.rollback();
} finally {
ThreadLocalSession.closeSession();
}
}
Inside findEntity():
Code:
public User findEntity(Long id) {
Session session = ThreadLocalSession.currentSession(); // same instance!
return session.find(....);
}
Doing things this way, allows me fine control over each of my "use case" methods, in that by having the session opend duing the execution of one of those methods, i can now control just what gets instantiated. Pretty neat.
Now my question... Where should transaction demarcation (beginTransaction(), commit(), rollback(), etc) occour? In my basic crud methods? Or in the more use case like methods that initiate the first opening of the session? I think the former is the correct anwser, but I would like to know what people are doing out there.
Also, am I correct to assume that by using the hibernate transaction API, I can later on plugin another transaction strategy without changing my code?
Hibernate rocks! I'm loving the fact how I can still have a properlly designed domain model, and now that I get it, have fine control over what I need to do. Pretty neat!
Thanks,
John