Hi Paul,
Let me try to say it in another way. There are different ways of handling non-serializable fields:
1) Open connections in PostConstruct/PostActivate, and close them in PreDestroy and PrePassivate
2) Set non-serializable fields to null in PrePassivate and create them again in the PostActivate using the information from the other fields.
3) Mark some fields as transient and initialize (make them null) them in the PostActivate
Let me give an example of the third option
In this example I have marked the Connection obtained from the ConnectionFactory as
transient as it isn't serializable and it isn't handled by the container (as the @Resource fields are). In my business logic I want to create the Connection object the first time by testing if the object isn't null. This is exactly what I have to take care of in the PostActivate method (as the container doesn't have to use java serialization): set my local connection object to null so that I will create a new (and valid) connection again. Maybe this is not the best example, but what I want to bring about is that this 3rd option might be a good option in some cases.
Code: Select all
@Stateless
@LocalBean
public class WebMessageSender {
@Resource(lookup = "jms/webmessage")
ConnectionFactory connfact;
@Resource(lookup = "jms/websendqueue", name = "q")
Queue queue;
@Resource
SessionContext sc;
transient private Connection connection;
public void sendWebMessage(String message) {
try {
Connection connection = getCon();
Session session = connection.createSession(true, 0);
MessageProducer producer = session.createProducer(queue);
TextMessage msg = session.createTextMessage(message);
producer.send(msg);
} catch (JMSException e) {
throw new EJBException();
}
}
private Connection getCon() {
if (connection == null) {
try {
this.connection = connfact.createConnection();
} catch (JMSException e) {
throw new EJBException();
}
}
return this.connection;
}
// lots of other stuff
}
What do you think?
Regards,
Frits