/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.orm.hibernate3; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Method; import java.sql.SQLException; import junit.framework.TestCase; import org.aopalliance.intercept.Interceptor; import org.aopalliance.intercept.Invocation; import org.aopalliance.intercept.MethodInvocation; import org.easymock.MockControl; import org.hibernate.FlushMode; import org.hibernate.HibernateException; import org.hibernate.SessionFactory; import org.hibernate.classic.Session; import org.hibernate.exception.ConstraintViolationException; import org.springframework.beans.factory.BeanFactory; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.transaction.support.TransactionSynchronizationManager; /** * @author Juergen Hoeller * @since 05.03.2005 */ public class HibernateInterceptorTests extends TestCase { public void testInterceptorWithNewSession() throws HibernateException { MockControl sfControl = MockControl.createControl(SessionFactory.class); SessionFactory sf = (SessionFactory) sfControl.getMock(); MockControl sessionControl = MockControl.createControl(Session.class); Session session = (Session) sessionControl.getMock(); sf.openSession(); sfControl.setReturnValue(session, 1); session.getSessionFactory(); sessionControl.setReturnValue(sf); session.flush(); sessionControl.setVoidCallable(1); session.close(); sessionControl.setReturnValue(null, 1); sfControl.replay(); sessionControl.replay(); HibernateInterceptor interceptor = new HibernateInterceptor(); interceptor.setSessionFactory(sf); try { interceptor.invoke(new TestInvocation(sf)); } catch (Throwable t) { fail("Should not have thrown Throwable: " + t.getMessage()); } sfControl.verify(); sessionControl.verify(); } public void testInterceptorWithNewSessionAndFlushNever() throws HibernateException { MockControl sfControl = MockControl.createControl(SessionFactory.class); SessionFactory sf = (SessionFactory) sfControl.getMock(); MockControl sessionControl = MockControl.createControl(Session.class); Session session = (Session) sessionControl.getMock(); sf.openSession(); sfControl.setReturnValue(session, 1); session.getSessionFactory(); sessionControl.setReturnValue(sf); session.setFlushMode(FlushMode.NEVER); sessionControl.setVoidCallable(1); session.close(); sessionControl.setReturnValue(null, 1); sfControl.replay(); sessionControl.replay(); HibernateInterceptor interceptor = new HibernateInterceptor(); interceptor.setFlushModeName("FLUSH_NEVER"); interceptor.setSessionFactory(sf); try { interceptor.invoke(new TestInvocation(sf)); } catch (Throwable t) { fail("Should not have thrown Throwable: " + t.getMessage()); } sfControl.verify(); sessionControl.verify(); } public void testInterceptorWithNewSessionAndFilter() throws HibernateException { MockControl sfControl = MockControl.createControl(SessionFactory.class); SessionFactory sf = (SessionFactory) sfControl.getMock(); MockControl sessionControl = MockControl.createControl(Session.class); Session session = (Session) sessionControl.getMock(); sf.openSession(); sfControl.setReturnValue(session, 1); session.getSessionFactory(); sessionControl.setReturnValue(sf); session.enableFilter("myFilter"); sessionControl.setReturnValue(null, 1); session.flush(); sessionControl.setVoidCallable(1); session.close(); sessionControl.setReturnValue(null, 1); sfControl.replay(); sessionControl.replay(); HibernateInterceptor interceptor = new HibernateInterceptor(); interceptor.setSessionFactory(sf); interceptor.setFilterName("myFilter"); try { interceptor.invoke(new TestInvocation(sf)); } catch (Throwable t) { fail("Should not have thrown Throwable: " + t.getMessage()); } sfControl.verify(); sessionControl.verify(); } public void testInterceptorWithThreadBound() { MockControl sfControl = MockControl.createControl(SessionFactory.class); SessionFactory sf = (SessionFactory) sfControl.getMock(); MockControl sessionControl = MockControl.createControl(Session.class); Session session = (Session) sessionControl.getMock(); session.getSessionFactory(); sessionControl.setReturnValue(sf, 1); session.isOpen(); sessionControl.setReturnValue(true, 1); sfControl.replay(); sessionControl.replay(); TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session)); HibernateInterceptor interceptor = new HibernateInterceptor(); interceptor.setSessionFactory(sf); try { interceptor.invoke(new TestInvocation(sf)); } catch (Throwable t) { fail("Should not have thrown Throwable: " + t.getMessage()); } finally { TransactionSynchronizationManager.unbindResource(sf); } sfControl.verify(); sessionControl.verify(); } public void testInterceptorWithThreadBoundAndFlushEager() throws HibernateException { MockControl sfControl = MockControl.createControl(SessionFactory.class); SessionFactory sf = (SessionFactory) sfControl.getMock(); MockControl sessionControl = MockControl.createControl(Session.class); Session session = (Session) sessionControl.getMock(); session.getSessionFactory(); sessionControl.setReturnValue(sf, 1); session.isOpen(); sessionControl.setReturnValue(true, 1); session.getFlushMode(); sessionControl.setReturnValue(FlushMode.AUTO, 1); session.flush(); sessionControl.setVoidCallable(1); sfControl.replay(); sessionControl.replay(); TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session)); HibernateInterceptor interceptor = new HibernateInterceptor(); interceptor.setFlushMode(HibernateInterceptor.FLUSH_EAGER); interceptor.setSessionFactory(sf); try { interceptor.invoke(new TestInvocation(sf)); } catch (Throwable t) { fail("Should not have thrown Throwable: " + t.getMessage()); } finally { TransactionSynchronizationManager.unbindResource(sf); } sfControl.verify(); sessionControl.verify(); } public void testInterceptorWithThreadBoundAndFlushEagerSwitch() throws HibernateException { MockControl sfControl = MockControl.createControl(SessionFactory.class); SessionFactory sf = (SessionFactory) sfControl.getMock(); MockControl sessionControl = MockControl.createControl(Session.class); Session session = (Session) sessionControl.getMock(); session.getSessionFactory(); sessionControl.setReturnValue(sf, 1); session.isOpen(); sessionControl.setReturnValue(true, 1); session.getFlushMode(); sessionControl.setReturnValue(FlushMode.NEVER, 1); session.setFlushMode(FlushMode.AUTO); sessionControl.setVoidCallable(1); session.flush(); sessionControl.setVoidCallable(1); session.setFlushMode(FlushMode.NEVER); sessionControl.setVoidCallable(1); sfControl.replay(); sessionControl.replay(); TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session)); HibernateInterceptor interceptor = new HibernateInterceptor(); interceptor.setFlushMode(HibernateInterceptor.FLUSH_EAGER); interceptor.setSessionFactory(sf); try { interceptor.invoke(new TestInvocation(sf)); } catch (Throwable t) { fail("Should not have thrown Throwable: " + t.getMessage()); } finally { TransactionSynchronizationManager.unbindResource(sf); } sfControl.verify(); sessionControl.verify(); } public void testInterceptorWithThreadBoundAndFlushCommit() { MockControl sfControl = MockControl.createControl(SessionFactory.class); SessionFactory sf = (SessionFactory) sfControl.getMock(); MockControl sessionControl = MockControl.createControl(Session.class); Session session = (Session) sessionControl.getMock(); session.getSessionFactory(); sessionControl.setReturnValue(sf, 1); session.isOpen(); sessionControl.setReturnValue(true, 1); session.getFlushMode(); sessionControl.setReturnValue(FlushMode.AUTO, 1); session.setFlushMode(FlushMode.COMMIT); sessionControl.setVoidCallable(1); session.setFlushMode(FlushMode.AUTO); sessionControl.setVoidCallable(1); sfControl.replay(); sessionControl.replay(); TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session)); HibernateInterceptor interceptor = new HibernateInterceptor(); interceptor.setSessionFactory(sf); interceptor.setFlushMode(HibernateInterceptor.FLUSH_COMMIT); try { interceptor.invoke(new TestInvocation(sf)); } catch (Throwable t) { fail("Should not have thrown Throwable: " + t.getMessage()); } finally { TransactionSynchronizationManager.unbindResource(sf); } sfControl.verify(); sessionControl.verify(); } public void testInterceptorWithThreadBoundAndFlushAlways() { MockControl sfControl = MockControl.createControl(SessionFactory.class); SessionFactory sf = (SessionFactory) sfControl.getMock(); MockControl sessionControl = MockControl.createControl(Session.class); Session session = (Session) sessionControl.getMock(); session.getSessionFactory(); sessionControl.setReturnValue(sf, 1); session.isOpen(); sessionControl.setReturnValue(true, 1); session.getFlushMode(); sessionControl.setReturnValue(FlushMode.AUTO, 1); session.setFlushMode(FlushMode.ALWAYS); sessionControl.setVoidCallable(1); session.setFlushMode(FlushMode.AUTO); sessionControl.setVoidCallable(1); sfControl.replay(); sessionControl.replay(); TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session)); HibernateInterceptor interceptor = new HibernateInterceptor(); interceptor.setSessionFactory(sf); interceptor.setFlushMode(HibernateInterceptor.FLUSH_ALWAYS); try { interceptor.invoke(new TestInvocation(sf)); } catch (Throwable t) { fail("Should not have thrown Throwable: " + t.getMessage()); } finally { TransactionSynchronizationManager.unbindResource(sf); } sfControl.verify(); sessionControl.verify(); } public void testInterceptorWithThreadBoundAndFilter() { MockControl sfControl = MockControl.createControl(SessionFactory.class); SessionFactory sf = (SessionFactory) sfControl.getMock(); MockControl sessionControl = MockControl.createControl(Session.class); Session session = (Session) sessionControl.getMock(); session.getSessionFactory(); sessionControl.setReturnValue(sf, 1); session.isOpen(); sessionControl.setReturnValue(true, 1); session.enableFilter("myFilter"); sessionControl.setReturnValue(null, 1); session.disableFilter("myFilter"); sessionControl.setVoidCallable(1); sfControl.replay(); sessionControl.replay(); TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session)); HibernateInterceptor interceptor = new HibernateInterceptor(); interceptor.setSessionFactory(sf); interceptor.setFilterName("myFilter"); try { interceptor.invoke(new TestInvocation(sf)); } catch (Throwable t) { fail("Should not have thrown Throwable: " + t.getMessage()); } finally { TransactionSynchronizationManager.unbindResource(sf); } sfControl.verify(); sessionControl.verify(); } public void testInterceptorWithThreadBoundAndFilters() { MockControl sfControl = MockControl.createControl(SessionFactory.class); SessionFactory sf = (SessionFactory) sfControl.getMock(); MockControl sessionControl = MockControl.createControl(Session.class); Session session = (Session) sessionControl.getMock(); session.getSessionFactory(); sessionControl.setReturnValue(sf, 1); session.isOpen(); sessionControl.setReturnValue(true, 1); session.enableFilter("myFilter"); sessionControl.setReturnValue(null, 1); session.enableFilter("yourFilter"); sessionControl.setReturnValue(null, 1); session.disableFilter("myFilter"); sessionControl.setVoidCallable(1); session.disableFilter("yourFilter"); sessionControl.setVoidCallable(1); sfControl.replay(); sessionControl.replay(); TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session)); HibernateInterceptor interceptor = new HibernateInterceptor(); interceptor.setSessionFactory(sf); interceptor.setFilterNames(new String[] {"myFilter", "yourFilter"}); try { interceptor.invoke(new TestInvocation(sf)); } catch (Throwable t) { fail("Should not have thrown Throwable: " + t.getMessage()); } finally { TransactionSynchronizationManager.unbindResource(sf); } sfControl.verify(); sessionControl.verify(); } public void testInterceptorWithFlushFailure() throws Throwable { MockControl sfControl = MockControl.createControl(SessionFactory.class); SessionFactory sf = (SessionFactory) sfControl.getMock(); MockControl sessionControl = MockControl.createControl(Session.class); Session session = (Session) sessionControl.getMock(); sf.openSession(); sfControl.setReturnValue(session, 1); session.getSessionFactory(); sessionControl.setReturnValue(sf, 1); SQLException sqlEx = new SQLException("argh", "27"); session.flush(); ConstraintViolationException jdbcEx = new ConstraintViolationException("", sqlEx, null); sessionControl.setThrowable(jdbcEx, 1); session.close(); sessionControl.setReturnValue(null, 1); sfControl.replay(); sessionControl.replay(); HibernateInterceptor interceptor = new HibernateInterceptor(); interceptor.setSessionFactory(sf); try { interceptor.invoke(new TestInvocation(sf)); fail("Should have thrown DataIntegrityViolationException"); } catch (DataIntegrityViolationException ex) { // expected assertEquals(jdbcEx, ex.getCause()); } sfControl.verify(); sessionControl.verify(); } public void testInterceptorWithThreadBoundEmptyHolder() { MockControl sfControl = MockControl.createControl(SessionFactory.class); SessionFactory sf = (SessionFactory) sfControl.getMock(); MockControl sessionControl = MockControl.createControl(Session.class); Session session = (Session) sessionControl.getMock(); sf.openSession(); sfControl.setReturnValue(session, 1); session.getSessionFactory(); sessionControl.setReturnValue(sf, 1); session.flush(); sessionControl.setVoidCallable(1); session.close(); sessionControl.setReturnValue(null, 1); sfControl.replay(); sessionControl.replay(); SessionHolder holder = new SessionHolder("key", session); holder.removeSession("key"); TransactionSynchronizationManager.bindResource(sf, holder); HibernateInterceptor interceptor = new HibernateInterceptor(); interceptor.setSessionFactory(sf); try { interceptor.invoke(new TestInvocation(sf)); } catch (Throwable t) { fail("Should not have thrown Throwable: " + t.getMessage()); } sfControl.verify(); sessionControl.verify(); } public void testInterceptorWithEntityInterceptor() throws HibernateException { MockControl interceptorControl = MockControl.createControl(org.hibernate.Interceptor.class); org.hibernate.Interceptor entityInterceptor = (org.hibernate.Interceptor) interceptorControl.getMock(); interceptorControl.replay(); MockControl sfControl = MockControl.createControl(SessionFactory.class); SessionFactory sf = (SessionFactory) sfControl.getMock(); MockControl sessionControl = MockControl.createControl(Session.class); Session session = (Session) sessionControl.getMock(); sf.openSession(entityInterceptor); sfControl.setReturnValue(session, 1); session.getSessionFactory(); sessionControl.setReturnValue(sf, 1); session.flush(); sessionControl.setVoidCallable(1); session.close(); sessionControl.setReturnValue(null, 1); sfControl.replay(); sessionControl.replay(); HibernateInterceptor interceptor = new HibernateInterceptor(); interceptor.setSessionFactory(sf); interceptor.setEntityInterceptor(entityInterceptor); try { interceptor.invoke(new TestInvocation(sf)); } catch (Throwable t) { fail("Should not have thrown Throwable: " + t.getMessage()); } interceptorControl.verify(); sfControl.verify(); sessionControl.verify(); } public void testInterceptorWithEntityInterceptorBeanName() throws HibernateException { MockControl interceptorControl = MockControl.createControl(org.hibernate.Interceptor.class); org.hibernate.Interceptor entityInterceptor = (org.hibernate.Interceptor) interceptorControl.getMock(); interceptorControl.replay(); MockControl interceptor2Control = MockControl.createControl(org.hibernate.Interceptor.class); org.hibernate.Interceptor entityInterceptor2 = (org.hibernate.Interceptor) interceptor2Control.getMock(); interceptor2Control.replay(); MockControl sfControl = MockControl.createControl(SessionFactory.class); SessionFactory sf = (SessionFactory) sfControl.getMock(); MockControl sessionControl = MockControl.createControl(Session.class); Session session = (Session) sessionControl.getMock(); sf.openSession(entityInterceptor); sfControl.setReturnValue(session, 1); sf.openSession(entityInterceptor2); sfControl.setReturnValue(session, 1); session.getSessionFactory(); sessionControl.setReturnValue(sf, 2); session.flush(); sessionControl.setVoidCallable(2); session.close(); sessionControl.setReturnValue(null, 2); sfControl.replay(); sessionControl.replay(); MockControl beanFactoryControl = MockControl.createControl(BeanFactory.class); BeanFactory beanFactory = (BeanFactory) beanFactoryControl.getMock(); beanFactory.getBean("entityInterceptor", org.hibernate.Interceptor.class); beanFactoryControl.setReturnValue(entityInterceptor, 1); beanFactory.getBean("entityInterceptor", org.hibernate.Interceptor.class); beanFactoryControl.setReturnValue(entityInterceptor2, 1); beanFactoryControl.replay(); HibernateInterceptor interceptor = new HibernateInterceptor(); interceptor.setSessionFactory(sf); interceptor.setEntityInterceptorBeanName("entityInterceptor"); interceptor.setBeanFactory(beanFactory); for (int i = 0; i < 2; i++) { try { interceptor.invoke(new TestInvocation(sf)); } catch (Throwable t) { fail("Should not have thrown Throwable: " + t.getMessage()); } } interceptorControl.verify(); interceptor2Control.verify(); sfControl.verify(); sessionControl.verify(); } protected void tearDown() { assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty()); assertFalse(TransactionSynchronizationManager.isSynchronizationActive()); } private static class TestInvocation implements MethodInvocation { private SessionFactory sessionFactory; public TestInvocation(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public Object proceed() throws Throwable { if (!TransactionSynchronizationManager.hasResource(this.sessionFactory)) { throw new IllegalStateException("Session not bound"); } return null; } public int getCurrentInterceptorIndex() { return 0; } public int getNumberOfInterceptors() { return 0; } public Interceptor getInterceptor(int i) { return null; } public Method getMethod() { return null; } public AccessibleObject getStaticPart() { return null; } public Object getArgument(int i) { return null; } public Object[] getArguments() { return null; } public void setArgument(int i, Object handler) { } public int getArgumentCount() { return 0; } public Object getThis() { return null; } public Object getProxy() { return null; } public Invocation cloneInstance() { return null; } public void release() { } } }