Example usage for org.hibernate FlushMode MANUAL

List of usage examples for org.hibernate FlushMode MANUAL

Introduction

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

Prototype

FlushMode MANUAL

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

Click Source Link

Document

The Session is only ever flushed when Session#flush is explicitly called by the application.

Usage

From source file:org.sparkcommerce.openadmin.server.service.persistence.module.BasicPersistenceModule.java

License:Apache License

@Override
public Serializable createPopulatedInstance(Serializable instance, Entity entity,
        Map<String, FieldMetadata> unfilteredProperties, Boolean setId, Boolean validateUnsubmittedProperties)
        throws ValidationException {
    Map<String, FieldMetadata> mergedProperties = filterOutCollectionMetadata(unfilteredProperties);
    FieldManager fieldManager = getFieldManager();
    boolean handled = false;
    for (FieldPersistenceProvider fieldPersistenceProvider : fieldPersistenceProviders) {
        FieldProviderResponse response = fieldPersistenceProvider
                .filterProperties(new AddFilterPropertiesRequest(entity), unfilteredProperties);
        if (FieldProviderResponse.NOT_HANDLED != response) {
            handled = true;/* w w w. j ava2 s.co m*/
        }
        if (FieldProviderResponse.HANDLED_BREAK == response) {
            break;
        }
    }
    if (!handled) {
        defaultFieldPersistenceProvider.filterProperties(new AddFilterPropertiesRequest(entity),
                unfilteredProperties);
    }
    Session session = getPersistenceManager().getDynamicEntityDao().getStandardEntityManager()
            .unwrap(Session.class);
    FlushMode originalFlushMode = session.getFlushMode();
    try {
        session.setFlushMode(FlushMode.MANUAL);
        for (Property property : entity.getProperties()) {
            BasicFieldMetadata metadata = (BasicFieldMetadata) mergedProperties.get(property.getName());
            Class<?> returnType;
            if (!property.getName().contains(FieldManager.MAPFIELDSEPARATOR)
                    && !property.getName().startsWith("__")) {
                Field field = fieldManager.getField(instance.getClass(), property.getName());
                if (field == null) {
                    LOG.debug("Unable to find a bean property for the reported property: " + property.getName()
                            + ". Ignoring property.");
                    continue;
                }
                returnType = field.getType();
            } else {
                if (metadata == null) {
                    LOG.debug("Unable to find a metadata property for the reported property: "
                            + property.getName() + ". Ignoring property.");
                    continue;
                }
                returnType = getMapFieldType(instance, fieldManager, property);
                if (returnType == null) {
                    returnType = getBasicSparkType(metadata.getFieldType());
                }
            }
            if (returnType == null) {
                throw new IllegalAccessException(
                        "Unable to determine the value type for the property (" + property.getName() + ")");
            }
            String value = property.getValue();
            if (metadata != null) {
                Boolean mutable = metadata.getMutable();
                Boolean readOnly = metadata.getReadOnly();

                if (metadata.getFieldType().equals(SupportedFieldType.BOOLEAN)) {
                    if (value == null) {
                        value = "false";
                    }
                }

                if ((mutable == null || mutable) && (readOnly == null || !readOnly)) {
                    if (value != null) {
                        handled = false;
                        PopulateValueRequest request = new PopulateValueRequest(setId, fieldManager, property,
                                metadata, returnType, value, persistenceManager, this);

                        boolean attemptToPopulate = true;
                        for (PopulateValueRequestValidator validator : populateValidators) {
                            PropertyValidationResult validationResult = validator.validate(request, instance);
                            if (!validationResult.isValid()) {
                                entity.addValidationError(property.getName(),
                                        validationResult.getErrorMessage());
                                attemptToPopulate = false;
                            }
                        }

                        if (attemptToPopulate) {
                            for (FieldPersistenceProvider fieldPersistenceProvider : fieldPersistenceProviders) {
                                FieldProviderResponse response = fieldPersistenceProvider.populateValue(request,
                                        instance);
                                if (FieldProviderResponse.NOT_HANDLED != response) {
                                    handled = true;
                                }
                                if (FieldProviderResponse.HANDLED_BREAK == response) {
                                    break;
                                }
                            }
                            if (!handled) {
                                defaultFieldPersistenceProvider
                                        .populateValue(
                                                new PopulateValueRequest(setId, fieldManager, property,
                                                        metadata, returnType, value, persistenceManager, this),
                                                instance);
                            }
                        }
                    } else {
                        try {
                            if (fieldManager.getFieldValue(instance, property.getName()) != null
                                    && (metadata.getFieldType() != SupportedFieldType.ID || setId)
                                    && metadata.getFieldType() != SupportedFieldType.PASSWORD) {
                                if (fieldManager.getFieldValue(instance, property.getName()) != null) {
                                    property.setIsDirty(true);
                                }
                                fieldManager.setFieldValue(instance, property.getName(), null);
                            }
                        } catch (FieldNotAvailableException e) {
                            throw new IllegalArgumentException(e);
                        }
                    }
                }
            }
        }
        validate(entity, instance, mergedProperties, validateUnsubmittedProperties);
        //if validation failed, refresh the current instance so that none of the changes will be persisted
        if (entity.isValidationFailure()) {
            //only refresh the instance if it was managed to begin with
            if (persistenceManager.getDynamicEntityDao().getStandardEntityManager().contains(instance)) {
                persistenceManager.getDynamicEntityDao().refresh(instance);
            }

            //re-initialize the valid properties for the entity in order to deal with the potential of not
            //completely sending over all checkbox/radio fields
            List<Serializable> entityList = new ArrayList<Serializable>(1);
            entityList.add(instance);
            Entity invalid = getRecords(mergedProperties, entityList, null, null)[0];
            invalid.setPropertyValidationErrors(entity.getPropertyValidationErrors());
            invalid.overridePropertyValues(entity);

            StringBuilder sb = new StringBuilder();
            for (Map.Entry<String, List<String>> entry : invalid.getPropertyValidationErrors().entrySet()) {
                Iterator<String> itr = entry.getValue().iterator();
                while (itr.hasNext()) {
                    sb.append(entry.getKey());
                    sb.append(" : ");
                    sb.append(itr.next());
                    if (itr.hasNext()) {
                        sb.append(" / ");
                    }
                }
            }

            throw new ValidationException(invalid, "The entity has failed validation - " + sb.toString());
        } else {
            fieldManager.persistMiddleEntities();
        }
    } catch (IllegalAccessException e) {
        throw new PersistenceException(e);
    } catch (InstantiationException e) {
        throw new PersistenceException(e);
    } finally {
        session.setFlushMode(originalFlushMode);
    }
    return instance;
}

