/* * Copyright 2002-2016 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.dao.annotation; import javax.persistence.PersistenceException; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.junit.Test; import org.springframework.aop.Advisor; import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator; import org.springframework.aop.framework.Advised; import org.springframework.aop.support.AopUtils; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.context.support.GenericApplicationContext; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.dao.annotation.PersistenceExceptionTranslationAdvisorTests.RepositoryInterface; import org.springframework.dao.annotation.PersistenceExceptionTranslationAdvisorTests.RepositoryInterfaceImpl; import org.springframework.dao.annotation.PersistenceExceptionTranslationAdvisorTests.StereotypedRepositoryInterfaceImpl; import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.stereotype.Repository; import static org.junit.Assert.*; /** * @author Rod Johnson * @author Juergen Hoeller */ public class PersistenceExceptionTranslationPostProcessorTests { @Test @SuppressWarnings("resource") public void proxiesCorrectly() { GenericApplicationContext gac = new GenericApplicationContext(); gac.registerBeanDefinition("translator", new RootBeanDefinition(PersistenceExceptionTranslationPostProcessor.class)); gac.registerBeanDefinition("notProxied", new RootBeanDefinition(RepositoryInterfaceImpl.class)); gac.registerBeanDefinition("proxied", new RootBeanDefinition(StereotypedRepositoryInterfaceImpl.class)); gac.registerBeanDefinition("classProxied", new RootBeanDefinition(RepositoryWithoutInterface.class)); gac.registerBeanDefinition("classProxiedAndAdvised", new RootBeanDefinition(RepositoryWithoutInterfaceAndOtherwiseAdvised.class)); gac.registerBeanDefinition("myTranslator", new RootBeanDefinition(MyPersistenceExceptionTranslator.class)); gac.registerBeanDefinition("proxyCreator", BeanDefinitionBuilder.rootBeanDefinition(AnnotationAwareAspectJAutoProxyCreator.class). addPropertyValue("order", 50).getBeanDefinition()); gac.registerBeanDefinition("logger", new RootBeanDefinition(LogAllAspect.class)); gac.refresh(); RepositoryInterface shouldNotBeProxied = (RepositoryInterface) gac.getBean("notProxied"); assertFalse(AopUtils.isAopProxy(shouldNotBeProxied)); RepositoryInterface shouldBeProxied = (RepositoryInterface) gac.getBean("proxied"); assertTrue(AopUtils.isAopProxy(shouldBeProxied)); RepositoryWithoutInterface rwi = (RepositoryWithoutInterface) gac.getBean("classProxied"); assertTrue(AopUtils.isAopProxy(rwi)); checkWillTranslateExceptions(rwi); Additional rwi2 = (Additional) gac.getBean("classProxiedAndAdvised"); assertTrue(AopUtils.isAopProxy(rwi2)); rwi2.additionalMethod(false); checkWillTranslateExceptions(rwi2); try { rwi2.additionalMethod(true); fail("Should have thrown DataAccessResourceFailureException"); } catch (DataAccessResourceFailureException ex) { assertEquals("my failure", ex.getMessage()); } } protected void checkWillTranslateExceptions(Object o) { assertTrue(o instanceof Advised); Advised a = (Advised) o; for (Advisor advisor : a.getAdvisors()) { if (advisor instanceof PersistenceExceptionTranslationAdvisor) { return; } } fail("No translation"); } @Repository public static class RepositoryWithoutInterface { public void nameDoesntMatter() { } } public interface Additional { void additionalMethod(boolean fail); } public static class RepositoryWithoutInterfaceAndOtherwiseAdvised extends StereotypedRepositoryInterfaceImpl implements Additional { @Override public void additionalMethod(boolean fail) { if (fail) { throw new PersistenceException("my failure"); } } } public static class MyPersistenceExceptionTranslator implements PersistenceExceptionTranslator { @Override public DataAccessException translateExceptionIfPossible(RuntimeException ex) { if (ex instanceof PersistenceException) { return new DataAccessResourceFailureException(ex.getMessage()); } return null; } } @Aspect public static class LogAllAspect { @Before("execution(void *.additionalMethod(*))") public void log(JoinPoint jp) { System.out.println("Before " + jp.getSignature().getName()); } } }