Example usage for org.hibernate FlushMode AUTO

List of usage examples for org.hibernate FlushMode AUTO

Introduction

In this page you can find the example usage for org.hibernate FlushMode AUTO.

Prototype

FlushMode AUTO

To view the source code for org.hibernate FlushMode AUTO.

Click Source Link

Document

The Session is sometimes flushed before query execution in order to ensure that queries never return stale state.

Usage

From source file:org.springframework.orm.hibernate4.HibernateTransactionManagerTests.java

License:Apache License

@Test
public void testTransactionWithPropagationSupportsAndInnerTransaction() throws Exception {
    final SessionFactory sf = mock(SessionFactory.class);
    final ImplementingSession session1 = mock(ImplementingSession.class);
    final ImplementingSession session2 = mock(ImplementingSession.class);
    Connection con = mock(Connection.class);
    Transaction tx = mock(Transaction.class);

    given(sf.openSession()).willReturn(session1, session2);
    given(session1.getSessionFactory()).willReturn(sf);
    given(session1.getFlushMode()).willReturn(FlushMode.AUTO);
    given(session2.beginTransaction()).willReturn(tx);
    given(session2.connection()).willReturn(con);
    given(session2.getFlushMode()).willReturn(FlushMode.AUTO);
    given(session2.isOpen()).willReturn(true);
    given(session2.isConnected()).willReturn(true);

    LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean() {
        @Override//from  w  w w.j a  v  a  2  s .c  o m
        protected SessionFactory buildSessionFactory(LocalSessionFactoryBuilder sfb) {
            return sf;
        }
    };
    lsfb.afterPropertiesSet();
    final SessionFactory sfProxy = lsfb.getObject();

    PlatformTransactionManager tm = new HibernateTransactionManager(sfProxy);
    TransactionTemplate tt = new TransactionTemplate(tm);
    tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS);
    final TransactionTemplate tt2 = new TransactionTemplate(tm);
    tt2.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

    assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf));
    tt.execute(new TransactionCallback() {
        @Override
        public Object doInTransaction(TransactionStatus status) {
            assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sfProxy));
            assertTrue("Is not new transaction", !status.isNewTransaction());
            assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
            assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
            Session session = sfProxy.openSession();
            assertSame(session1, session);
            tt2.execute(new TransactionCallback() {
                @Override
                public Object doInTransaction(TransactionStatus status) {
                    assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
                    assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
                    Session session = ((SessionHolder) TransactionSynchronizationManager.getResource(sf))
                            .getSession();
                    assertSame(session2, session);
                    session.flush();
                    return null;
                }
            });
            session.flush();
            session.close();
            assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
            assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
            return null;
        }
    });
    assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf));

    verify(session1).flush();
    verify(session1).close();
    verify(session2).flush();
    verify(session2).close();
    verify(tx).commit();
}

From source file:org.springframework.orm.hibernate4.HibernateTransactionManagerTests.java

License:Apache License

