SPEL! I conquered you on a Friday!

Today is my first attempt at using SPEL. After a mighty struggle, I was able to conquer it!

Background:

I needed a year variable for some work on a jsp page. It’s not always defined. I know for our routable datasource, a default year is required in order for it to work. I wanted to use the same default year but I only want the variable to be defined once and used in both places.

So I looked into SPEL.

It seems like the correct solution for the problem.

My original idea:


As it turns out, SPEL does not yet support embedded variables. SPEL, you must improve yourself!

My workaround:

I do not love it but it accomplishes my goal of not defining it more than one place.

Define the variable in a properties file e.g. application.properties
defaultYear=2011

Then use placeholder instead of SPEL notation to include it in spring.

Syntax grrr syntax:

Sadly some of my time was to learn the fact you CANNOT put a space between # and { in SPEL. For example, # {bean.property} will NOT work, but #{bean.property} will. It seems obvious afterwards but the error message you get just DOES NOT help you come to that conclusion.

Moral of the story:

SPEL is very handy but it’s yet perfect. Do keep that in mind as an alternative solution when dealing with Spring. If you use annotation, you can do @Value(“#{bean.property}”). Refer documentation for more info.

Grails: I will not use you

After the cijug presentation on Grails, I’ve decided I will not use it.

I know Grails is hot and cool but I don’t like it. It’s probably just a personal preference.

Why don’t I want to use Grails

  • It’s built on spring and hibernate, so why not just use them directly?
  • It’s just adding another layer of complexity. Now if something goes wrong, you need to know grails (groovy) plus all of the frameworks it uses underneath.
  • The generation bit is nice but personally I want control over all of the magic. You will need to modify them anyway. So why not just write them from scratch and LEARN YOUR HTML? This reminds me of the old Microsoft FrontPage HTML generation that always bit my ass when I first started creating web pages. But it probably wouldn’t be as bad since Microsoft was targeting their own browsers with the HTML generated.
  • The URL mapping is stupid. Spring’s innate annotation style mapping is so much easier.
  • I’m not a fan of the taglib. Why do I ever want to write HTML in Java? It makes me feel dirty. Plus it’s harder to debug. Personally the only “taglib” I like is facelets’ version. It felt more like writing HTML.

The only thing I really liked about Grails based on the presentation is the orm custom mapping. I prefer that over hibernate’s innate xml or annotation.

class Person {
  String firstName
  static mapping = {
      table 'people'
      firstName column:'First_Name'
  }
}

But that’s hardly worth a complete switch.

During the whole presentation I was thinking of a pyramid:

I remember not too long ago Spring and Hibernate are the newest and coolest kids on the block. Now we are just piling it on. What will we add next? I mean do you still need know Java any more to support applications? You really just need tons and tons of framework knowledge. Where do you get these knowledge from school? They are not going to teach them in college.

Spring row mapper

A coworker and I were chatting regarding spring rowMappers and I did a little more research and found the following:

Spring’s simpleJdbcTemplate deprecated methods with parameterizedRowMapper in spring 3. The class ParameterizedRowMapper is not deprecated.

Spring’s jdbcTemplate however only has methods that take RowMapper<T> so it will continue to work with parameterizedRowMapper.

But it seems to me the direction of Spring is to go back to use genericized rowMapper e.g. RowMapper<T>. So for all of my new mappers, I will probably implement RowMapper<T> instead of ParameterizedRowMapper<T>.

Spring: check if a column exist using resultset

If you have a strange requirement in the rowMapper to check if a column exists or not, you could try to catch a SQLException of invalid column name or you could try:

public static boolean doesColumnExist(String columnName, ResultSet rs) throws SQLException{
	ResultSetMetaData meta = rs.getMetaData();
	int numCol = meta.getColumnCount();
	for (int i = 1; i <= numCol; i++) {
		if(meta.getColumnName(i).equalsIgnoreCase(columnName)) {
			return true;

		}

	}
	return false;
}

How to execute IN() SQL in spring jdbcTemplate

So for a long time, I wondered how you’d do the sql IN() using spring jdbcTemplate. Today I had an opportunity to work it out.

Normally I used

List Foos = jdbcTemplate.query("select * from foo where name = ?", 
	new Object[] { "foo1" }, 
	new FooMapper()
);

It’s not too friendly if you do

select * from food where name in ('foo1', 'foo2')

If you wish to use the “where in” sql, there is a pretty elegant way to do it in spring since spring 2.0 actually. I didn’t find out until today.

NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
MapSqlParameterSource parameters = new MapSqlParameterSource();
parameters.addValue("names", Arrays.asList("foo1", "foo2"));
List Foos = namedParameterJdbcTemplate.query("select * from foo where name in (:names)",
	parameters,
	new FooMapper()
);

Spring loading properties from database with a twist

Watched the spring framework 3.1 webinar today and it was pretty interesting.

Anyway, at work we are trying to possibly load property values from a database to resolve some tension between the developers and system specialists.

I played a little bit at home as how we would set this up. This is not a new issue obviously; many have solved it previously. I did it partly as an exercise to familiarize myself with cygwin, maven and intellij as they are the new tools I will be using at my new job :)

