Class HibernateDBConnection

java.lang.Object
org.dspace.core.HibernateDBConnection
All Implemented Interfaces:
DBConnection<org.hibernate.Session>

public class HibernateDBConnection extends Object implements DBConnection<org.hibernate.Session>
Hibernate implementation of the DBConnection.

NOTE: This class does NOT represent a single Hibernate database connection. Instead, it wraps Hibernate's Session object to obtain access to a database connection in order to execute one or more transactions.

Per DSpace's current Hibernate configuration ([dspace]/config/core-hibernate.xml), we use the one-session-per-thread approach (ThreadLocalSessionContext). This means that Hibernate creates a single Session per thread (request), at the time when getCurrentSession() is first called.

This Session may be reused for multiple Transactions, but if commit() is called, any objects (Entities) in the Session become disconnected and MUST be reloaded into the Session (see reloadEntity() method below).

If an Error occurs, the Session itself is invalidated. No further Transactions can be run on that Session.

DSpace generally follows the "Session-per-request" transactional pattern described here: https://docs.jboss.org/hibernate/orm/5.0/userguide/en-US/html/ch06.html#session-per-request

Author:
kevinvandevelde at atmire.com
  • Constructor Details

    • HibernateDBConnection

      public HibernateDBConnection()
  • Method Details

    • getSession

      public org.hibernate.Session getSession() throws SQLException
      Retrieves the current Session from Hibernate (per our settings, Hibernate is configured to create one Session per thread). If Session doesn't yet exist, it is created. A Transaction is also initialized (or reinintialized) in the Session if one doesn't exist, or was previously closed (e.g. if commit() was previously called)
      Specified by:
      getSession in interface DBConnection<org.hibernate.Session>
      Returns:
      Hibernate current Session object
      Throws:
      SQLException
    • isTransActionAlive

      public boolean isTransActionAlive()
      Check if the connection has a currently active Transaction. A Transaction is active if it has not yet been either committed or rolled back.
      Specified by:
      isTransActionAlive in interface DBConnection<org.hibernate.Session>
      Returns:
    • getTransaction

      protected org.hibernate.Transaction getTransaction()
      Retrieve the current Hibernate Transaction object from our Hibernate Session.
      Returns:
      current Transaction (may be active or inactive) or null
    • isSessionAlive

      public boolean isSessionAlive()
      Check if Hibernate Session is still "alive" / open. An open Session may or may not have an open Transaction (so isTransactionAlive() may return false even if isSessionAlive() returns true). A Session may be reused for multiple transactions (e.g. if commit() is called, the Session remains alive while the Transaction is closed)
      Specified by:
      isSessionAlive in interface DBConnection<org.hibernate.Session>
      Returns:
      true if Session is alive, false otherwise
    • rollback

      public void rollback() throws SQLException
      Rollback any changes applied to the current Transaction. This also closes the Transaction. A new Transaction may be opened the next time getSession() is called.
      Specified by:
      rollback in interface DBConnection<org.hibernate.Session>
      Throws:
      SQLException
    • closeDBConnection

      public void closeDBConnection() throws SQLException
      Close our current Database connection. This also closes & unbinds the Hibernate Session from our thread.

      NOTE: Because DSpace configures Hibernate to automatically create a Session per thread, a Session may still exist after this method is called (as Hibernate may automatically create a new Session for the current thread). However, Hibernate will automatically clean up any existing Session when the thread closes.

      Specified by:
      closeDBConnection in interface DBConnection<org.hibernate.Session>
      Throws:
      SQLException
    • commit

      public void commit() throws SQLException
      Commits any current changes cached in the Hibernate Session to the database & closes the Transaction. To open a new Transaction, you may call getSession().

      WARNING: When commit() is called, while the Session is still "alive", all previously loaded objects (entities) become disconnected from the Session. Therefore, if you continue to use the Session, you MUST reload any needed objects (entities) using reloadEntity() method.

      Specified by:
      commit in interface DBConnection<org.hibernate.Session>
      Throws:
      SQLException
    • shutdown

      public void shutdown()
      Description copied from interface: DBConnection
      Close all sessions. Release all associated resources (cache, DBMS connections, etc.) To be used only when exiting the application.
      Specified by:
      shutdown in interface DBConnection<org.hibernate.Session>
    • getType

      public String getType()
      Description copied from interface: DBConnection
      Some description of the DBMS used to persist entities.
      Specified by:
      getType in interface DBConnection<org.hibernate.Session>
      Returns:
      Brand, version, dialect, etc. Implementation specific.
    • getDataSource

      public DataSource getDataSource()
      Description copied from interface: DBConnection
      The JDBC DataSource used by this session. Think carefully before using.
      Specified by:
      getDataSource in interface DBConnection<org.hibernate.Session>
      Returns:
      the source of DBMS connections.
    • getDatabaseConfig

      public DatabaseConfigVO getDatabaseConfig() throws SQLException
      Description copied from interface: DBConnection
      Identify certain characteristics of the DBMS being used to support persistence.
      Specified by:
      getDatabaseConfig in interface DBConnection<org.hibernate.Session>
      Returns:
      a collection of DBMS, database and connection information.
      Throws:
      SQLException - passed through.
    • getCacheSize

      public long getCacheSize() throws SQLException
      Description copied from interface: DBConnection
      How many entities are cached in this session?
      Specified by:
      getCacheSize in interface DBConnection<org.hibernate.Session>
      Returns:
      number of cached entities.
      Throws:
      SQLException - passed through.
    • reloadEntity

      public <E extends ReloadableEntity> E reloadEntity(E entity) throws SQLException
      Reload an entity into the Hibernate cache. This can be called after a call to commit() to re-cache an object in the Hibernate Session (see commit()). Failing to reload objects into the cache may result in a Hibernate throwing a "LazyInitializationException" if you attempt to use an object that has been disconnected from the Session cache.
      Specified by:
      reloadEntity in interface DBConnection<org.hibernate.Session>
      Type Parameters:
      E - The class of the entity. The entity must implement the ReloadableEntity interface.
      Parameters:
      entity - The DSpace object to reload
      Returns:
      the newly cached object.
      Throws:
      SQLException
    • setConnectionMode

      public void setConnectionMode(boolean batchOptimized, boolean readOnlyOptimized) throws SQLException
      Description copied from interface: DBConnection
      Configure the connection for special uses.
      Specified by:
      setConnectionMode in interface DBConnection<org.hibernate.Session>
      Parameters:
      batchOptimized - if true, optimize for batch use. Typically this means suppressing automatic flushing of updates, thus requiring manual flushing at appropriate points in the process.
      readOnlyOptimized - if true, optimize for read-only use. Typically this suppresses all updating.
      Throws:
      SQLException
    • isOptimizedForBatchProcessing

      public boolean isOptimizedForBatchProcessing()
      Description copied from interface: DBConnection
      Has this session been configured for large batches? Typically this means that automatic flushing of updates to the database is suppressed, and thus one must take care to flush manually (or commit) at appropriate times.
      Specified by:
      isOptimizedForBatchProcessing in interface DBConnection<org.hibernate.Session>
      Returns:
      true if configured for batch.
    • uncacheEntities

      public void uncacheEntities() throws SQLException
      Description copied from interface: DBConnection
      Remove all entities from the session cache.

      Entities removed from cache are not saved in any way. Therefore, if you have modified any entities, you should be sure to DBConnection.commit() changes before calling this method.

      Specified by:
      uncacheEntities in interface DBConnection<org.hibernate.Session>
      Throws:
      SQLException - passed through.
    • uncacheEntity

      public <E extends ReloadableEntity> void uncacheEntity(E entity) throws SQLException
      Evict an entity from the hibernate cache.

      When an entity is evicted, it frees up the memory used by that entity in the cache. This is often necessary when batch processing a large number of objects (to avoid out-of-memory exceptions).

      Specified by:
      uncacheEntity in interface DBConnection<org.hibernate.Session>
      Type Parameters:
      E - The class of the entity. The entity must implement the ReloadableEntity interface.
      Parameters:
      entity - The entity to evict
      Throws:
      SQLException - When reloading the entity from the database fails.
    • flushSession

      public void flushSession() throws SQLException
      Do a manual flush. This synchronizes the in-memory state of the Session with the database (write changes to the database)
      Specified by:
      flushSession in interface DBConnection<org.hibernate.Session>
      Throws:
      SQLException - passed through.