Article: Hibernate 3.1 Used with Tomcat 5.5.x

Discussions

News: Article: Hibernate 3.1 Used with Tomcat 5.5.x

  1. Article: Hibernate 3.1 Used with Tomcat 5.5.x (43 messages)

    This three-article series describes the configuration of Tomcat 5.5.x and Hibernate 3.1 so they can be used together. Part one describes how to configure the Tomcat 5.5 Context.xml file using raw JDBC to access the MySQL database, part two describes the same process but with Hibernate intead of raw JDBC, and part three illustrates a Hibernate database update and talks about application design in a shopping cart scenario.

    Threaded Messages (43)

  2. servlet example[ Go to top ]

    Aren't servlets supposed to be thread safe (unless they implement some sort of marker interface)? The example servlet in part 3 (have a private Session attribute) is not thread safe.
  3. Re: servlet example[ Go to top ]

    Yea, Servlets are not thread safe. You shouldn't have any private data that relates to a specific request. It's really annoying.
  4. thought so[ Go to top ]

    I looked at the examples first and didn't waste time reading the article once I noticed such a basic flaw. Stuff like that throws the entire content into question.
  5. resource-ref ?[ Go to top ]

    Since when can you define a resource definition in context.xml and use it without referencing this resource in web.xml via resource-ref ? This is kinda new to me. Marc
  6. Hibernate docs is confusing..[ Go to top ]

    and dont even think about using it with Spring. In my last project i've pulled my hair with countless number of Lazy exceptions and went crazy trying out different combos of saveorupdate, update, lock, merge etc., Can Hibernate folks rename the commonly used methods to be a bit descriptive? http://www.intellibitz.com
  7. In my last project i've pulled my hair with countless number of Lazy exceptions and went crazy trying out different combos of saveorupdate, update, lock, merge etc., he he he agree with you 100% ;-) I think I need to add your point to my points why Springframework and Hibernate are the "Heavyweight Champions" in our Java frameworks world... More about this: http://lofidewanto.blogspot.com/2006/08/heavyweight-champions-are.html Cheers, Lofi.
  8. Lofi...
    I also know that Springframework 2.0 uses XML schema so the XML files are easier and shorter to create, but again, I hate creating XML files by hand and you?
    How does XML schema makes your files shorter or easier to create? XML Schema only give a structure and a more flexible constraint model for validating your XML documents.
    Do you know how many methods do we have in Hibernate just to persist or create a new object? What are these methods actually for: save, saveOrUpdate, persist, merge? Man, in SQL we just have one command: insert! Do we really need those different kind of methods just for a simple thing? Why can't we just say "save" and everything will be taken care by Hibernate?
    You forgot that in SQL there is also update, which is what saveOrUpdate is all about. It will upate the object if one already exists. Ilya
  9. How does XML schema makes your files shorter or easier to create? XML Schema only give a structure and a more flexible constraint model for validating your XML documents. I mean "... Spring XML configuration is now even easier, thanks to the advent of the new XML configuration syntax based on XML Schema ...". Not necessary shorter but it seems to be easier. See this: http://static.springframework.org/spring/docs/2.0-rc4/reference/new-in-2.html#new-in-2-ioc-configuration You forgot that in SQL there is also update, which is what saveOrUpdate is all about. It will upate the object if one already exists. Yes, I know "update" but I talked about "insert" and you can do this in different ways in Hibernate including "saveOrUpdate" which are confusing... Why don't we just have "save" and "update", that's it. If you read this JavaLobby thread: http://www.javalobby.org/java/forums/t78583.html ... it seems that I'm not alone with my opinions ;-) Cheers, Lofi.
  10. I think it's better to ignore this article and go to appfuse, look at how they use Spring, Hibernate and Struts (ignore DWR, Sitemesh .... first).
  11. Interesting code too Wouldn't this throw a nullpointer if no result is found ?
    Query q = session.createQuery("from Driver d where d.name = :name"); q.setString("name," name); Driver newOwner = (Driver) q.list().get(0); return newOwner;
    And handling excptions like this won't make it any easier to figure out what went wrong :)
    catch (Exception e) { session.getTransaction().rollback(); throw new ServletException();}
  12. lol[ Go to top ]

    tough crowd.
  13. Not a good article. Do not use a Session per operation. Ever. Do not show it to anybody. Do not use a complex Tomcat configuration just to refer to a JNDI datasource in your Hibernate configuration file. This will give you zero more portability than a Hibernate-managed connection pool. It will not be better. Read the Hibernate documentation and Wiki explanations if you want to know how getCurrentSession() really works. Finally, just read the Hibernate/Tomcat tutorial that is the first chapter of the Hibernate reference documentation: http://www.hibernate.org/hib_docs/v3/reference/en/html/tutorial.html More content, better and correct result, easier.
  14. I have just seen this in the last part of the article: "We have seen recommendations in the Hibernate literature that the scope of the open Hibernate Session be kept short - as limited as possible - as a first choice. We would rather make this recommendation in the strongest possible terms. By all means, open the Hibernate Session and begin the transaction, save whatever object instances you need to save, then commit the transaction, within a single method - as in the examples you have seen to this point in this article series. Be strongly inclined to consider any other approach unacceptable." This is absolute nonsense. I have no idea why I keep writing and explaining the exact opposite for more than 4 years... also, a Tranaction.commit() does not close the Hibernate Session if you opened it with openSession(). Can this article please be reviewed again?
  15. ...I keep writing and explaining the exact opposite for more than 4 years...
    Oh sorry dude, a misunderstanding for 4 years running.
  16. I have just seen this in the last part of the article:

    "We have seen recommendations in the Hibernate literature that the scope of the open Hibernate Session be kept short - as limited as possible - as a first choice. We would rather make this recommendation in the strongest possible terms. By all means, open the Hibernate Session and begin the transaction, save whatever object instances you need to save, then commit the transaction, within a single method - as in the examples you have seen to this point in this article series. Be strongly inclined to consider any other approach unacceptable."

    This is absolute nonsense. I have no idea why I keep writing and explaining the exact opposite for more than 4 years... also, a Tranaction.commit() does not close the Hibernate Session if you opened it with openSession().

    Can this article please be reviewed again?
    Christian, I don't wish to comment directly on the article as I haven't read it, but I'm a bit confused regarding your comments. Coz Hibernate in Action states on page 173: "Usually, your first choice should be to keep the Hibernate Session open no longer than a single database transaction (session-per-request)." Is this the preferred approach, or not. Thanks for any response.
  17. "Usually, your first choice should be to keep the Hibernate Session open no longer than a single database transaction (session-per-request)." Is this the preferred approach, or not. Thanks for any response.
    Yes. But session-per-operation is an anti-pattern, one of the most expensive mistakes you can make in a Hibernate persistence layer design. The Session in Hibernate is basically (besides the main API) a cache of managed instances and a queue of SQL DML filled and flushed by Hibernate. Even the name "session" should make it clear that it is not supposed to be used to execute just one operation. http://hibernate.org/42.html
  18. "Usually, your first choice should be to keep the Hibernate Session open no longer than a single database transaction (session-per-request)."
    Is this the preferred approach, or not. Thanks for any response.


    Yes. But session-per-operation is an anti-pattern, one of the most expensive mistakes you can make in a Hibernate persistence layer design. The Session in Hibernate is basically (besides the main API) a cache of managed instances and a queue of SQL DML filled and flushed by Hibernate. Even the name "session" should make it clear that it is not supposed to be used to execute just one operation.

    http://hibernate.org/42.html
    I thought I understood you until this post, but this seems a little unclear. You seem to be agreeing that "keep the Hibernate Session open no longer than a single database transaction" is the preferred approach. But then you say this is "an anti-pattern, one of the most expensive mistakes you can make in a Hibernate persistence layer design". How can "an expensive mistake" be "the preferred approach"? I'm confused, so I think I must be reading your post wrong. Maybe there's a distinction there between "operation" and "transaction" that I'm missing.
  19. session per request/operation[ Go to top ]

    I think what he means is: - session per HTTP request is good - session per operation (e.g. per method call) is nonsense
  20. Maybe there's a distinction there between "operation" and "transaction" that I'm missing.
    Uh, yes, they are not the same thing at all. A database operation is not a database transaction. Really, why make this more complex, it's totally simple. Do not design your application in a way that executes every Hibernate call/operation in a new Session. That's why it is named Session.
  21. Btw, this is all in the reference documentation: http://hibernate.org/hib_docs/v3/reference/en/html/transactions.html#transactions-basics-uow
  22. Re: Article: Hibernate 3.1 Used with Tomcat 5.5.x[ Go to top ]

    "Usually, your first choice should be to keep the Hibernate Session open no longer than a single database transaction (session-per-request)."
    Is this the preferred approach, or not. Thanks for any response.


    Yes. But session-per-operation is an anti-pattern, one of the most expensive mistakes you can make in a Hibernate persistence layer design. The Session in Hibernate is basically (besides the main API) a cache of managed instances and a queue of SQL DML filled and flushed by Hibernate. Even the name "session" should make it clear that it is not supposed to be used to execute just one operation.

    http://hibernate.org/42.html


    I thought I understood you until this post, but this seems a little unclear.

    You seem to be agreeing that "keep the Hibernate Session open no longer than a single database transaction" is the preferred approach. But then you say this is "an anti-pattern, one of the most expensive mistakes you can make in a Hibernate persistence layer design". How can "an expensive mistake" be "the preferred approach"?

    I'm confused, so I think I must be reading your post wrong. Maybe there's a distinction there between "operation" and "transaction" that I'm missing.
    Operation and transaction are two different things. A transaction can span multiple operations. A session per transactions, simple means keep the session open for the duration of your transaction. In webapp terms, this mostly means keeping a session open for the duration of the HTTP-Session. Within that session, you will have multiple operations that are demarcated as a single transaction. The transaction should be committed and/or rolled back at the end of the request and the session closed. Ilya
  23. Operation and transaction are two different things. A transaction can span multiple operations. A session per transactions, simple means keep the session open for the duration of your transaction. In webapp terms, this mostly means keeping a session open for the duration of the HTTP-Session. Within that session, you will have multiple operations that are demarcated as a single transaction. The transaction should be committed and/or rolled back at the end of the request and the session closed.
    OK, with available scopes, session scope for Hibernate session makes most sense, but is far then perfect. Hibernate session should span user transaction, or conversation, or process. Example 1: Editing an entity. First, entity is displayed in readonly mode on a page. User clicks edit and entity is displayed in editing mode with HTML fields. User edits the entity, producing zero or more page refreshes, AJAX roundrips etc... User finally clicks save button and readonly entity page appears with new entity value. All this shoud happen in one Hibernate Session. Example 2: Users creates complex entity using multi page wizard. After N pages, summary page with all entered attributes and collections apper asking user to validete his/her input. User confirms and flow control goes to another page. This is another conversation. Interesting thing is that when using Hibernate with JSF, one HTTP request can deal with 2 Hibernate sessions. This is when HTTP request causes that flow control goes from one conversation to the other. Then one session is used when reconstructing old page's JSF component tree, and the other is used when creating new page's JSF component tree. This is because new page belongs to new conversation.
  24. Operation and transaction are two different things. A transaction can span multiple operations. A session per transactions, simple means keep the session open for the duration of your transaction. In webapp terms, this mostly means keeping a session open for the duration of the HTTP-Session. Within that session, you will have multiple operations that are demarcated as a single transaction. The transaction should be committed and/or rolled back at the end of the request and the session closed.


    OK, with available scopes, session scope for Hibernate session makes most sense, but is far then perfect. Hibernate session should span user transaction, or conversation, or process.

    Example 1: Editing an entity. First, entity is displayed in readonly mode on a page. User clicks edit and entity is displayed in editing mode with HTML fields. User edits the entity, producing zero or more page refreshes, AJAX roundrips etc... User finally clicks save button and readonly entity page appears with new entity value. All this shoud happen in one Hibernate Session.

    Example 2: Users creates complex entity using multi page wizard. After N pages, summary page with all entered attributes and collections apper asking user to validete his/her input. User confirms and flow control goes to another page. This is another conversation.

    Interesting thing is that when using Hibernate with JSF, one HTTP request can deal with 2 Hibernate sessions. This is when HTTP request causes that flow control goes from one conversation to the other. Then one session is used when reconstructing old page's JSF component tree, and the other is used when creating new page's JSF component tree. This is because new page belongs to new conversation.
    I think alot of confusion is due to lack of understand of transactions by some folks. I think just reading some transaction resources (even the hibernate transaction docs), would exlain alot. Also, familiarity with Unit of Work pattern, defined clearly in Fowler's PEAA should read. One thing to remember is that the JDBC Connection is not thread safe, though why many use Hibernate Sessions as ThreadLocal objects, to ensure thread confinement. For conversational transactions, many issues can arrise. You can maintain the Session object throughout your stateful conversation, if you can guarantee that it's not accessed by multiple threads. If you have a multithreaded application, and multiple thread will participate in the same transaction, I believe you'd have to use non-JDBC transaction manager, since your transaction now spans multiple connection objects and Hibernate Sessions. It gets more complex, depending on your requirements. I think most people just write webapps where a transaction spans a single HTTP Request, therefore since the request is contained within the same thread, using ThreadLocal Session objects and/or maintaining the session object within a request object would do. Ilya
  25. woohoo, finally it came up[ Go to top ]

    I think most people just write webapps where a transaction spans a single HTTP Request, therefore since the request is contained within the same thread, using ThreadLocal Session objects and/or maintaining the session object within a request object would do.

    Ilya
    If someone is looking for a clear and simple way that will solve 90% of your requirements, this is the way to go. Don't try to make it more complicated unless absolutely necessary. This is what Spring's OpenSessionInView does by default. Or is for some reason you don't like Spring, store your session in thread local then close it via servlet filter at the end of a request. Look at available working examples and learn from it first, only after that should one try to improve and invent something new (otherwise, how would you know if your brilliant invention is actually an improvement from what is currently available).
  26. JTA bound sessions[ Go to top ]

    We have been using JTA bound sessions with getCurrentSession on the session factory and session factory configured to auto flush and close on transaction commit. Obviously, a JTA transaction in most cases span a user request. And it works like a dream :-) Meeraj
  27. Re: JTA bound sessions[ Go to top ]

    Sorry, to be clear, auto flush and close the session on transaction commit.
  28. "We have seen recommendations in the Hibernate literature that the scope of the open Hibernate Session be kept short - as limited as possible - as a first choice. We would rather make this recommendation in the strongest possible terms. By all means, open the Hibernate Session and begin the transaction, save whatever object instances you need to save, then commit the transaction, within a single method - as in the examples you have seen to this point in this article series. Be strongly inclined to consider any other approach unacceptable."

    This is absolute nonsense. I have no idea why I keep writing and explaining the exact opposite for more than 4 years...
    I agree. Hibernate Session should span user transaction at all means, except when there are ultra high scalability requirements.
  29. Hibernate Session should span user transaction at all means, except when there are ultra high scalability requirements.
    *sigh* Yes (assuming "user transaction" means conversation), and No. Session-per-operation, and what the authors recommend, will guarantee that your application never scales.
  30. Exactly... but looking at at the context of the article "operation" could mean doGet / doPost. The wording is really misleading. Doing Hibernate operation and HTML rendering inside a servlet is a very bad practice anyway and I think it is not good to promote that (even in simple example code) in an article in TSS.
  31. Hibernate 3.1 Used with Tomcat 5.5.x[ Go to top ]

    First I don't see exactly why not use Hibernate with Jetty :-)). I've read this post just to see what the hell has Hibernate to do with Tomcat 5.5 that it doesn't have with Jetty, or Geronimo or JBOSS. The answer is ... well ... Second, Hibernate is really hard to get right, at least for humans (Bears seem to handle their version of it very well). So before adivsing others how to do it, you should really make sure you've understood ALL stuff the Hibernate guys say in their tutorial, WIKI and Hibernate In Action. Then, check your content several times befor posting it because you can be sure that somewhere, somehow, you missused Hibernate :-D. And read some servlet spec also. Any version.
  32. Re: Hibernate 3.1 Used with Tomcat 5.5.x[ Go to top ]

    And BTW. I thought that after all these years WE've ALL agreed that this is TOTALLY WRONG especially when teaching others ?! Because they can get the impression that this could actually be fine ? out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"); out.println(""); out.println(" A Servlet Which Accesses JNDI"); out.println(" ");
  33. no offense but...[ Go to top ]

    ...tss should really pull this article. or rework it into a "what not to do" article.
  34. This is what happens....[ Go to top ]

    ...when you mindlessly post crap just to see if you can spawn a discussion - Regina go home.
  35. I am happy this is not printed on paper, poor trees! Tss should double check what is published.
  36. From the authors ... It’s pretty funny to read comments about an article from people who in quite a few cases haven’t read it. We heard about the same experience from book authors or movie directors – often on a political or a religious subject – who found their works criticized from a theoretical perspective by people who hadn’t read the book or seen the movie. It must be human nature. There are also many comments from people who have myriad different environments. This article is aimed specifically at the environment referenced in the title: Hibernate 3.1 Used with Tomcat 5.5. We have experienced a real problem in this environment which we wanted to advise developers about. The problem can arise if any ThreadLocal – for instance the built-in Hibernate 3.1 ThreadLocal – is used with the Tomcat thread pooling mechanism. The two mechanisms conflict. A Hibernate session saved in a ThreadLocal can become exposed to unrelated business transactions which happen to capture the thread next, in a subsequent Http request. Are any or many of you currently using this pair of technologies together? (We think there are still many Tomcat 5.0 users, and many Hibernate 3.0 users.) If you are, how do you avoid the conflict if you allow your Hibernate session to span multiple Http requests (and multiple Tomcat threads)? Note the problem described in this article can occur only with getCurrentSession( ) – which makes use of the ThreadLocal. It cannot occur with openSession( ), which makes no ongoing use of a Hibernate session opened in a previous Http request. This behavior is readily testable. Setup a Tomcat 5.5 environment allowing only a small number of concurrent threads – say 3 or 4. Create a couple of distinct, simplistic business transactions which span Http requests. Attempt to preserve information – any information – it doesn’t need to have anything to do with Hibernate – and do some tracing/logging in which you display the thread ID. You will see Tomcat thread pooling eventually recycle thread IDs to another business transaction, allowing inappropriate access to the ThreadLocal contents to take place. The Hibernate Version 3.0.x Reference Documentation began with a very nice Chapter 1, entitled “Quickstart with Tomcat”. This Tomcat-specific chapter is unfortunately no longer present in the Hibernate Version 3.1.x Reference Documentation, but was at the time a great help for new Tomcat/Hibernate programmers. The version of Tomcat it was concerned with was Tomcat 4.1. It contains a very important statement (on page 7) which is as important now for Tomcat users as it was then: “Note that you may call HibernateUtil.currentSession() as many times as you like, you will always get the current Session of this thread. You have to make sure the Session is closed after your unit-of-work completes, either in your servlet code or in a servlet filter before the HTTP response is sent.” We feel that chapter should be updated to reflect Tomcat 5.5 and Hibernate 3.1, and reinstated in the Reference Documentation. Those of you who understand servlet filters will understand the point made in the passage we have quoted. Likewise, those of you who understand the ThreadLocal mechanism will see the problem with multi-Http request transactions in a thread pooling environment. Bill Treuman and Igor Dayen
  37. It’s pretty funny to read comments about an article from people who in quite a few cases haven’t read it.
    Real fun, yeah.
    The problem can arise if any ThreadLocal – for instance the built-in Hibernate 3.1 ThreadLocal – is used with the Tomcat thread pooling mechanism. The two mechanisms conflict. A Hibernate session saved in a ThreadLocal can become exposed to unrelated business transactions which happen to capture the thread next, in a subsequent Http request.
    This can not happen if your code is correct. (I'm too lazy now to explain all the exceptions where this can actually happen, suffice it to say that they are all quite serious programming errors, like starting a transaction and never committing it.) What _is_ broken is the code in your article and you will definitely get Hibernate Sessions leaking into different threads/requests. Others have already mentioned that the Session in member variable in a servlet is not safe at all. This error has nothing to do with Hibernate, you just wrote a servlet that is not thread-safe. This has nothing to do with the built-in thread-local Session handling of Hibernate, or even any thread-local variables.
    Are any or many of you currently using this pair of technologies together? (We think there are still many Tomcat 5.0 users, and many Hibernate 3.0 users.) If you are, how do you avoid the conflict if you allow your Hibernate session to span multiple Http requests (and multiple Tomcat threads)?
    I bet thousands of people use this combination without any problems. They will have a problem if they would take the code you wrote (or believe what you recommend about session scope, etc).
    This Tomcat-specific chapter is unfortunately no longer present in the Hibernate Version 3.1.x Reference Documentation, but was at the time a great help for new Tomcat/Hibernate programmers.
    This chapter has been rewritten and been replaced with a better tutorial. Which actually has code that works with no elaborate extra configuration in Tomcat (the DBCP pooling there is really not very useful). The code is even included in the package so you could compare it to yours and see where it is different. In the rest of your posting it looks like you want to say that (in Tomcat) a servlet filter (which does the cleanup of the thread-local) actually runs in a different thread than the servlet (which uses the thread-local). First, it should be obvious that filters are not the issue here, they haven't been mentioned at all. Secondly, in Tomcat, a servlet filter executes in the same thread as the servlet, one thread per request. This was confirmed just now by a colleague of mine, who is a developer working on Tomcat. It would be great if you could get TSS to remove the article so that you can correct the code.
  38. Another thought: Could it be that you don't know that the scope of a value in a thread-local variable is a single request? I'm guessing here, but from what you wrote it sounds like you have tried to store something in a thread-local and expected it to be there for several requests. And then came the thread pool etc...
  39. must be joke[ Go to top ]

    you're kidding right? is this some sort of joke? is it april first and I missed something? where are the tss editors that allow such crap to be "promoted" as a "solution"??? my suggestion: delete your jdk and install vb... it was made for you
  40. Actually[ Go to top ]

    I find this kind of discussion invaluable. You have to wonder if these stacks are designed for the average programmer or not. People brave enough to post articles and bring out discussion in this kind of forum are the ones who allow them to get better, because the documentation is never perfect and everyone makes mistakes. Sure, they must correct errors, but it's the rude people who shoot conversation down without anything positive to say that make this exercise unpleasant.
  41. my disgust...[ Go to top ]

    ...comes from the perspective of having to interview developers for positions that claim they have experience with "X" (and in reality are clueless) the authors of this article unfortunately fit the category. several other posts in this discussion have asked with this misleading "article" is posted as a "how-to" on tss. i'm only sorry that i had to be "rude" to draw out an actual response. i don't disagree that the discussion has been valuable but that does not negate the responsiblity of tss for promoting misleading materials.
  42. what a lovely day[ Go to top ]

    what a lovely day reading this thread...
  43. Must disagree with some people[ Go to top ]

    I must disagree with some people people's post that the datasources shouldn't be entered in the context.xml file (I'm assuming that the context.xml files are deployed in the conf directory, not embedded in the war's META-INF/context.xml). Alot of organizations out there have an admin team that maintain the runtime servers (ie. tomcat, jboss, websphere and etc). The same people also maintains the database servers and etc. They should be able to move and re-point the datasources somewhere else in a consistent manner (in this case, they know that they have to modify the context.xml file, and not go mucking around in the source repository then try to change the hibernate.cfg.xml, or the applicationContext.xml file, then rebuild the war to redeploy). The hibernate.cfg.xml, or the applicationContext.xml is then configured to point the the JNDI datasource.
  44. What are the recommended best practices if I were to use Hibernate for real-time (e.g:-financial) applications? Speed is of essence..so would one choose to use stored procs or the ordinary servlet-->to db via dao code?