/** Test that session-closed protections work properly in all environments. */ @Test public void testSessionClosedProtections() throws Throwable { prepare(); Session s = getSessionUnderTest(); release(s); done(); assertFalse(s.isOpen()); assertFalse(s.isConnected()); assertNotNull(s.getStatistics()); assertNotNull(s.toString()); try { s.createQuery("from Silly").list(); fail("allowed to create query on closed session"); } catch (Throwable ignore) { } try { s.getTransaction(); fail("allowed to access transaction on closed session"); } catch (Throwable ignore) { } try { s.close(); fail("allowed to close already closed session"); } catch (Throwable ignore) { } try { s.isDirty(); fail("allowed to check dirtiness of closed session"); } catch (Throwable ignore) { } }
public static void rollback() { Session session = getCurrentSession(); try { if (session.isOpen()) { if (session.isDirty()) { LOG.warn("rolling back transaction after exception"); session.getTransaction().rollback(); } else { LOG.warn("closing open transaction after exception"); session.close(); } } } catch (Throwable t) { LOG.error("failed to roll back transaction after exception, attempting to close", t); session.close(); } }
public boolean isDirty() throws HibernateException { return session.isDirty(); }
/** * invocation interceptor for prepairing this {@link Thread} for execution and subsequently * reseting it. * * @see * org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation) */ public Object invoke(MethodInvocation arg0) throws Throwable { boolean readOnly = checkReadOnly(arg0); boolean stateful = StatefulServiceInterface.class.isAssignableFrom(arg0.getThis().getClass()); boolean isClose = stateful && "close".equals(arg0.getMethod().getName()); if (!readOnly && this.readOnly) { throw new ApiUsageException("This instance is read-only"); } // ticket:1254 // and ticket:1266 final Session session = factory.getSession(); if (!readOnly) { sql.deferConstraints(); } if (!doLogin(readOnly, isClose)) { return null; } boolean failure = false; Object retVal = null; try { secSys.enableReadFilter(session); retVal = arg0.proceed(); saveLogs(readOnly, session); secSys.cd.loadPermissions(session); return retVal; } catch (Throwable ex) { failure = true; throw ex; } finally { try { // on failure, we want to make sure that no one attempts // any further changes. if (failure) { // TODO we should probably do some forced clean up here. } // stateful services should NOT be flushed, because that's part // of the state that should hang around. else if (stateful) { // we don't want to do anything, really. } // read-only sessions should not have anything changed. else if (readOnly) { if (session.isDirty()) { if (log.isDebugEnabled()) { log.debug("Clearing dirty session."); } session.clear(); } } // stateless services, don't keep their sesssions about. else { session.flush(); if (session.isDirty()) { throw new InternalException( "Session is dirty. Cannot properly " + "reset security system. Must rollback.\n Session=" + session); } secSys.disableReadFilter(session); session.clear(); } } finally { secSys.disableReadFilter(session); secSys.invalidateEventContext(); } } }