0

I'm training Spring. My app is not perfect but it's not a case of my problem. I have an Aspect which has to be executed before save() method in book Dao. But when I start JUnit tests in debug mode, first line of Aspect's before method (checkNotNullId()) is never reached, and I get an AssertionError in my test as it reaches fail() method. Why is that so? Here is my JUnit class, Aspect class, and class @Before is pointing at:

BookDaoAdvisor

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import pl.spring.demo.annotation.NullableId;
import pl.spring.demo.common.Sequence;
import pl.spring.demo.dao.AbstractDao;
import pl.spring.demo.exception.BookNotNullIdException;
import pl.spring.demo.to.IdAware;

import java.lang.reflect.Method;

@Aspect
public class BookDaoAdvisor {

@Autowired
private Sequence sequence;
private AbstractDao<? extends IdAware> objects;
@SuppressWarnings("unchecked")
@Before("execution(* pl.spring.demo.dao.impl.BookDaoImpl.save(..))")
public void before(JoinPoint joinPoint, NullableId nullableId) throws BookNotNullIdException {
    checkNotNullId(joinPoint.getArgs()[0]);
    if (joinPoint.getThis() instanceof AbstractDao){
        objects = (AbstractDao<? extends IdAware>)joinPoint.getThis();
        setNextId(joinPoint.getArgs()[0]);
    }
}

private void checkNotNullId(Object o){
    if (o instanceof IdAware && ((IdAware) o).getId() != null) {
        throw new BookNotNullIdException();
    }
}
private void setNextId(Object o){
    if (o instanceof IdAware){
        ((IdAware) o).setId(sequence.nextValue(objects.findAll()));
    }
}

}

BookDaoImpl

package pl.spring.demo.dao.impl;

import pl.spring.demo.annotation.NullableId;
import pl.spring.demo.common.Sequence;
import pl.spring.demo.dao.BookDao;
import pl.spring.demo.exception.BookNotNullIdException;
import pl.spring.demo.mapper.BookEntityBookToMapper;
import pl.spring.demo.to.AuthorTo;
import pl.spring.demo.to.BookEntity;
import pl.spring.demo.to.BookTo;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class BookDaoImpl implements BookDao {

private final Set<BookEntity> ALL_BOOKS = new HashSet<>();
@Autowired
private Sequence sequence;
@Autowired
private BookEntityBookToMapper bookMapper;

public BookDaoImpl() {
    addTestBooks();
}

@Override
public List<BookTo> findAll() {
    List<BookTo> books = new ArrayList<BookTo>();
    for (BookEntity book: ALL_BOOKS) {
        books.add(bookMapper.mapBookEntityToBookTo(book));
    }
    return books;
}

@Override
public List<BookTo> findBookByTitle(String title) {
    method code...
}

@Override
public List<BookTo> findBooksByAuthor(String authorName) {
    method code...
}

@Override
@NullableId
public BookTo save(BookTo book) throws BookNotNullIdException {
    ALL_BOOKS.add(bookMapper.mapBookToToBookEntity(book));
    return book;
}

public void setSequence(Sequence sequence) {
    this.sequence = sequence;
}

private void addTestBooks() {
    ALL_BOOKS.add(new BookEntity(1L, "book1", "author1"));
    ALL_BOOKS.add(new BookEntity(2L, "book2", "author2"));
    ALL_BOOKS.add(new BookEntity(3L, "book3", "author3"));
    ALL_BOOKS.add(new BookEntity(4L, "book4", "author4"));
    ALL_BOOKS.add(new BookEntity(5L, "book5", "author5"));
    ALL_BOOKS.add(new BookEntity(6L, "book6", "author6"));
}
}

JUnit

package pl.spring.demo.service;

import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import pl.spring.demo.exception.BookNotNullIdException;
import pl.spring.demo.to.BookTo;

import java.util.List;

import static org.junit.Assert.*;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "CommonServiceTest-context.xml")
public class BookServiceImplTest {

@Autowired
private BookService bookService;
@Autowired
private CacheManager cacheManager;

@Before
public void setUp() {
    cacheManager.getCache("booksCache").clear();
}

@Test(expected = BookNotNullIdException.class)
public void testShouldThrowBookNotNullIdException() {
    // given
    final BookTo bookToSave = new BookTo();
    bookToSave.setId(22L);
    // when
    bookService.saveBook(bookToSave);
    // then
    fail("test should throw BookNotNullIdException");
}
}

