It should be closed when you're done with (but this can be done automatically for you as we'll see).
It all depends on how you obtain the session.
if you use sessionFactory.getCurrentSession(), you'll obtain a "current session" which is bound to the lifecycle of the transaction and will be automatically flushed and closed when the transaction ends (commit or rollback).
If you decide to use sessionFactory.openSession(), you'll have to manage the session yourself and to flush and close it "manually".
For more info you can check http://docs.jboss.org/hibernate/core/3.3/reference/en/html/transactions.html#transactions-basics-apptx
Well, an edit for you:
SessionFactory.openSession() always opens a new session that you have to close once you are done with the operations. SessionFactory.getCurrentSession() returns a session bound to a context - you don't need to close this.
Edit2
hibernate.current_session_context_class to thread and then implement something like a servlet filter that opens the session - then you can access that session anywhere else by using the SessionFactory.getCurrentSession().
SessionFactory.openSession() always opens a new session that you have to close once you are done with the operations. SessionFactory.getCurrentSession() returns a session bound to a context - you don't need to close this.
If you are using Spring or EJBs to manage transactions you can configure them to open / close sessions along with the transactions.
You should never use one session per web app - session is not a thread safe object - cannot be shared by multiple threads. You should always use "one session per request" or "one session per transaction"