Archive

Archive for September, 2009

Spring: Handling incoming JMS messages asynchronously

September 2, 2009 Andrew Hahn Leave a comment

Handling incoming JMS messages in an asynchronous manner requires, implementing a MessageListener, creating a connection, starting a thread, handling connection loss and thread death, etc…
Spring’s MessageListenerContainers provide a “Message Driven Pojo” framework that handles all that for you except implementing the MessageListener.

To take advantage of this you first need to create JMS connection factory and Destination:

	<bean id="connectionPool"
		class="org.springframework.jms.connection.SingleConnectionFactory">
		<property name="targetConnectionFactory">
			<bean class="org.apache.activemq.ActiveMQConnectionFactory">
				<property name="brokerURL" value="tcp://localhost"/>
			</bean>
		</property>
	</bean>

	<bean id="messageDestination" class="org.apache.activemq.command.ActiveMQQueue">
		<constructor-arg value="MY.INCOMING" />
	</bean>

Then implement the MessageListener interface:

@Component("IncomingMsgProcessor")
public class IncomingMsgProcessor implements MessageListener {
    @Override
    public void onMessage(Message message)
    {
         //Your message handling code here
    }
}

And finally inject an instance into the MessageListenerContainer:

	<bean id="incommingMessageListenerContainer"
		class="org.springframework.jms.listener.DefaultMessageListenerContainer">
		<property name="connectionFactory" ref="connectionPool" />
		<property name="destination" ref="messageDestination" />
		<property name="messageListener" ref="IncomingMsgProcessor" />
		<!--
			Retry connection every 10 seconds.
		-->
		<property name="recoveryInterval" value="10000" />
	</bean>

org.springframework.jms.listener.DefaultMessageListenerContainer gives a nice set of features, but spring offers other implementations if more (or less) is needed. If your message listener needs access to the JMS session you can implement SessionAwareMessageListener which has a method that take the message and session onMessage(Message message, Session session) instead.

Categories: activemq, java, jms, spring

Spring: Injecting JAXB (Un)Marshaller

September 1, 2009 Andrew Hahn Leave a comment

Create a JAXB context passing an array of root element classes:

	<bean id="jaxbContext" class="javax.xml.bind.JAXBContext"
		factory-method="newInstance">
		<constructor-arg>
			<list>
				<value type="java.lang.Class">my.example.rootclass.Root</value>
			</list>
		</constructor-arg>
	</bean>

Create prototypes for the marshallers/unmarshallers

	<!-- Pool (un)marshallers to improve performance -->
	<bean id="marshallerTarget" class="javax.xml.bind.Marshaller"
		factory-bean="jaxbContext" factory-method="createMarshaller"
		scope="prototype">
	</bean>

	<bean id="unmarshallerTarget" class="javax.xml.bind.Unmarshaller"
		factory-bean="jaxbContext" factory-method="createUnmarshaller"
		scope="prototype">
	</bean>

Wrap these in pool targets:

	<bean id="poolTargetSource" class="org.springframework.aop.target.CommonsPoolTargetSource">
		<property name="targetBeanName" value="marshallerTarget" />
		<property name="maxSize" value="25" />
	</bean>

	<bean id="unmarshallerPoolTargetSource" class="org.springframework.aop.target.CommonsPoolTargetSource">
		<property name="targetBeanName" value="unmarshallerTarget" />
		<property name="maxSize" value="25" />
	</bean>

And create pools for reusing marshallers/unmarshallers:

	<bean id="marshaller" class="org.springframework.aop.framework.ProxyFactoryBean">
		<qualifier value="marshaller" />
		<property name="targetSource" ref="poolTargetSource" />
	</bean>

	<bean id="unmarshaller" class="org.springframework.aop.framework.ProxyFactoryBean">
		<qualifier value="unmarshaller" />
		<property name="targetSource" ref="unmarshallerPoolTargetSource" />
	</bean>

This will create one context that will be used to create up to 25 marshallers/unmarshallers. Each will be created on demand until there are 25 in use simultaneously, then calls to them will block until one becomes available. Be careful changing the state on the (un)marshallers. It would probably be a better idea to create prototypes for each configuration and inject a separate pool for each.

These can be injected in the application context or using annotations:

    @Autowired
    @Qualifier("unmarshaller")
    private Unmarshaller unmarshaller;

    @Autowired
    @Qualifier("marshaller")
    private Marshaller marshaller;
Categories: java, jaxb, spring

Spring: Injecting ActiveMQ JMS Connection

September 1, 2009 Andrew Hahn Leave a comment

First create a connection factory.

	<bean id="connectionPool"
		class="org.springframework.jms.connection.SingleConnectionFactory">
		<property name="targetConnectionFactory">
			<bean class="org.apache.activemq.ActiveMQConnectionFactory">
				<property name="brokerURL" value="tcp://localhost"/>
			</bean>
		</property>
	</bean>

Create destiation:

	<bean id="messageDestination" class="org.apache.activemq.command.ActiveMQQueue">
		<constructor-arg value="MY.OUTGOING" />
	</bean>

Inject this into spring a template:

	<bean id="jmsSendTemplate" class="org.springframework.jms.core.JmsTemplate">
		<qualifier value="messageTemplate" />
		<property name="connectionFactory">
			<ref bean="connectionFactory" />
		</property>
		<property name="defaultDestination">
			<ref bean="messageDestination" />
		</property>
	</bean>

Which can then be injected in the application context or using annotations:

    @Autowired
    @Qualifier("messageTemplate")
    JmsTemplate jmsReceiveTemplate;
Categories: activemq, java, jms, spring

Next Sequence Value Using Hibernate Entity Manager

September 1, 2009 Andrew Hahn Leave a comment

To retrieve the next value of an Orcale sequence using the Hibernate Entity Manager first create a result set mapping.

@SqlResultSetMapping(name = "NextSequenceVal", columns = { @ColumnResult(name = "NEXTVAL") })

The mapping can go anywhere, I like to put it on the entity it is most closely associated with.
Then in your DAO.

    public Long getNextElecTransUniqueId()
    {
        Query query = entityManager.createNativeQuery("SELECT MY_SEQUENCE.NEXTVAL from Dual",
                "NextSequenceVal");
        // Workaround for
        // http://opensource.atlassian.com/projects/hibernate/browse/EJB-434
        // which breaks query.getSingleResult()
        return ((BigDecimal) query.getResultList().get(0)).longValue();

    }

This example is written for Hibernate 3.3.2, Hibernate Entity Manager 3.4.0, Oracle 10g.

Note: in Entity Manager 3.4.0 if you use query.getSingleResult() you will get the exception:
Exception: org.hibernate.exception.SQLGrammarException: could not execute query^M
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:90)^M
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)^M
at org.hibernate.loader.Loader.doList(Loader.java:2235)^M
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2129)^M
at org.hibernate.loader.Loader.list(Loader.java:2124)^M
at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:312)^M
at org.hibernate.impl.SessionImpl.listCustomQuery(SessionImpl.java:1723)^M
at org.hibernate.impl.AbstractSessionImpl.list(AbstractSessionImpl.java:165)^M
at org.hibernate.impl.SQLQueryImpl.list(SQLQueryImpl.java:175)^M
at org.hibernate.ejb.QueryImpl.getSingleResult(QueryImpl.java:88)^M
Caused by: java.sql.SQLException: ORA-02287: sequence number not allowed here

Categories: hibernate, java