From source file:org.springframework.orm.hibernate3.HibernateAccessor.java

License:Apache License

/**
 * Apply the flush mode that's been specified for this accessor
 * to the given Session./*w w  w.  j a  v a  2  s .  c o m*/
 * @param session the current Hibernate Session
 * @param existingTransaction if executing within an existing transaction
 * @return the previous flush mode to restore after the operation,
 * or {@code null} if none
 * @see #setFlushMode
 * @see org.hibernate.Session#setFlushMode
 */
protected FlushMode applyFlushMode(Session session, boolean existingTransaction) {
    if (getFlushMode() == FLUSH_NEVER) {
        if (existingTransaction) {
            FlushMode previousFlushMode = session.getFlushMode();
            if (!previousFlushMode.lessThan(FlushMode.COMMIT)) {
                session.setFlushMode(FlushMode.MANUAL);
                return previousFlushMode;
            }
        } else {
            session.setFlushMode(FlushMode.MANUAL);
        }
    } else if (getFlushMode() == FLUSH_EAGER) {
        if (existingTransaction) {
            FlushMode previousFlushMode = session.getFlushMode();
            if (!previousFlushMode.equals(FlushMode.AUTO)) {
                session.setFlushMode(FlushMode.AUTO);
                return previousFlushMode;
            }
        } else {
            // rely on default FlushMode.AUTO
        }
    } else if (getFlushMode() == FLUSH_COMMIT) {
        if (existingTransaction) {
            FlushMode previousFlushMode = session.getFlushMode();
            if (previousFlushMode.equals(FlushMode.AUTO) || previousFlushMode.equals(FlushMode.ALWAYS)) {
                session.setFlushMode(FlushMode.COMMIT);
                return previousFlushMode;
            }
        } else {
            session.setFlushMode(FlushMode.COMMIT);
        }
    } else if (getFlushMode() == FLUSH_ALWAYS) {
        if (existingTransaction) {
            FlushMode previousFlushMode = session.getFlushMode();
            if (!previousFlushMode.equals(FlushMode.ALWAYS)) {
                session.setFlushMode(FlushMode.ALWAYS);
                return previousFlushMode;
            }
        } else {
            session.setFlushMode(FlushMode.ALWAYS);
        }
    }
    return null;
}

From source file:org.springframework.orm.hibernate3.HibernateInterceptorTests.java

License:Apache License