@Test
public void testTransactionCommitWithPreBound() throws Exception {
    final DataSource ds = mock(DataSource.class);
    Connection con = mock(Connection.class);
    final SessionFactory sf = mock(SessionFactory.class);
    final ImplementingSession session = mock(ImplementingSession.class);
    Transaction tx = mock(Transaction.class);

    given(session.beginTransaction()).willReturn(tx);
    given(session.isOpen()).willReturn(true);
    given(session.getFlushMode()).willReturn(FlushMode.MANUAL);
    given(session.connection()).willReturn(con);
    given(con.getTransactionIsolation()).willReturn(Connection.TRANSACTION_READ_COMMITTED);
    given(session.isConnected()).willReturn(true);

    HibernateTransactionManager tm = new HibernateTransactionManager();
    tm.setSessionFactory(sf);/*from   w w w  . j  a  v a 2  s.  c om*/
    tm.setDataSource(ds);
    TransactionTemplate tt = new TransactionTemplate(tm);
    tt.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);
    final List l = new ArrayList();
    l.add("test");
    assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds));
    assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive());
    TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session));
    assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));

    Object result = tt.execute(new TransactionCallback() {
        @Override
        public Object doInTransaction(TransactionStatus status) {
            assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));
            assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds));
            SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sf);
            assertTrue("Has thread transaction", sessionHolder.getTransaction() != null);
            Session sess = ((SessionHolder) TransactionSynchronizationManager.getResource(sf)).getSession();
            assertEquals(session, sess);
            return l;
        }
    });
    assertTrue("Correct result list", result == l);

    assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));
    SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sf);
    assertTrue("Hasn't thread transaction", sessionHolder.getTransaction() == null);
    TransactionSynchronizationManager.unbindResource(sf);
    assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds));
    assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive());

    InOrder ordered = inOrder(session, con);
    ordered.verify(con).setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
    ordered.verify(session).setFlushMode(FlushMode.AUTO);
    ordered.verify(con).setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
    ordered.verify(session).setFlushMode(FlushMode.MANUAL);
    verify(tx).commit();
    verify(session).disconnect();
}

From source file:org.springframework.orm.hibernate4.HibernateTransactionManagerTests.java

License:Apache License

@Test
public void testTransactionCommitWithPreBoundAndResultAccessAfterCommit() throws Exception {
    final DataSource ds = mock(DataSource.class);
    Connection con = mock(Connection.class);
    final SessionFactory sf = mock(SessionFactory.class);
    final ImplementingSession session = mock(ImplementingSession.class);
    Transaction tx = mock(Transaction.class);

    given(session.beginTransaction()).willReturn(tx);
    given(session.isOpen()).willReturn(true);
    given(session.getFlushMode()).willReturn(FlushMode.MANUAL);
    given(session.connection()).willReturn(con);
    given(con.getTransactionIsolation()).willReturn(Connection.TRANSACTION_READ_COMMITTED);
    given(con.getHoldability()).willReturn(ResultSet.CLOSE_CURSORS_AT_COMMIT);
    given(session.isConnected()).willReturn(true);

    HibernateTransactionManager tm = new HibernateTransactionManager();
    tm.setSessionFactory(sf);//from   www.  j  av  a 2 s  .c  o m
    tm.setDataSource(ds);
    tm.setAllowResultAccessAfterCompletion(true);
    TransactionTemplate tt = new TransactionTemplate(tm);
    tt.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);
    final List l = new ArrayList();
    l.add("test");
    assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds));
    assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive());
    TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session));
    assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));

    Object result = tt.execute(new TransactionCallback() {
        @Override
        public Object doInTransaction(TransactionStatus status) {
            assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));
            assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds));
            SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sf);
            assertTrue("Has thread transaction", sessionHolder.getTransaction() != null);
            Session sess = ((SessionHolder) TransactionSynchronizationManager.getResource(sf)).getSession();
            assertEquals(session, sess);
            return l;
        }
    });
    assertTrue("Correct result list", result == l);

    assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));
    SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sf);
    assertTrue("Hasn't thread transaction", sessionHolder.getTransaction() == null);
    TransactionSynchronizationManager.unbindResource(sf);
    assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds));
    assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive());

    InOrder ordered = inOrder(session, con);
    ordered.verify(con).setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
    ordered.verify(con).setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);
    ordered.verify(session).setFlushMode(FlushMode.AUTO);
    ordered.verify(con).setHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT);
    ordered.verify(con).setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
    ordered.verify(session).setFlushMode(FlushMode.MANUAL);
    verify(tx).commit();
}

From source file:org.springframework.orm.hibernate4.HibernateTransactionManagerTests.java

License:Apache License

