Hi,
I have a similar problem but I don't have the possibility (i think) to use one connection for the transaction instead of opening and closing it for each message to push into the JMS.
Here I will describe my situation; I have a Java EE application on Glassfish using JPA (toplink) as persistence layer. When an entity is changed an update needs to be send to some clients. For this a JMS Topic is created which the clients read from.
On the JPA entity I added a EntityListener annotation, the implementation of this class handles the PostPersist, the implementation pushes a message into the JMS Topic like this:
public class EntityListenerImpl {
@PostPersist
public void postPersist(Object entity) {
String entityName = entity.getClass().getName();
Long entityId = ((HasId) entity).getId();
// changemessage is my own class holding entity information which can be serialized
ChangeMessage changeMessage = new ChangeMessage(entityName, entityId);
InitialContext initialContext;
TopicConnection connection = null;
TopicSession session = null;
TopicPublisher publisher = null;
try {
// get a connection and session for the topic
initialContext = new InitialContext();
TopicConnectionFactory connectionFactory = (TopicConnectionFactory) initialContext.lookup("jms/TopicConnectionFactory");
connection = connectionFactory.createTopicConnection();
session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
// look up the topic
Topic topic = (Topic) initialContext.lookup("jms/HtChangeNotification");
connection.start();
// get a publisher for the topic
publisher = session.createPublisher(topic);
publisher.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
// publish the message
ObjectMessage message = session.createObjectMessage();
message.setObject(changeMessage);
publisher.publish(message);
connectionFactory = null;
if (initialContext != null) {
initialContext.close();
}
} catch (Throwable ex) {
LogFactory.getLog(getClass()).error("Error", ex);
} finally {
if (publisher != null) {
try {
publisher.close();
publisher = null;
} catch (JMSException ex) {
LogFactory.getLog(getClass()).error("Error", ex);
}
}
if (session != null) {
try {
session.close();
session = null;
} catch (JMSException ex) {
LogFactory.getLog(getClass()).error("Error", ex);
}
}
if (connection != null) {
try {
connection.close();
connection = null;
} catch (JMSException ex) {
LogFactory.getLog(getClass()).error("Error", ex);
}
}
}
}
As far as I know I can't control the lifecycle of the entity listener and thus not of the JMS connection. Creating a private variable for a connection also seems like a risk because I don't know if the application server uses an entity listener instance per thread, domain instance, when it garbage collected etc...
What would be the correct way to do this?
Chris
[Message sent by forum member 'sisirhc' (chriswesdorp_at_gmail.com)]
http://forums.java.net/jive/thread.jspa?messageID=366053