Is this pattern safe?

Consider the following stateless bean with a resource-injected DataSource. All of the methods in the bean want to use a connection acquired from the DataSource; we would like to avoid having to code this explicitly in every method, so we write an interceptor instead that sets a private connection field in the bean, and closes it after the method has finished executing:

@WebService

@Stateless(name ="MyExampleEJB")

@Interceptors({MyExampleBean.MyExampleInterceptor.class})

publicclass MyExampleBean{

@Resource(mappedName="jdbc/myDataSource")private DataSource ds;

private Connection connection;

publicstaticclass MyExampleInterceptor{

@AroundInvoke

public Object acquireConnection(InvocationContext ic)throws Exception{

MyExampleBean source = (MyExampleBean) ic.getTarget();

source.connection = source.ds.getConnection();

try{

return ic.proceed();

}finally{ source.connection.close(); source.connection=null;}

}

}

// ...methods which want to use this connection...

}

Questions:

i) Is this safe? Can we guarantee that no more than one attempt at a time will be made to execute any method on the same bean.

ii) Is this sensible? Is there a much simpler way of accomplishing the same thing?

[2157 byte] By [DominicFoxa] at [2007-11-26 17:37:02]
# 1

Hi Dominic,

i) Yes, it's safe. There is guaranteed to be a separate instance of the interceptor class for

each bean instance.The ejb container will always prevent concurrent access to the

same bean instance, so there's no need for any additional synchronization.

ii) Yes, it's sensible. @AroundInvoke methods are a good place for code that applies

to many methods of the same bean.There isn't a much simpler way of doing the

connection retrieval/close on each method invocation, other than moving up a level

of abstraction and using the Java Persistence API instead :-)

--ken

ksaksa at 2007-7-9 0:05:10 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 2
Thanks for this; I have lots of evil ideas for interception-related magic now.Another quick question: is there any way for the invoked method to get hold of the invocation context passed between the interceptors?
DominicFoxa at 2007-7-9 0:05:10 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 3

There's no specific API to get the InvocationContext from a business method since

the design center for InvocationContext is as a communication conduit between

the interceptors themselves.So, the best approach is just to pull out any applicable

contextData within the AroundInvoke method and set it on the bean instance.That's a

bit cleaner than just setting the InvocationContext itself on the bean instance, since that

object is considered a special container object that is not intended to be passed around.

Forgot to mention that you can also implement an AroundInvoke method on the

bean class itself.It's a good option for cases where the logic in the interceptor is

tightly coupled to a specific bean.It saves you having to implement a

separate inner class and makes it easier to access bean instance state.

--ken

ksaksa at 2007-7-9 0:05:10 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...