@Test
public void testTransactionRollbackWithPreBound() throws Exception {
    final DataSource ds = mock(DataSource.class);
    Connection con = mock(Connection.class);
    final SessionFactory sf = mock(SessionFactory.class);
    final ImplementingSession session = mock(ImplementingSession.class);
    final Transaction tx1 = mock(Transaction.class);
    final Transaction tx2 = mock(Transaction.class);

    given(session.beginTransaction()).willReturn(tx1, tx2);
    given(session.isOpen()).willReturn(true);
    given(session.getFlushMode()).willReturn(FlushMode.MANUAL);
    given(session.isConnected()).willReturn(true);
    given(session.connection()).willReturn(con);

    HibernateTransactionManager tm = new HibernateTransactionManager();
    tm.setSessionFactory(sf);// w w w .j av  a2s.  c om
    tm.setDataSource(ds);
    final TransactionTemplate tt = new TransactionTemplate(tm);
    assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds));
    assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive());
    TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session));
    assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));

    try {
        tt.execute(new TransactionCallbackWithoutResult() {
            @Override
            public void doInTransactionWithoutResult(TransactionStatus status) {
                assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));
                assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds));
                SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sf);
                assertEquals(tx1, sessionHolder.getTransaction());
                tt.execute(new TransactionCallbackWithoutResult() {
                    @Override
                    public void doInTransactionWithoutResult(TransactionStatus status) {
                        status.setRollbackOnly();
                        Session sess = ((SessionHolder) TransactionSynchronizationManager.getResource(sf))
                                .getSession();
                        assertEquals(session, sess);
                    }
                });
            }
        });
        fail("Should have thrown UnexpectedRollbackException");
    } catch (UnexpectedRollbackException ex) {
        // expected
    }

    assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));
    SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sf);
    assertTrue("Hasn't thread transaction", sessionHolder.getTransaction() == null);
    assertTrue("Not marked rollback-only", !sessionHolder.isRollbackOnly());

    tt.execute(new TransactionCallbackWithoutResult() {
        @Override
        public void doInTransactionWithoutResult(TransactionStatus status) {
            assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));
            assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds));
            SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sf);
            assertEquals(tx2, sessionHolder.getTransaction());
            Session sess = ((SessionHolder) TransactionSynchronizationManager.getResource(sf)).getSession();
            assertEquals(session, sess);
        }
    });

    assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));
    assertTrue("Hasn't thread transaction", sessionHolder.getTransaction() == null);
    TransactionSynchronizationManager.unbindResource(sf);
    assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds));
    assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive());

    verify(tx1).rollback();
    verify(tx2).commit();
    InOrder ordered = inOrder(session);
    ordered.verify(session).clear();
    ordered.verify(session).setFlushMode(FlushMode.AUTO);
    ordered.verify(session).setFlushMode(FlushMode.MANUAL);
    ordered.verify(session).disconnect();
}

From source file:org.springframework.orm.hibernate4.HibernateTransactionManagerTests.java

License:Apache License

@Test
public void testTransactionRollbackWithHibernateManagedSession() throws Exception {
    final SessionFactory sf = mock(SessionFactory.class);
    final Session session = mock(Session.class);
    final Transaction tx1 = mock(Transaction.class);
    final Transaction tx2 = mock(Transaction.class);

    given(sf.getCurrentSession()).willReturn(session);
    given(session.isOpen()).willReturn(true);
    given(session.getTransaction()).willReturn(tx1, tx2);
    given(session.beginTransaction()).willReturn(tx1, tx2);
    given(session.getFlushMode()).willReturn(FlushMode.MANUAL);

    HibernateTransactionManager tm = new HibernateTransactionManager();
    tm.setSessionFactory(sf);//from   w  ww  . ja  va2s. c o m
    tm.setPrepareConnection(false);
    tm.setHibernateManagedSession(true);
    final TransactionTemplate tt = new TransactionTemplate(tm);

    assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf));

    try {
        tt.execute(new TransactionCallbackWithoutResult() {
            @Override
            public void doInTransactionWithoutResult(TransactionStatus status) {
                assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));
                tt.execute(new TransactionCallbackWithoutResult() {
                    @Override
                    public void doInTransactionWithoutResult(TransactionStatus status) {
                        status.setRollbackOnly();
                        Session sess = ((SessionHolder) TransactionSynchronizationManager.getResource(sf))
                                .getSession();
                        assertEquals(session, sess);
                    }
                });
            }
        });
        fail("Should have thrown UnexpectedRollbackException");
    } catch (UnexpectedRollbackException ex) {
        // expected
    }

    assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf));

    tt.execute(new TransactionCallbackWithoutResult() {
        @Override
        public void doInTransactionWithoutResult(TransactionStatus status) {
            assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));
            Session sess = ((SessionHolder) TransactionSynchronizationManager.getResource(sf)).getSession();
            assertEquals(session, sess);
        }
    });

    verify(tx1).rollback();
    verify(tx2).commit();
    InOrder ordered = inOrder(session);
    ordered.verify(session).setFlushMode(FlushMode.AUTO);
    ordered.verify(session).setFlushMode(FlushMode.MANUAL);
}