bookService.saveBook()

returns

bookDao.save()

which is interface method implemented by BookDaoImpl class.

my error:

java.lang.Exception: Unexpected exception, expected<pl.spring.demo.exception.BookNotNullIdException> but was<java.lang.AssertionError>
at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:28)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:73)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:73)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:224)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

Caused by: java.lang.AssertionError: test should throw BookNotNullIdException
at org.junit.Assert.fail(Assert.java:88)
at pl.spring.demo.service.BookServiceImplTest.testShouldThrowBookNotNullIdException(BookServiceImplTest.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at     org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:19)
... 22 more

XML:

<?xml version="1.0" encoding="UTF-8"?>
<beans xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd                   http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:aop="http://www.springframework.org/schema/aop"     xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans">

<import resource="cache-context.xml" />
<context:annotation-config/>
<aop:aspectj-autoproxy/>
<context:component-scan base-package="pl.spring.demo"></context:component-scan>
<util:properties location="classpath:config/application.properties" id="applicationProperties"/>
<bean id="bookService" class="pl.spring.demo.service.impl.BookServiceImpl"/>
<bean id="bookDaoAdvisor" class="pl.spring.demo.aop.BookDaoAdvisor"/>

And Exception after adding BookDaoAdvisor to XML:

java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:94)
at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:72)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:212)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:200)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:259)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:261)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:219)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.cache.annotation.AnnotationCacheOperationSource#0': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.cache.config.internalCacheAdvisor': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: error at ::0 formal unbound in pointcut 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:125)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:109)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:261)
at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:68)
at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:86)
... 25 more

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.cache.config.internalCacheAdvisor': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: error at ::0 formal unbound in pointcut 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans(BeanFactoryAdvisorRetrievalHelper.java:92)
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findCandidateAdvisors(AbstractAdvisorAutoProxyCreator.java:101)
at org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors(AnnotationAwareAspectJAutoProxyCreator.java:85)
at org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator.shouldSkip(AspectJAwareAdvisorAutoProxyCreator.java:103)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:324)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:293)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1579)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
... 39 more

Caused by: java.lang.IllegalArgumentException: error at ::0 formal unbound in pointcut 
at org.aspectj.weaver.tools.PointcutParser.parsePointcutExpression(PointcutParser.java:301)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:206)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.checkReadyToMatch(AspectJExpressionPointcut.java:192)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.getClassFilter(AspectJExpressionPointcut.java:169)
at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:208)
at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:262)
at org.springframework.aop.support.AopUtils.findAdvisorsThatCanApply(AopUtils.java:294)
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findAdvisorsThatCanApply(AbstractAdvisorAutoProxyCreator.java:118)
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(AbstractAdvisorAutoProxyCreator.java:88)
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean(AbstractAdvisorAutoProxyCreator.java:69)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:330)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.getEarlyBeanReference(AbstractAutoProxyCreator.java:232)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getEarlyBeanReference(AbstractAutowireCapableBeanFactory.java:819)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$2.getObject(AbstractAutowireCapableBeanFactory.java:529)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:192)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:173)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:240)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1477)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1222)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
... 53 more
cb4
  • 6,689
  • 7
  • 45
  • 57
RIPI
  • 321
  • 1
  • 9
  • 20
  • What do you want to intercept... before what? The execution, the call, the assignment? Next to that there is no `save()` method, you have a method with an argument. The pointcut should look something like `@Before("execution(* pl.spring.demo.dao.impl.BookDao+.save(*))")`. – M. Deinum May 03 '16 at 08:18
  • Sorry, but I don't understand what you mean. I want Aspect's before() method to be fired before bookDao's save() method and throw Exception as I'm trying to save book with Id that is already set. Id should've been set in Aspect. Not earlier. I've changed before in the way, you wrote and it's still never reached. – RIPI May 03 '16 at 08:28