@Test
public void testInterceptorWithNewSessionAndFlushNever() throws HibernateException {
    HibernateInterceptor interceptor = new HibernateInterceptor();
    interceptor.setFlushModeName("FLUSH_NEVER");
    interceptor.setSessionFactory(sessionFactory);
    try {//from w w w .  j a v a  2 s. c  o m
        interceptor.invoke(invocation);
    } catch (Throwable t) {
        fail("Should not have thrown Throwable: " + t.getMessage());
    }
    verify(session).setFlushMode(FlushMode.MANUAL);
    verify(session, never()).flush();
    verify(session).close();
}

From source file:org.springframework.orm.hibernate3.HibernateJtaTransactionTests.java

License:Apache License

@SuppressWarnings({ "rawtypes", "unchecked" })
private void doTestJtaTransactionCommit(int status, final boolean readOnly) throws Exception {
    UserTransaction ut = mock(UserTransaction.class);
    final SessionFactory sf = mock(SessionFactory.class);
    final Session session = mock(Session.class);
    Query query = mock(Query.class);
    if (status == Status.STATUS_NO_TRANSACTION) {
        given(ut.getStatus()).willReturn(status, Status.STATUS_ACTIVE);
    } else {// w  ww.ja  v  a2 s. c  om
        given(ut.getStatus()).willReturn(status);
    }

    final List list = new ArrayList();
    list.add("test");
    given(sf.openSession()).willReturn(session);
    given(session.getSessionFactory()).willReturn(sf);
    given(session.isOpen()).willReturn(true);
    given(session.createQuery("some query string")).willReturn(query);
    given(query.list()).willReturn(list);
    given(session.getFlushMode()).willReturn(FlushMode.AUTO);

    JtaTransactionManager ptm = new JtaTransactionManager(ut);
    TransactionTemplate tt = new TransactionTemplate(ptm);
    tt.setReadOnly(readOnly);
    assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive());
    assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf));

    Object result = tt.execute(new TransactionCallback() {

        @Override
        public Object doInTransaction(TransactionStatus status) {
            try {
                assertTrue("JTA synchronizations active",
                        TransactionSynchronizationManager.isSynchronizationActive());
                assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf));
                HibernateTemplate ht = new HibernateTemplate(sf);
                ht.setExposeNativeSession(true);
                ht.executeFind(new HibernateCallback() {

                    @Override
                    public Object doInHibernate(org.hibernate.Session sess) {
                        assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));
                        assertEquals(session, sess);
                        return null;
                    }
                });
                ht = new HibernateTemplate(sf);
                List htl = ht.executeFind(new HibernateCallback() {

                    @Override
                    public Object doInHibernate(org.hibernate.Session sess) {
                        assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));
                        return sess.createQuery("some query string").list();
                    }
                });
                assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));
                return htl;
            } catch (Error err) {
                err.printStackTrace();
                throw err;
            }
        }
    });

    assertTrue("Correct result list", result == list);
    assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf));
    assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive());

    if (status == Status.STATUS_NO_TRANSACTION) {
        InOrder ordered = inOrder(ut);
        ordered.verify(ut).begin();
        ordered.verify(ut).commit();
    }

    if (readOnly) {
        verify(session).setFlushMode(FlushMode.MANUAL);
    } else {
        verify(session).flush();
    }
    verify(session).close();
}

From source file:org.springframework.orm.hibernate3.HibernateJtaTransactionTests.java

License:Apache License

