Class 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 Detail

      • HibernateDBConnection

        public HibernateDBConnection()
    • Method Detail

      • 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.
      • 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.
      • 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.