I ran into a stupid problem yesterday when I was trying to setup Spring + Hibernate with HSQLDB. Everything looked fine except it didn’t work… The error I got was the following:

org.springframework.jdbc.BadSqlGrammarException: Hibernate operation: could not insert: [com.company.domain.Payment]; bad SQL grammar [insert into Payment (paymentId, customerId, orderId, paymentReferenceNumber, sum, validTransactionDate) values (null, ?, ?, ?, ?, ?)]; nested exception is java.sql.SQLException: Table not found in statement [insert into Payment (paymentId, customerId, orderId, paymentReferenceNumber, sum, validTransactionDate) values (null, ?, ?, ?, ?, ?)]
The error might be obvious to the reader, but it was not for me… A column can’t be named ‘sum’ – ¬†it’s a reserved word in SQL.
Hibernate has the ability to autocreate tables for you but it said eaxactly nothing about failing to do so.
Advertisements

I’m on a new project and have the opportunity to make things right from the beginning. I’ve been trying to include version number and build number into the packaged WAR file. As a bonus I’ve made the version available through a web page like:

Version: MyApp-1.0 (build number 7)

My project is a web service built with maven. TeamCity (5.1.1) is used for building. I use IntelliJ IDEA version 9 as my IDE. With version number I refer to the version in my pom.xml, for instance:

    <version>1.0</version>

Build number refers to the automatically incremented build number in TeamCity.

These are the steps I took:

1. In the TeamCity Build configuration, make sure Build number format includes {0}.

2. Create/edit your project file src/main/resources/application.properties:

    version=${pom.name}-${pom.version} (build number ${build.number})

pom.name and pom.version are Maven attributes defined in the beginning of your pom.xml. build.number is an environment variable set by TeamCity at build time.

3. Edit pom.xml:

<properties>
<!--
When building on TeamCity this property is set as an environment variable by TeamCity and then maven replaces the placeholder in application.properties.
When compiling locally we have to set this property here or Spring will fail to resolve the placeholder in application.properties. This works in IntelliJ (only?) with its feature to filter maven resources.
A cleaner solution is to set up an envrionment variable in the IDE with this name, but this requires new developers to configure the IDE.
-->
  <build.number>Unknown/local build</build.number>
</properties>
...
<resources>
  <resource>
    src/main/resources
    <filtering>true</filtering>
  </resource>
</resources>

This will make Maven replace the variables in application.properties with maven properties and environemnt variable available at build time.

4. Now the packaged application.properties will contain current build number from TeamCity and maven artifact name and version from your pom.xml !

As a bonus I made the version available via a jsp called status.jsp. Getting the version property from application.properties into a jsp can be made in several ways of course. Since my project don’t contain any web stuff (only web services) I created the jsp in a hacky way:

<html><body>
  <p>Version: <%= BusinessServiceImpl.instance.version %></p>
</body></html>

And BusinessServiceImpl:

@Autowired
public String version;
public static StaffDiscountServiceImpl instance;

public StaffDiscountServiceImpl(} {
  instance = this;
}

The version attribute is autowired and defined in Spring’s applicationContext.xml:

<context:property-placeholder location="classpath:/application.properties "/>
<bean id="version" >
  <constructor-arg value="${version}" />
</bean>

There’s certainly better ways of doing this jsp stuff (comments, please!) but this was simple and it works.