@SuppressWarnings({ "rawtypes", "unchecked" })
protected void doTestJtaTransactionCommitWithPreBound(boolean jtaTm, final boolean flushNever,
        final boolean readOnly) throws Exception {

    UserTransaction ut = mock(UserTransaction.class);
    given(ut.getStatus()).willReturn(Status.STATUS_NO_TRANSACTION, Status.STATUS_ACTIVE, Status.STATUS_ACTIVE);

    TransactionManager tm = mock(TransactionManager.class);
    if (jtaTm) {/*from  w  w  w .j a va  2s .  co m*/
        MockJtaTransaction transaction = new MockJtaTransaction();
        given(tm.getTransaction()).willReturn(transaction);
    }

    final SessionFactoryImplementor sf = mock(SessionFactoryImplementor.class);
    final ExtendedSession session = mock(ExtendedSession.class);
    given(sf.getTransactionManager()).willReturn(jtaTm ? tm : null);
    given(session.isOpen()).willReturn(true);
    given(session.getFlushMode()).willReturn(flushNever ? FlushMode.MANUAL : FlushMode.AUTO);

    TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session));
    try {
        JtaTransactionManager ptm = new JtaTransactionManager(ut);
        TransactionTemplate tt = new TransactionTemplate(ptm);
        tt.setReadOnly(readOnly);
        final List l = new ArrayList();
        l.add("test");
        assertTrue("JTA synchronizations not active",
                !TransactionSynchronizationManager.isSynchronizationActive());
        assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));

        Object result = tt.execute(new TransactionCallback() {

            @Override
            public Object doInTransaction(TransactionStatus status) {
                try {
                    assertTrue("JTA synchronizations active",
                            TransactionSynchronizationManager.isSynchronizationActive());
                    assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));
                    HibernateTemplate ht = new HibernateTemplate(sf);
                    ht.setExposeNativeSession(true);
                    List htl = null;
                    for (int i = 0; i < 5; i++) {
                        htl = ht.executeFind(new HibernateCallback() {

                            @Override
                            public Object doInHibernate(org.hibernate.Session sess) {
                                assertTrue("Has thread session",
                                        TransactionSynchronizationManager.hasResource(sf));
                                assertEquals(session, sess);
                                return l;
                            }
                        });
                        assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));
                    }
                    return htl;
                } catch (Error err) {
                    err.printStackTrace();
                    throw err;
                }
            }
        });

        assertTrue("Correct result list", result == l);
        assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));
        assertTrue("JTA synchronizations not active",
                !TransactionSynchronizationManager.isSynchronizationActive());
    } finally {
        TransactionSynchronizationManager.unbindResource(sf);
    }

    verify(ut).begin();
    verify(ut).commit();

    if (flushNever) {
        if (!readOnly) {
            InOrder ordered = inOrder(session);
            ordered.verify(session).setFlushMode(FlushMode.AUTO);
            ordered.verify(session).setFlushMode(FlushMode.MANUAL);
        }
    }
    if (!flushNever && !readOnly) {
        verify(session).flush();
    }
    verify(session).afterTransactionCompletion(true, null);
    verify(session).disconnect();
}

From source file:org.springframework.orm.hibernate3.HibernateJtaTransactionTests.java

License:Apache License

@Test
@SuppressWarnings({ "rawtypes", "unchecked" })
public void testTransactionWithPropagationSupports() throws Exception {

    UserTransaction ut = mock(UserTransaction.class);
    given(ut.getStatus()).willReturn(Status.STATUS_NO_TRANSACTION, Status.STATUS_ACTIVE);

    final SessionFactory sf = mock(SessionFactory.class);
    final Session session = mock(Session.class);

    given(sf.openSession()).willReturn(session);
    given(session.getSessionFactory()).willReturn(sf);
    given(session.getFlushMode()).willReturn(FlushMode.MANUAL);

    JtaTransactionManager tm = new JtaTransactionManager(ut);
    TransactionTemplate tt = new TransactionTemplate(tm);
    tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS);
    assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf));

    tt.execute(new TransactionCallback() {

        @Override/*from w  w w .  j  a v a2s  .  c  o m*/
        public Object doInTransaction(TransactionStatus status) {
            assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf));
            assertTrue("Is not new transaction", !status.isNewTransaction());
            assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
            assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
            HibernateTemplate ht = new HibernateTemplate(sf);
            ht.setFlushMode(HibernateTemplate.FLUSH_EAGER);
            ht.execute(new HibernateCallback() {

                @Override
                public Object doInHibernate(org.hibernate.Session session) {
                    return null;
                }
            });
            assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));
            return null;
        }
    });

    assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf));
    InOrder ordered = inOrder(session);
    ordered.verify(session).setFlushMode(FlushMode.AUTO);
    ordered.verify(session).flush();
    ordered.verify(session).setFlushMode(FlushMode.MANUAL);
    ordered.verify(session).close();
}

From source file:org.springframework.orm.hibernate3.HibernateJtaTransactionTests.java

License:Apache License

