improve doc for CurrentSessionContext

This commit is contained in:
Gavin 2022-12-27 18:31:25 +01:00 committed by Gavin King
parent f7a4343a33
commit 6c3131b981
4 changed files with 63 additions and 24 deletions

View File

@ -78,9 +78,6 @@ import jakarta.persistence.criteria.CriteriaUpdate;
* However, for processes which read many entities, a {@link StatelessSession} should
* be used.
* <p>
* A {@code Session} is never threadsafe. Each thread or transaction must obtain its own
* instance from a {@link SessionFactory}.
* <p>
* A session might be associated with a container-managed JTA transaction, or it might be
* in control of its own <em>resource-local</em> database transaction. In the case of a
* resource-local transaction, the client must demarcate the beginning and end of the
@ -104,9 +101,17 @@ import jakarta.persistence.criteria.CriteriaUpdate;
* }
* </pre>
* <p>
* If the {@code Session} throws an exception, the current transaction must be rolled back
* and the session must be discarded. The internal state of the {@code Session} might not
* be consistent with the database after the exception occurs.
* It's crucially important to appreciate the following restrictions and why they exist:
* <ul>
* <li>If the {@code Session} throws an exception, the current transaction must be rolled
* back and the session must be discarded. The internal state of the {@code Session}
* cannot be expected to be consistent with the database after the exception occurs.
* <li>At the end of a logical transaction, the session must be explicitly {@linkplain
* #close() destroyed}, so that all JDBC resources may be released.
* <li>A {@code Session} is never thread-safe. It contains various different sorts of
* fragile mutable state. Each thread or transaction must obtain its own dedicated
* instance from the {@link SessionFactory}.
* </ul>
* <p>
* A {@code Session} instance is serializable if its entities are serializable.
* <p>

View File

@ -35,13 +35,19 @@ import jakarta.persistence.EntityManagerFactory;
* Crucially, this is where a program comes to obtain {@linkplain Session sessions}.
* Typically, a program has a single {@link SessionFactory} instance, and must
* obtain a new {@link Session} instance from the factory each time it services
* a client request.
* a client request. It is then also responsible for {@linkplain Session#close()
* destroying} the session at the end of the client request.
* <p>
* The {@link #inSession} and {@link #inTransaction} methods provide a convenient
* way to obtain a session, with or without starting a transaction, and have it
* cleaned up automatically, relieving the program of the need to explicitly
* call {@link Session#close()} and {@link Transaction#commit()}.
* <p>
* Alternatively, {@link #getCurrentSession()} provides support for the notion
* of contextually-scoped sessions, where an implementation of the SPI interface
* {@link org.hibernate.context.spi.CurrentSessionContext} is responsible for
* creating, scoping, and destroying sessions.
* <p>
* Depending on how Hibernate is configured, the {@code SessionFactory} itself
* might be responsible for the lifecycle of pooled JDBC connections and
* transactions, or it may simply act as a client for a connection pool or
@ -138,9 +144,9 @@ public interface SessionFactory extends EntityManagerFactory, Referenceable, Ser
/**
* Obtains the <em>current session</em>, an instance of {@link Session}
* implicitly associated with some context. For example, the session
* might be associated with the current thread, or with the current
* JTA transaction.
* implicitly associated with some context or scope. For example, the
* session might be associated with the current thread, or with the
* current JTA transaction.
* <p>
* The context used for scoping the current session (that is, the
* definition of what precisely "current" means here) is determined
@ -150,12 +156,16 @@ public interface SessionFactory extends EntityManagerFactory, Referenceable, Ser
* {@value org.hibernate.cfg.AvailableSettings#CURRENT_SESSION_CONTEXT_CLASS}.
* <p>
* If no {@link org.hibernate.context.spi.CurrentSessionContext} is
* explicitly configured, but JTA is configured, then
* {@link org.hibernate.context.internal.JTASessionContext} is used.
* explicitly configured, but JTA support is enabled, then
* {@link org.hibernate.context.internal.JTASessionContext} is used,
* and the current session is scoped to the active JTA transaction.
*
* @return The current session.
*
* @throws HibernateException Indicates an issue locating a suitable current session.
*
* @see org.hibernate.context.spi.CurrentSessionContext
* @see org.hibernate.cfg.AvailableSettings#CURRENT_SESSION_CONTEXT_CLASS
*/
Session getCurrentSession() throws HibernateException;

View File

@ -1118,13 +1118,18 @@ public interface AvailableSettings {
/**
* Specifies a {@link org.hibernate.context.spi.CurrentSessionContext} for
* scoping the {@linkplain org.hibernate.SessionFactory#getCurrentSession()
* current session}, either:<ul>
* current session}, either:
* <ul>
* <li>{@code jta}, {@code thread}, or {@code managed}, or
* <li>the name of a class implementing
* {@code org.hibernate.context.spi.CurrentSessionContext}.
* </ul>
* If this property is not set, but JTA support is enabled, then
* {@link org.hibernate.context.internal.JTASessionContext} is used
* by default.
*
* @see org.hibernate.SessionFactory#getCurrentSession()
* @see org.hibernate.context.spi.CurrentSessionContext
*/
String CURRENT_SESSION_CONTEXT_CLASS = "hibernate.current_session_context_class";

View File

@ -12,22 +12,41 @@ import org.hibernate.HibernateException;
import org.hibernate.Session;
/**
* Defines the contract for implementations which know how to scope the notion
* of a {@link org.hibernate.SessionFactory#getCurrentSession() current session}.
* Defines the contract for objects which are able to manage the lifecycle
* of a {@link Session} associated with a well-defined "context" or "scope",
* providing the concrete implementation behind the notion of the
* {@linkplain org.hibernate.SessionFactory#getCurrentSession() current session}.
* <p>
* Implementations should adhere to the following:
* The lifecycle of the context/scope is not specified by Hibernate, and
* varies depending on the nature of the program. The only hard restriction
* is that the scope must be single-threaded. On the other hand, since state
* tends to build up in the first-level cache of session, sessions should
* typically not be associated with long-lived scopes.
* <p>
* The most typical example of s scope with which a current session might
* be associated is the HTTP request context in a web application.
* <p>
* An implementation of this interface must:
* <ul>
* <li>contain a constructor accepting a single argument of type
* {@link org.hibernate.engine.spi.SessionFactoryImplementor}
* <li>should be thread safe
* <li>should be fully serializable
* <li>have a constructor accepting a single argument of type
* {@link org.hibernate.engine.spi.SessionFactoryImplementor},
* <li>be thread-safe,
* <li>be fully serializable,
* <li>guarantee that it {@link Session#close() destroys} every session it
* creates, and
* <li>ensure that each session it creates is the exclusive property of a
* single thread, since sessions contain fragile mutable state and are
* <em>never</em> considered thread-safe.
* </ul>
* <p>
* Implementors should be aware that they are also fully responsible for
* cleanup of any generated current-sessions.
* Every {@linkplain org.hibernate.SessionFactory session factory} has
* exactly one instance of this interface.
* <p>
* Note that there will be exactly one instance of the configured
* CurrentSessionContext implementation per {@link org.hibernate.SessionFactory}.
* An implementation may be selected by setting the configuration property
* {@value org.hibernate.cfg.AvailableSettings#CURRENT_SESSION_CONTEXT_CLASS}.
*
* @see org.hibernate.SessionFactory#getCurrentSession()
* @see org.hibernate.cfg.AvailableSettings#CURRENT_SESSION_CONTEXT_CLASS
*
* @author Steve Ebersole
*/