From source file:org.springframework.orm.hibernate4.SpringSessionContext.java

License:Apache License

/**
 * Retrieve the Spring-managed Session for the current thread, if any.
 *///from  w ww  .  j a  v  a  2 s  .c  om
@Override
public Session currentSession() throws HibernateException {
    Object value = TransactionSynchronizationManager.getResource(this.sessionFactory);
    if (value instanceof Session) {
        return (Session) value;
    } else if (value instanceof SessionHolder) {
        SessionHolder sessionHolder = (SessionHolder) value;
        Session session = sessionHolder.getSession();
        if (!sessionHolder.isSynchronizedWithTransaction()
                && TransactionSynchronizationManager.isSynchronizationActive()) {
            TransactionSynchronizationManager.registerSynchronization(
                    new SpringSessionSynchronization(sessionHolder, this.sessionFactory, false));
            sessionHolder.setSynchronizedWithTransaction(true);
            // Switch to FlushMode.AUTO, as we have to assume a thread-bound Session
            // with FlushMode.MANUAL, which needs to allow flushing within the transaction.
            FlushMode flushMode = session.getFlushMode();
            if (flushMode.equals(FlushMode.MANUAL)
                    && !TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
                session.setFlushMode(FlushMode.AUTO);
                sessionHolder.setPreviousFlushMode(flushMode);
            }
        }
        return session;
    }

    if (this.transactionManager != null) {
        try {
            if (this.transactionManager.getStatus() == Status.STATUS_ACTIVE) {
                Session session = this.jtaSessionContext.currentSession();
                if (TransactionSynchronizationManager.isSynchronizationActive()) {
                    TransactionSynchronizationManager
                            .registerSynchronization(new SpringFlushSynchronization(session));
                }
                return session;
            }
        } catch (SystemException ex) {
            throw new HibernateException("JTA TransactionManager found but status check failed", ex);
        }
    }

    if (TransactionSynchronizationManager.isSynchronizationActive()) {
        Session session = this.sessionFactory.openSession();
        if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
            session.setFlushMode(FlushMode.MANUAL);
        }
        SessionHolder sessionHolder = new SessionHolder(session);
        TransactionSynchronizationManager.registerSynchronization(
                new SpringSessionSynchronization(sessionHolder, this.sessionFactory, true));
        TransactionSynchronizationManager.bindResource(this.sessionFactory, sessionHolder);
        sessionHolder.setSynchronizedWithTransaction(true);
        return session;
    } else {
        throw new HibernateException("Could not obtain transaction-synchronized Session for current thread");
    }
}

From source file:org.springframework.orm.hibernate43.HibernateTransactionManager.java

License:Apache License

