Rectangle 27 0

java How to handle internal calls on SpringEJBMockito... proxies?


Internally in the class get a reference to the proxy.

Refactor your classes to avoid the self-invocation calls that bypass the proxy.

Advantages of this approach are its simplicity and that there are no ties to any framework. However, it may not be appropriate for a very transactional heavy code base as you'd end up with many trivially small classes.

An option - but one that requires moderate refactoring, introducing additional framework ties and increased complexity - so probably not a preferred option

As AspectJ does not use proxies then self-invocation is not a problem

I'll talk about Spring and @Transactional but the advise applies for many other frameworks also.

Refactor your code to use manual transaction demarcation - possibly using the decorator pattern.

There are a number of possible solutions.

This can be done by injecting the proxy or with hard coded " AopContext.currentProxy()" call (see Spring docs above.).

This is a very clean method though - it is at the expense of introducing another framework. I've worked on a large project where AspectJ was introduced for this very reason.

This is an inherent problem with proxy based aspects. It is discussed in the spring documentation here:

This method allows you to avoid splitting the classes but in many ways negates the advantages of using the transactional annotation. My personal opinion is that this is one of those things that is a little ugly but the ugliness is self contained and might be the pragmatic approach if lots of transactions are used.

Usually splitting up the code is the best answer and can also be good thing for seperation of concerns also. However, if I had a framework/application that heavily relied on nested transactions I would consider using AspectJ to allow self-invocation.

thanks best answer so far. So i think i'll use AopContext.currentProxy() only on some very specific cases since i'm not on a heavy transactionnal app

Note
Rectangle 27 0

java How to handle internal calls on SpringEJBMockito... proxies?


@SebastienLorber - I think that's a perfectly fine compromise (I've done it myself a few times, to get around this type of restriction in Spring AOP) as long as you document it in javadoc/comments so the next guy understands what you are doing and why.

Actually injecting the proxy into the proxied class seems quite easy to me and it ensures that your transactions work well for internal calls, don't you think it's an easy workaround?

As always when modelling and designing complex use cases - focus on understandable and maintainable design and code. If you prefer a certain pattern or design but it clashes with the underlying framework, consider if it's worth a complex workaround to shoehorn your design into the framework, or if you should compromise and conform your design to the framework where necessary. Don't fight the framework unless you absolutely have to.

My advice - if you can accomplish your goal with such an easy compromise as to split out into a few extra service classes - do it. It sounds a lot cheaper in terms of time, testing and agony than the alternative. And it sure sounds a lot easier to maintain and less of a headache for the next guy to take over.

that's true. the problem is well known i think but for newcomers javadoc is welcome... still i wonder what "which spring is doing now" means. This problem is perhaps already solved?

Note
Rectangle 27 0

java How to handle internal calls on SpringEJBMockito... proxies?


I usually make it simple, so I split the code into two objects.

The alternative is to demarcate the new transaction yourself, if you need to keep everything in the same file, using a TransactionTemplate. A few more lines of code, but not more than defining a new bean. And it sometimes makes the point more obvious.

Note