/** 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();
      }
    }
  }