@Override
protected void doBegin(Object transaction, TransactionDefinition definition) {
    HibernateTransactionObject txObject = (HibernateTransactionObject) transaction;

    if (txObject.hasConnectionHolder() && !txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
        throw new IllegalTransactionStateException(
                "Pre-bound JDBC Connection found! HibernateTransactionManager does not support "
                        + "running within DataSourceTransactionManager if told to manage the DataSource itself. "
                        + "It is recommended to use a single HibernateTransactionManager for all transactions "
                        + "on a single DataSource, no matter whether Hibernate or JDBC access.");
    }//from  w  ww .ja  va  2 s  .c  o  m

    Session session = null;

    try {
        if (txObject.getSessionHolder() == null
                || txObject.getSessionHolder().isSynchronizedWithTransaction()) {
            Interceptor entityInterceptor = getEntityInterceptor();
            Session newSession = (entityInterceptor != null
                    ? getSessionFactory().withOptions().interceptor(entityInterceptor).openSession()
                    : getSessionFactory().openSession());
            if (logger.isDebugEnabled()) {
                logger.debug("Opened new Session [" + newSession + "] for Hibernate transaction");
            }
            txObject.setSession(newSession);
        }

        session = txObject.getSessionHolder().getSession();

        if (this.prepareConnection && isSameConnectionForEntireSession(session)) {
            // We're allowed to change the transaction settings of the JDBC Connection.
            if (logger.isDebugEnabled()) {
                logger.debug("Preparing JDBC Connection of Hibernate Session [" + session + "]");
            }
            Connection con = ((SessionImplementor) session).connection();
            Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
            txObject.setPreviousIsolationLevel(previousIsolationLevel);
        } else {
            // Not allowed to change the transaction settings of the JDBC Connection.
            if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
                // We should set a specific isolation level but are not allowed to...
                throw new InvalidIsolationLevelException(
                        "HibernateTransactionManager is not allowed to support custom isolation levels: "
                                + "make sure that its 'prepareConnection' flag is on (the default) and that the "
                                + "Hibernate connection release mode is set to 'on_close' (SpringTransactionFactory's default).");
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Not preparing JDBC Connection of Hibernate Session [" + session + "]");
            }
        }

        if (definition.isReadOnly() && txObject.isNewSession()) {
            // Just set to MANUAL in case of a new Session for this transaction.
            session.setFlushMode(FlushMode.MANUAL);
        }

        if (!definition.isReadOnly() && !txObject.isNewSession()) {
            // We need AUTO or COMMIT for a non-read-only transaction.
            FlushMode flushMode = session.getFlushMode();
            if (FlushMode.isManualFlushMode(session.getFlushMode())) {
                session.setFlushMode(FlushMode.AUTO);
                txObject.getSessionHolder().setPreviousFlushMode(flushMode);
            }
        }

        Transaction hibTx;

        // Register transaction timeout.
        int timeout = determineTimeout(definition);
        if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
            // Use Hibernate's own transaction timeout mechanism on Hibernate 3.1+
            // Applies to all statements, also to inserts, updates and deletes!
            hibTx = session.getTransaction();
            hibTx.setTimeout(timeout);
            hibTx.begin();
        } else {
            // Open a plain Hibernate transaction without specified timeout.
            hibTx = session.beginTransaction();
        }

        // Add the Hibernate transaction to the session holder.
        txObject.getSessionHolder().setTransaction(hibTx);

        // Register the Hibernate Session's JDBC Connection for the DataSource, if set.
        if (getDataSource() != null) {
            Connection con = ((SessionImplementor) session).connection();
            ConnectionHolder conHolder = new ConnectionHolder(con);
            if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
                conHolder.setTimeoutInSeconds(timeout);
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Exposing Hibernate transaction as JDBC transaction [" + con + "]");
            }
            TransactionSynchronizationManager.bindResource(getDataSource(), conHolder);
            txObject.setConnectionHolder(conHolder);
        }

        // Bind the session holder to the thread.
        if (txObject.isNewSessionHolder()) {
            TransactionSynchronizationManager.bindResource(getSessionFactory(), txObject.getSessionHolder());
        }
        txObject.getSessionHolder().setSynchronizedWithTransaction(true);
    }

    catch (Throwable ex) {
        if (txObject.isNewSession()) {
            try {
                if (session.getTransaction().isActive()) {
                    session.getTransaction().rollback();
                }
            } catch (Throwable ex2) {
                logger.debug("Could not rollback Session after failed transaction begin", ex);
            } finally {
                SessionFactoryUtils.closeSession(session);
            }
        }
        throw new CannotCreateTransactionException("Could not open Hibernate Session for transaction", ex);
    }
}

