When using the Spring framework, one can still benefit from dependency injection etc. even if a bean is not obtained from a bean factory by using the @Configurable annotation, f.e.:

@Configurable(value = "myBean")
public class MyBean {
   ...
}

Where myBean is the bean id in the spring context.

This approach can be somewhat problematic, though, when used in conjunction with aspect-oriented features.
Say, for example, you also want to use JPA and require a transactional behavior.

You would usually do the following:

@Configurable(value = "myBean")
public class MyBean {
   @Transactional
    public void foo() {
    ...
    }
}

This will not work, but lead to an exception like this:


java.lang.IllegalStateException: Post-processor tried to replace bean instance of type [my.package.MyBean] with (proxy) object of type [my.package.MyBean$$EnhancerByCGLIB$$c029ddbf] - not supported for aspect-configured classes!

The reason is that @Configurable will ask spring to configure the current bean during constructor invokation. During configuration, a number of bean post processors will be invoked on the bean, and one of them, namely the InfrastructureAdvisorAutoProxyCreator will find the @Transactional annotation – which advices the post processor to proxy the bean in order to manage the required transaction’s context.

But you cannot override the expected outcome of a class instanciation with new with a proxy object – since it is not of the same type as the expected object!

Thus, @Configurable and @Transactional – together with any other advice that leads to a proxy object – cannot coexist in your class.

Share →

6 Responses to Why @Configurable and @Transactional don’t belong to into the same class

  1. Allard says:

    Olaf, you can use AspectJ to wire transactionality into your bean. The aspect required is in the spring-aspects jar, where the aspect treating @Configurable is placed too. If you use AspectJ, there is no problem using @Configurable and @Transactional in the same bean.
    See Spring’s documentation here: http://static.springframework.org/spring/docs/2.5.x/reference/aop.html#aop-using-aspectj.

  2. olaf says:

    Hi Allard, you certainly do have a point.

    @Transactional and @Configurable are a problem when creating proxy classes rather than directly advising the code. It should indeed be feasible with using the reference you posted.

    Thanks a lot!

  3. Manju says:

    Hi, I am having the exact same issue. Poted on: http://forum.springsource.org/showthread.php?t=103203
    I went thru the link that you provided, I am using AspectJ, still couldn’t get this to work. Can you suggest me some solution?

    • olaf says:

      Hi Manju,

      The basic solution is not to use @Configurable. Using this means that you using new GenericJpaDao() somewhere but still want the spring application context to be the factory for the resulting instance. This is not a safe concept, thus the conflicts you are experiencing.
      I think @Configurable is somewhat a legacy workaround provided by spring. Where exactly are you using new GenericJpaDao()? If it is for testing, spring-test can provide you with cool solutions to use dependency injection in JUnit-based tests.

      Best,
      Olaf

      • Hi Olaf,

        First, I want to thank you that your explanation helped me to see that I was trying to advice my @Configurable objects with an unintended pointcut expression.

        Second, IMHO @Configurable is not a legacy workaround but it is the result of trying to make domain objects richer. For example those domain objects could be able to trigger their persistence, but this doesnt mean that they should control transactions. TX should be controlled by service layer only. So it would be better if you “autowire” a transactional service bean into your domain object and foo method should delegate its operation to that bean.

        Third, there are some bugs related with LTW of those non-spring classes, and they result with failure of autowiring in some cases like following: https://jira.springsource.org/browse/SPR-5138 It is sad that they havent yet brought a solution to such problems, and it becomes show stopper.

        Kind Regards

  4. […] concern is that @Configurable and @Transactional do not work together.  I cannot declare method in my domain to be transactional while having that bean also being […]

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>