@Test
@SuppressWarnings("rawtypes")
public void testJtaSessionSynchronizationWithRollbackByOtherThread() throws Exception {

    TransactionManager tm = mock(TransactionManager.class);
    MockJtaTransaction transaction = new MockJtaTransaction();
    given(tm.getTransaction()).willReturn(transaction);
    given(tm.getStatus()).willReturn(Status.STATUS_NO_TRANSACTION);
    final SessionFactoryImplementor sf = mock(SessionFactoryImplementor.class);
    final Session session = mock(Session.class);
    given(sf.openSession()).willReturn(session);
    given(sf.getTransactionManager()).willReturn(tm);
    given(session.isOpen()).willReturn(true);

    assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf));
    final HibernateTemplate ht = new HibernateTemplate(sf);
    ht.setExposeNativeSession(true);//from   ww w .jav a  2  s .  co  m
    for (int i = 0; i < 5; i++) {
        ht.executeFind(new HibernateCallback() {

            @Override
            public Object doInHibernate(org.hibernate.Session sess) {
                assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));
                assertEquals(session, sess);
                return null;
            }
        });
    }

    final Synchronization synchronization = transaction.getSynchronization();
    assertTrue("JTA synchronization registered", synchronization != null);
    Thread thread = new Thread() {

        @Override
        public void run() {
            synchronization.afterCompletion(Status.STATUS_ROLLEDBACK);
        }
    };
    thread.start();
    thread.join();

    assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));
    assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive());

    TransactionTemplate tt = new TransactionTemplate(new JtaTransactionManager(tm));
    tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS);
    tt.setReadOnly(true);
    tt.execute(new TransactionCallbackWithoutResult() {

        @Override
        protected void doInTransactionWithoutResult(TransactionStatus status) {
            assertTrue("JTA synchronizations active",
                    TransactionSynchronizationManager.isSynchronizationActive());
            for (int i = 0; i < 5; i++) {
                ht.executeFind(new HibernateCallback() {

                    @Override
                    public Object doInHibernate(org.hibernate.Session sess) {
                        assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));
                        assertEquals(session, sess);
                        return null;
                    }
                });
            }
        }
    });

    assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf));
    assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive());

    verify(session).setFlushMode(FlushMode.MANUAL);
    verify(session, times(2)).close();
}

From source file:org.springframework.orm.hibernate3.HibernateJtaTransactionTests.java

License:Apache License

@SuppressWarnings("rawtypes")
private void doTestJtaSessionSynchronizationWithPreBound(boolean flushNever) throws Exception {

    TransactionManager tm = mock(TransactionManager.class);
    MockJtaTransaction transaction = new MockJtaTransaction();
    given(tm.getTransaction()).willReturn(transaction);
    final SessionFactoryImplementor sf = mock(SessionFactoryImplementor.class);
    final Session session = mock(Session.class);
    given(sf.getTransactionManager()).willReturn(tm);
    given(session.isOpen()).willReturn(true);
    if (flushNever) {
        given(session.getFlushMode()).willReturn(FlushMode.MANUAL, FlushMode.AUTO, FlushMode.MANUAL);
    } else {//w  w w . java  2  s.  c om
        given(session.getFlushMode()).willReturn(FlushMode.AUTO);
    }

    assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf));
    TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session));
    try {
        assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));
        HibernateTemplate ht = new HibernateTemplate(sf);
        ht.setExposeNativeSession(true);
        for (int i = 0; i < 5; i++) {
            ht.executeFind(new HibernateCallback() {

                @Override
                public Object doInHibernate(org.hibernate.Session sess) {
                    assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));
                    assertEquals(session, sess);
                    return null;
                }
            });
        }

        Synchronization synchronization = transaction.getSynchronization();
        assertTrue("JTA synchronization registered", synchronization != null);
        synchronization.beforeCompletion();
        synchronization.afterCompletion(Status.STATUS_COMMITTED);
        assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));
    } finally {
        TransactionSynchronizationManager.unbindResource(sf);
    }
    assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf));

    InOrder ordered = inOrder(session);
    if (flushNever) {
        ordered.verify(session).setFlushMode(FlushMode.AUTO);
        ordered.verify(session).setFlushMode(FlushMode.MANUAL);
    } else {
        ordered.verify(session).flush();
    }
    ordered.verify(session).disconnect();
}

From source file:org.springframework.orm.hibernate3.HibernateTemplateTests.java

License:Apache License

@Test
public void testExecuteWithNewSessionAndFlushNever() throws HibernateException {
    hibernateTemplate.setFlushMode(HibernateTemplate.FLUSH_NEVER);
    final List l = new ArrayList();
    l.add("test");
    List result = hibernateTemplate.executeFind(new HibernateCallback<Object>() {
        @Override// w  w  w . j  av  a  2s  .  c  om
        public Object doInHibernate(org.hibernate.Session session) throws HibernateException {
            return l;
        }
    });
    assertTrue("Correct result list", result == l);
    verify(session).setFlushMode(FlushMode.MANUAL);
    verify(session).close();
}

From source file:org.springframework.orm.hibernate3.HibernateTemplateTests.java

License:Apache License

@Test
public void testSaveOrUpdateWithFlushModeNever() throws HibernateException {
    TestBean tb = new TestBean();
    given(session.getFlushMode()).willReturn(FlushMode.MANUAL);
    try {//from   w w w  .j a  v  a  2  s.  c  om
        hibernateTemplate.saveOrUpdate(tb);
        fail("Should have thrown InvalidDataAccessApiUsageException");
    } catch (InvalidDataAccessApiUsageException ex) {
        // expected
    }
    verify(session).close();
}