The things to accomplish

  • Load properties to replace placeholders in spring config from both .properties file and a database table
  • The configuration table will contain properties for more than one application
  • Use another .properties file to initialize the datasource for the database configuration table.

Main libraries used

  • Spring (3.0.3.RELEASE)
  • H2 database (1.1.118)
  • Spring modules (0.8a)
  • Commons-configuration (1.6)
  • JUnit (4.5)
  • Spring-test (3.0.3.RELEASE)

I first created a simple project via maven. I assume you have maven installed with shell/batch access.

mvn archetype:generate -B -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.0 -DgroupId=net.pureessence -DartifactId=DatabaseConfiguration -Dversion=1.0 -Dpackage=net.pureessence.example

How I wired up the configuration datasource

I created a factory to create the datasource using org.apache.commons.dbcp.BasicDataSourceFactory.createDataSource(properties) and loaded the initial datasource properties statically via the class loader. For more information on the property keys used by BasicDataSourceFactory.createDataSource, visit this test case.

public static DataSource createDataSource(String propertyFilename) throws Exception {
    Properties properties = new Properties();
    InputStream in = PropertiesDataSourceFactory.class.getClassLoader().getResourceAsStream(propertyFilename);
    properties.load(in);
    in.close();

    return BasicDataSourceFactory.createDataSource(properties);
}
<bean id="dataSource" class="net.pureessence.example.PropertiesDataSourceFactory" factory-method="createDataSource">
    <constructor-arg type="java.lang.String" value="databaseForConfiguration.properties" />
</bean>

How I wired up the configuration

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
    p:location="classpath:env.properties"
    p:properties-ref="commonsConfigurationFactoryBean"/>

<bean id="commonsConfigurationFactoryBean" class="org.springmodules.commons.configuration.CommonsConfigurationFactoryBean">
    <constructor-arg ref="databaseConfiguration"/>
</bean>

<bean id="databaseConfiguration" class="org.apache.commons.configuration.DatabaseConfiguration">
    <constructor-arg type="javax.sql.DataSource" ref="dataSource"/>
    <constructor-arg name="table" value="configuration"/><!— configuration table name —>
    <constructor-arg name="nameColumn" value="application"/><!— name column —>
    <constructor-arg name="keyColumn" value="key"/><!— key column —>
    <constructor-arg name="valueColumn" value="value"/><!— value column —>
    <constructor-arg name="name">
    <util:constant static-field="net.pureessence.example.Constants.APPLICATION_ONE"/>
    </constructor-arg><!— name (specific configurations) —>
</bean>

<bean id="person" class="net.pureessence.example.Person"
    p:firstName="${first.name}"
    p:lastName="${last.name}"
    p:email="${email}"
    p:car="${car}" />

The property key “car” is loaded from env.properties while “first.name”, “last.name” and “email” properties are loaded from the database table.

Why it works

In order to load configuration/placeholders from a database table, the datasource has to be instaniated prior to the instaniation of all of the other beans with placeholders. The databsource factory creates the instance of the datasource via another properties file loaded outside of spring.

Note about the tests

The tests are set up to load the H2 database with the configuration table & data prior to the loading of the spring context in order for it to work.

Source code

It contains both intellij and eclipse project files. You should have the m2eclipse plugin for eclipse installed in order to pull down the jars in pom.xml.

»>Git Repository