Table of Contents

Working with Sessions

Overview of the Facets Systems

This section deals with the details of storing objects. Before we can show some code samples of how to persist an object, we have to cover some ground regarding the need for and use of sessions.

What is a session ?

A session (like everything else in Facets) is an object. The session object maintains a relationship between a thread, the Facets Repository, and the objects in use by the current transaction. We will discuss the nature and use of transactions a little later in this module, but at this point it is sufficient to bear in mind the fact that the session contains a reference to the current transaction.

Sessions in a Java VM are centrally managed by an instance of a SessionFactory. A SessionFactory is responsible for creating, managing and pooling all created sessions. The SessionFactory will only create a new session if there is not one available to use or if told do so directly. Later on in this section we will see that it is beneficial to retrieve a session, use it, and then return it to the SessionFactory so that it can be re-used by another thread.

The basic 8 step interaction when working with sessions and transactions is shown in the diagram below

Sessions and Threads

Since all but the smallest of Java applications make use of threads, it is important to consider how sessions interact with threads. When a session is created or retrieved by the SessionFactory, it is "attached" to the thread that requested it. This is necessary since the objects that are retrieved from the repository have to be noted by the session so that they can be managed transactionally. While it is possible to manage the linking of the sessions manually (and there are the appropriate methods on the GsSession class for doing this) it is better left to Facets to handle this. Always ensure that you only use the objects retrieved within a thread, within that same thread. In other words do not attempt to transfer objects between threads unless you use a special thread independent mechanism for doing so (use an ExportableSharedObjRef, whose use is discussed in module 10, Caching Persistent Objects for Later Use).

Getting a Session

A SessionFactory is used to create and manage sessions. Before we can create a session we have to create a SessionFactory. There can only be one SessionFactory per VM since a SessionFactory has the responsibility of guarding the use of sessions in that VM. We therefore create a SessionFactory by asking the SessionFactory class to either create a SessionFactory if there is not one already around or to return the singleton instance. Once we have the instance we can then create a session, the following method illustrates the point:

public void performSomeOperation()
{
    SessionFactory sessionFactory;
    GsSession session = null;
    try {
        sessionFactory = SessionFactory.getSessionFactory();		
    } catch (Exception ex) {
        System.err.println("unable to get session factory");
        return;		
    }
    try {
        session = sessionFactory.getSession();
        // do stuff inside a session
    } catch (Exception ex) {
        System.err.println("unable to create session");
        return;		
    } finally {	
        if (session != null) {
            session.close();	
        }
    }
}

What is important to note in the above code snippet is that the code that uses the session is bracketed in a try-catch-finally clause. As we mentioned above, sessions are system resources and it is important that they are not lost. If we are finished using a session, it is vital that the SessionFactory be informed that we no longer have a use for it. We do this by invoking the close method on the session. This tells the GsSession and the SessionFactory that the current thread is finished using the session, and that either the resources it is using can be released, or that they can be re-used. By bracketing this code with the finally, we ensure that no matter what happens, the session is released.

The use of the try-catch-finally clause is one that we will use repeatedly when coding. It is a very useful mechanism, since it allows us to selectively catch exceptions that are of importance to use, but also to have a catchall mechanism that will ensure that no matter what happens, a certain piece of code is executed. It is worth remembering that there can be a number of catch statements before the finally clause. This is useful when a section of protected code can raise a number of different exceptions.

©2005 GemStone Systems, Inc.