2 Answers2

1

From my point of view three things to check:

  • first, the advice: @Before("execution(* pl.spring.demo.dao.impl.BookDaoImpl.save(..))"), your advice seems for another method (without parameters) and is missing execution group;
  • second, the @Aspect shall be a spring bean, is it being added to the context (declared on xml or annotated with @Component)?
  • third, remove the NullableId nullableId from your @Before method of your @Aspect class.
Francisco Spaeth
  • 23,493
  • 7
  • 67
  • 106
  • oh. It wasn't. It was just annotated as @Aspect. Now when I added Component annotation I have failed to load application context error. I will try to add it also to xml – RIPI May 03 '16 at 10:10
  • what is the exception? – Francisco Spaeth May 03 '16 at 10:23
  • Wow...I added this monster to my question – RIPI May 03 '16 at 10:28
  • Have you updated your `@Before` declaration to `@Before("execution(* pl.spring.demo.dao.impl.BookDaoImpl.save(..))")`? – Francisco Spaeth May 03 '16 at 10:34
  • ohhh one additional thing, remove the `NullableId nullableId` parameter – Francisco Spaeth May 03 '16 at 10:47
  • omg. Your my hero :) Thank you. Now it throws expected Exception so it enters the Aspect. Now I have mistake in code of Aspect as it doesnt want to enter setId method, but it's not a topic of my question, and I think I will solve it on my own. Thank you very much one more. Spring is pretty now thing to me. – RIPI May 03 '16 at 11:00
0

you need to change @Before in BookDaoAdvisor.java like this

@Before("execution(* pl.spring.demo.dao.impl.BookDaoImpl.save(..))")

After this change your BookDaoAdvisor.java will be

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import pl.spring.demo.annotation.NullableId;
import pl.spring.demo.common.Sequence;
import pl.spring.demo.dao.AbstractDao;
import pl.spring.demo.exception.BookNotNullIdException;
import pl.spring.demo.to.IdAware;

import java.lang.reflect.Method;

@Aspect
public class BookDaoAdvisor {

@Autowired
private Sequence sequence;
private AbstractDao<? extends IdAware> objects;
@SuppressWarnings("unchecked")
@Before("execution(* pl.spring.demo.dao.impl.BookDaoImpl.save(..))")
public void before(JoinPoint joinPoint, NullableId nullableId) throws BookNotNullIdException {
    checkNotNullId(joinPoint.getArgs()[0]);
    if (joinPoint.getThis() instanceof AbstractDao){
        objects = (AbstractDao<? extends IdAware>)joinPoint.getThis();
        setNextId(joinPoint.getArgs()[0]);
    }
}

private void checkNotNullId(Object o){
    if (o instanceof IdAware && ((IdAware) o).getId() != null) {
        throw new BookNotNullIdException();
    }
}
private void setNextId(Object o){
    if (o instanceof IdAware){
        ((IdAware) o).setId(sequence.nextValue(objects.findAll()));
    }
}

}
Prakash Hari Sharma
  • 1,414
  • 2
  • 17
  • 22
  • I think I've already tried exactly the same code earlier :) But I've tried it once more now and my test still ends with AssertionError. – RIPI May 03 '16 at 08:42
  • why you added fail("test should throw BookNotNullIdException"); remove it from test and use bookToSave.setId(null); to test it. – Prakash Hari Sharma May 03 '16 at 09:53
  • If your code doing well and throw BookNotNullIdException, means your test success – Prakash Hari Sharma May 03 '16 at 09:55
  • hmmm...I think you missunderstood this code. I can delete fail(), but it will still crash as my test expect Exception. I know that it will work fine if Id was null, but I want to test Aspect which checks if id is null. But I can't as it never enters the Aspect. And that is my real problem as when I want to add book with null Id, Aspect won't give it nextId number. It's id will still be null... – RIPI May 03 '16 at 10:03
  • ok, got it, Have you declared bean of your Aspect class and enable autoproxy and component scan – Prakash Hari Sharma May 03 '16 at 10:11
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/110892/discussion-between-prakash-hari-sharma-and-ripi). – Prakash Hari Sharma May 03 '16 at 10:13