From source file:org.springframework.orm.hibernate43.SpringSessionContext.java

License:Apache License

/**
 * Retrieve the Spring-managed Session for the current thread, if any.
 *//*  w w  w  . j a va  2 s  . c om*/
public Session currentSession() throws HibernateException {
    Object value = TransactionSynchronizationManager.getResource(this.sessionFactory);
    if (value instanceof Session) {
        return (Session) value;
    } else if (value instanceof SessionHolder) {
        SessionHolder sessionHolder = (SessionHolder) value;
        Session session = sessionHolder.getSession();
        if (TransactionSynchronizationManager.isSynchronizationActive()
                && !sessionHolder.isSynchronizedWithTransaction()) {
            TransactionSynchronizationManager.registerSynchronization(
                    new SpringSessionSynchronization(sessionHolder, this.sessionFactory));
            sessionHolder.setSynchronizedWithTransaction(true);
            // Switch to FlushMode.AUTO, as we have to assume a thread-bound Session
            // with FlushMode.MANUAL, which needs to allow flushing within the transaction.
            FlushMode flushMode = session.getFlushMode();
            if (FlushMode.isManualFlushMode(flushMode)
                    && !TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
                session.setFlushMode(FlushMode.AUTO);
                sessionHolder.setPreviousFlushMode(flushMode);
            }
        }
        return session;
    } else if (this.jtaSessionContext != null) {
        Session session = this.jtaSessionContext.currentSession();
        if (TransactionSynchronizationManager.isSynchronizationActive()) {
            TransactionSynchronizationManager.registerSynchronization(new SpringFlushSynchronization(session));
        }
        return session;
    } else {
        throw new HibernateException("No Session found for current thread");
    }
}

From source file:org.springframework.orm.hibernate5.HibernateTransactionManager.java

License:Apache License

