Archive for the ‘Spring’ Category

ActiveMQ Embedded Broker

November 7, 2007

You can run ActiveMQ brokers in your Spring based servlets. Embedding ActiveMQ should make the deployment easier, since the embedded broker is running in the JVM of Tomcat, and you wont have to monitor a second set of JMV clusters simply to be able to use JMS in your application.

I tried to get embedded broker to work using the relatively scant ActiveMQ documentation on this topic. Here is what I did:

  1. I updated the Spring configuration by updating the beans tag name space specification.
    
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:amq="http://activemq.org/config/1.0"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
    http://activemq.org/config/1.0 http://activemq.apache.org/snapshot-schema/activemq-core-5.0-SNAPSHOT.xsd">
    ...
    
    <beans>
    
  2. Add the configuration to create the embedded broker
    
      <!--  lets create an embedded ActiveMQ Broker -->
      <amq:broker useJmx="false" persistent="false">
        <amq:transportConnectors>
          <amq:transportConnector uri="tcp://localhost:0" />
        </amq:transportConnectors>
      </amq:broker>
    
  3. Now when you start Tomcat, you’ll see the following error message:
    
    SEVERE: Context initialization failed
    org.springframework.beans.factory.parsing.BeanDefinitionParsingException:
      Configuration problem: Unable to locate NamespaceHandler for namespace [http://activemq.org/config/1.0]
    Offending resource: ServletContext resource [/WEB-INF/applicationContext.xml]
    
    

    To fix this issue, you must add xbean-spring-3.0.jar to the lib folder of your webapp. This jar is in the .../lib/optional/ folder of your ActiveMQ release.

  4. Now the code compiles and the servlet does start, but there were other issues, the number of threads under eclipse kept changing rapidly and I still needed to figure out what other configuration settings I need to pass to ActiveMQ. I’ll tackle this part later… (last night when I was trying this activemq.apache.org was unreachable and I had to copy the xsd file to my web server for any of this work).

Declarative transactions in Spring

August 28, 2007

Spring applicationContext.xml file for the sample projectSpring declarative transactions, and the DAO design pattern simplify database (& JMS) programming. With the DAO design pattern, you need to create your domain objects and encapsulate the database access in the DAO classes. This makes up the model part of your application. The model component also includes the business (aka manager layer) that captures the semantics of your application. The methods of the business layer need to be enlisted in the transaction. I’ve updated my sample project to include the business layer and a JUNIT test case for the transaction. (more…)

Cascaded delete with hibernate

August 26, 2007

When you’ve modeled a parent and child association with a hibernate mapping, you can configure the association so that when you delete a parent all of the children are also deleted. For an example, see these mappings and the test case (method – testCascadedDelete).

In a cascaded delete, first the children get deleted and finally the parent. But the children are deleted one at a time. Instead of say (delete from child where parentId=xx;). I wonder if there is a hibernate setting for optimizing MySQL statements (assuming that a single delete is more efficient than multiple ones).

Lazy initialization with Hibernate and Spring

August 26, 2007

If are new to Hibernate and Spring, you may have come across the following exception:


net.sf.hibernate.LazyInitializationException Failed to lazily initialize a
collection - no session or session was closed

This problem surfaces when you try to create a hibernate mapping to model a parent child association so that the database query to get the children is executed only when you attempt to access the set of children (and not before). This is the so called lazy initialization of a collection, the alternative is to perform eager initialization where the query to get the children is executed when the parent object is created.

To get lazy initialization to work, you need to understand how to configure Spring, how to create the correct hibernate mapping files, and in particular, the life cycle of the hibernate session object.

Spring provides a number of abstractions to make working with hibernate easier and more efficient. With respect to hibernate sessions, Spring offers a number of options depending on whether you’re writing a servlet or not. In the case of the servlet, you can use Spring’s OpenSessionInViewFilter class which ensures that the hibernate session is attached to the thread that is processing the entire HTTP request. If you’re writing an application or a JUNIT test case, for example, then you need to ensure that transaction synchronization is happening per thread. See the JUNIT setUp and tearDown methods here for how to do this.

I started writing a sample hibernate/spring application to test how lazy initialization and cascaded deletes work. The sources of this sample can be accessed here. Whist I was doing this work, I came across this excellent description on how to test hibernate and spring.

Spring configuration with property files

August 1, 2007

The Spring configuration files can include values from your properties files. You can easily customize this so that you can take control when the key and or the value of a property is requested. To do so, you must first tell Spring the location of your properties file:


<beans>
  <bean class="com.mycompany.MyPropertyPlaceholderConfigurer">
    <property name="locations">
       <value>classpath:my.properties</value>
    </property>
  </bean>
...

Next you must create the class:
com.mycompay.MyPropertyPlaceholderConfigurer:


package com.mycompany;
import java.util.Properties;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import com.adobe.hs.spdf.common.PropReader;
public class MyPropertyPlaceholderConfigurer extends
   PropertyPlaceholderConfigurer {

   // process the key and then return the associated value...
   protected String resolvePlaceholder(String placeholder, Properties props) {
	String value = process-the-key-and-lookup-the-value;
	return value;
   }
}

Finally, you can use the Spring’s ${...} notation to reference values from your properties file. e.g.,

Spring & Hibernate’s not mapped problem

July 20, 2007

I’m sure that many hours must have been spent by Spring/Hibernate users trying to figure out why they are getting the table not mapped exception when they are sure that have mapped the table. Well the problem can be fixed if you take care of the case (upper vs. lower case). Suppose that the name of your table is user and the name of the your class is User.Here is the crux of the problem:This is the wrong version that leads to the not mapped exception:getHibernateTemplate().find("from user");Here is the correct version:getHibernateTemplate().find("from User");You see the problem is that in the hibernate version of the SQL, you are expected to use the name of your class and not the name of the table. Typically, the name of the table is all in lowercase and the name of the class starts with an uppercase. Yep programming can be very frustrating.

Spring with ActiveMQ

July 3, 2007

Spring provides an abstraction for dealing with JMS. Specifically for adding and removing messages to a JMS queue and for browsing a queue. I found the documentation for removing messages from a queue, i.e., consuming messages in the context of a servlet to be somewhat scant. Here is what I had to do configure Spring to send and consume messages. (more…)