0

I want to migrate a Stateful Session Bean (EJB 2.1) to a Spring bean. Both the Stateful Bean and the Spring Bean shall run in Websphere Application Server using the Websphere Transaction Manager (the WebsphereUowTransactionManager interface allows Spring to access it).

The old Stateful Session Bean implements the SessionSynchronization interface to make use of the callback methods (specifically the afterCompletion callback).

I tried using prototype scope for my bean, because to my knowledge this emulates a Stateful bean, and implementing the TransansactionSynchronization interface offered by Spring.

As I later understood, these callbacks can't be called because "In contrast to the other scopes, Spring does not manage the complete lifecycle of a prototype bean: the container instantiates, configures, and otherwise assembles a prototype object, and hands it to the client, with no further record of that prototype instance" http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#beans-factory-scopes-prototype

Session scope could be a solution, but the Session bean is called from a Message Driven Pojo that consumes messages from a JMS Queue.

EDIT: The old session bean is only a "wrapper" for a pure Java class that implements the various writing to queues etc. So it takes the existing class and makes a bean out of it, implementing the SessionSynchronization.

public class XXXMessageSenderBean extends MessageSenderBean implements javax.ejb.SessionBean, SessionSynchronization { }

My idea was to take the same Java class and create a Spring Bean (interface and implementation classes):

public interface XXXMessageSenderPojo extends TransactionSynchronization

public class XXXMessageSenderPojoImpl extends MessageSenderBean implements XXXMessageSenderPojo
Entomo
  • 275
  • 3
  • 12
  • 1
    Why? Why do you need this explicit callbacks? What is so special about it that you need it and what cannot be done with a singleton (or prototype) and using declarative transaction management. You can (and should I guess) always manually register the bean implementing `TransactionSynchronization` using the `TransactionSynchronizationManager.registerSynchronization` method. Something you can easily do when a message arrives and you start processing (or after retrieving the bean from the context). – M. Deinum Jun 10 '15 at 09:43
  • Some cleanup, like calling `javax.jms.MessageProducer.close()`. Could you elaborate a bit more in your idea of implementing something similar with `TransactionSynchronization`? – Entomo Jun 10 '15 at 10:01
  • 1
    Why would you need that? That is already handled by springs transaction management and, assuming you use spring to drive your MDP to, spring. So basically you are trying to work around spring and declarative tx management? If you need to send use a `JmsTemplate` which handles all this for you, no need to hack around with a callback. – M. Deinum Jun 10 '15 at 10:08
  • Could you expand your answer with some code and configuration? IMHO you shouldn't need a callback and it feels like you are complicating things with that. – M. Deinum Jun 10 '15 at 10:09
  • Well, this is an old application, and my job currently is to only showcase if it is possible to achieve a similar behavior with Spring. If the sending to the queue was happening simply through a MDP there wouldn't be the need for any of this, but it happens through this Stateful Bean and I can't afford to rewrite the whole code base now (will do later though). How would this cleanup be done in Spring after retrieving the bean? – Entomo Jun 10 '15 at 10:26
  • As stated register it manually, but I strongly suggest instead of doing that use a `JmsTemplate` for sending. It simplifies your code and doesn't need the callback. – M. Deinum Jun 10 '15 at 10:29
  • I literally can't since for some classes I only get the .class files and am supposed to deliver something that works with that...by registering it manually do I get access to these specific callbacks? – Entomo Jun 10 '15 at 10:48
  • Now i'm confused what on earth are you trying to do? Are you trying to shoehorn an EJB2.1 into the spring container? That is obviously not going to work, regardless of the scope. – M. Deinum Jun 10 '15 at 10:51
  • As stated before post some code and configuration that way we can help yu better. If you have a bean that implements `TransactionSynchronization` just register it with a call to `TransactionSynchronizationManager.registerSynchronization` somewhere in your `onMessage`. But frankly you can eliminate a lot of code by just using spring and the abstraction instead of trying to work around them (which is basically what you are doing now). – M. Deinum Jun 10 '15 at 10:55
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/80265/discussion-between-entomo-and-m-deinum). – Entomo Jun 11 '15 at 09:37

0 Answers0