@Override
protected void doBegin(Object transaction, TransactionDefinition definition) {
    HibernateTransactionObject txObject = (HibernateTransactionObject) transaction;

    if (txObject.hasConnectionHolder() && !txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
        throw new IllegalTransactionStateException(
                "Pre-bound JDBC Connection found! HibernateTransactionManager does not support "
                        + "running within DataSourceTransactionManager if told to manage the DataSource itself. "
                        + "It is recommended to use a single HibernateTransactionManager for all transactions "
                        + "on a single DataSource, no matter whether Hibernate or JDBC access.");
    }/*from w w  w  .j  a v  a 2s .  c o m*/

    Session session = null;

    try {
        if (txObject.getSessionHolder() == null
                || txObject.getSessionHolder().isSynchronizedWithTransaction()) {
            Interceptor entityInterceptor = getEntityInterceptor();
            Session newSession = (entityInterceptor != null
                    ? getSessionFactory().withOptions().interceptor(entityInterceptor).openSession()
                    : getSessionFactory().openSession());
            if (logger.isDebugEnabled()) {
                logger.debug("Opened new Session [" + newSession + "] for Hibernate transaction");
            }
            txObject.setSession(newSession);
        }

        session = txObject.getSessionHolder().getSession();

        if (this.prepareConnection && isSameConnectionForEntireSession(session)) {
            // We're allowed to change the transaction settings of the JDBC Connection.
            if (logger.isDebugEnabled()) {
                logger.debug("Preparing JDBC Connection of Hibernate Session [" + session + "]");
            }
            Connection con = ((SessionImplementor) session).connection();
            Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
            txObject.setPreviousIsolationLevel(previousIsolationLevel);
            if (this.allowResultAccessAfterCompletion && !txObject.isNewSession()) {
                int currentHoldability = con.getHoldability();
                if (currentHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT) {
                    txObject.setPreviousHoldability(currentHoldability);
                    con.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);
                }
            }
        } else {
            // Not allowed to change the transaction settings of the JDBC Connection.
            if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
                // We should set a specific isolation level but are not allowed to...
                throw new InvalidIsolationLevelException(
                        "HibernateTransactionManager is not allowed to support custom isolation levels: "
                                + "make sure that its 'prepareConnection' flag is on (the default) and that the "
                                + "Hibernate connection release mode is set to 'on_close' (the default for JDBC).");
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Not preparing JDBC Connection of Hibernate Session [" + session + "]");
            }
        }

        if (definition.isReadOnly() && txObject.isNewSession()) {
            // Just set to MANUAL in case of a new Session for this transaction.
            session.setFlushMode(FlushMode.MANUAL);
        }

        if (!definition.isReadOnly() && !txObject.isNewSession()) {
            // We need AUTO or COMMIT for a non-read-only transaction.
            FlushMode flushMode = session.getFlushMode();
            if (session.getFlushMode().equals(FlushMode.MANUAL)) {
                session.setFlushMode(FlushMode.AUTO);
                txObject.getSessionHolder().setPreviousFlushMode(flushMode);
            }
        }

        Transaction hibTx;

        // Register transaction timeout.
        int timeout = determineTimeout(definition);
        if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
            // Use Hibernate's own transaction timeout mechanism on Hibernate 3.1+
            // Applies to all statements, also to inserts, updates and deletes!
            hibTx = session.getTransaction();
            hibTx.setTimeout(timeout);
            hibTx.begin();
        } else {
            // Open a plain Hibernate transaction without specified timeout.
            hibTx = session.beginTransaction();
        }

        // Add the Hibernate transaction to the session holder.
        txObject.getSessionHolder().setTransaction(hibTx);

        // Register the Hibernate Session's JDBC Connection for the DataSource, if set.
        if (getDataSource() != null) {
            Connection con = ((SessionImplementor) session).connection();
            ConnectionHolder conHolder = new ConnectionHolder(con);
            if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
                conHolder.setTimeoutInSeconds(timeout);
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Exposing Hibernate transaction as JDBC transaction [" + con + "]");
            }
            TransactionSynchronizationManager.bindResource(getDataSource(), conHolder);
            txObject.setConnectionHolder(conHolder);
        }

        // Bind the session holder to the thread.
        if (txObject.isNewSessionHolder()) {
            TransactionSynchronizationManager.bindResource(getSessionFactory(), txObject.getSessionHolder());
        }
        txObject.getSessionHolder().setSynchronizedWithTransaction(true);
    }

    catch (Throwable ex) {
        if (txObject.isNewSession()) {
            try {
                if (session.getTransaction().getStatus() == TransactionStatus.ACTIVE) {
                    session.getTransaction().rollback();
                }
            } catch (Throwable ex2) {
                logger.debug("Could not rollback Session after failed transaction begin", ex);
            } finally {
                SessionFactoryUtils.closeSession(session);
                txObject.setSessionHolder(null);
            }
        }
        throw new CannotCreateTransactionException("Could not open Hibernate Session for transaction", ex);
    }
}

From source file:org.springframework.orm.jpa.hibernate.HibernateNativeEntityManagerFactoryIntegrationTests.java

License:Apache License

@Test // SPR-16956
public void testReadOnly() {
    assertSame(FlushMode.AUTO, sessionFactory.getCurrentSession().getHibernateFlushMode());
    assertFalse(sessionFactory.getCurrentSession().isDefaultReadOnly());
    endTransaction();//w  w w.  j  ava2s.  co  m

    this.transactionDefinition.setReadOnly(true);
    startNewTransaction();
    assertSame(FlushMode.MANUAL, sessionFactory.getCurrentSession().getHibernateFlushMode());
    assertTrue(sessionFactory.getCurrentSession().isDefaultReadOnly());
}