Thursday, August 27, 2009

Hibernate session and Wicket filters

I am working on a web application with Spring, Hibernate and Wicket. I need to define Hibernate session filter in web.xml for "open session in view". But I kept getting Hibernate errors when the app started. The fix, as noted in "Wicket in Action", is to define Hibernate session filter ahead of Wicket filter in web.xml.

Here is a complete web.xml as example.

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">

<display-name>skills</display-name>

<!-- Hibernate session filter -->
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>


<!--
There are three means to configure Wickets configuration mode and they
are tested in the order given. 1) A system property:
-Dwicket.configuration 2) servlet specific <init-param> 3) context
specific <context-param> The value might be either "development"
(reloading when templates change) or "deployment". If no configuration
is found, "development" is the default.
-->

<filter>
<filter-name>wicket.skills</filter-name>
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
<init-param>
<param-name>applicationClassName</param-name>
<param-value>com.guident.skills.web.SkillsWicketApplication</param-value>
</init-param>
<init-param>
<param-name>configuration</param-name>
<param-value>development</param-value>
<!--
change "development" to "deployment" for production
<param-value>deployment</param-value>
-->
</init-param>
</filter>

<filter-mapping>
<filter-name>wicket.skills</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>


<!-- Spring context loader -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml
classpath:service.xml
classpath:dao.xml
</param-value>
</context-param>


</web-app>

Create MySQL Triggers

I need to create a trigger in MySQL in the GUI tool Query Browser. However, I kept running into syntax errors. It turns out that I had to specify a delimiter other than ";" like the following.

Delimiter $$

CREATE TRIGGER tr_skill_path BEFORE INSERT ON skill
FOR EACH ROW
BEGIN
DECLARE parent_path CHAR;

IF NEW.parent_skill_id is not null THEN
select path into parent_path from skill where skill_id = NEW.parent_skill_id;
END IF;

IF parent_path is null THEN
SET NEW.path = CAST(NEW.skill_id AS CHAR);
ELSE
SET NEW.path = CONCAT(parent_path, '.', CAST(NEW.skill_id AS CHAR));
END IF;
END$$

Delimiter ;

This made it pass the syntax error. But another error came up:
Access denied; you need the SUPER privilege for this operation

According to MySQL Manual, "SUPER privileges are administrative and can only be granted globally". So it won't work if the grant is only for the schema. More on this later...

Map boolean in Hibernate

How can you map Y/N in database as boolean in Java with Hibernate?

1. Java
private boolean trainingOnly;
// getters and setters

2. DB
training_only VARCHAR(1) DEFAULT 'N',

3. hbm.xml
<property name="trainingOnly" type="yes_no">
<column name="training_only" length="1" />
</property>

Monday, August 24, 2009

Increase Selenium timeout value

I am testing a slow loading page with Selenium (html recorded by Selenium IDE) but it always fails due to timeout. The default timeout value is 300000, i.e., 30 seconds. I know, I know - it is plenty of time and something needs to be done to that page. The question here, however, is how to increase Selenium's timeout to get the test passed.

I can specify the timeout value at the beginning of the html script like

<tr>
<td>setTimeout</td>
<td>600000</td>
<td></td>
</tr>

Now the test passed happily.

Friday, August 21, 2009

Spring test & JUnit

Spring 2.5.x works with JUnit 4.4 but not JUnit 4.5+. You will run into org/junit/Assume$AssumptionViolatedException. This was fixed in Spring 3.0.

http://jira.springframework.org/browse/SPR-5145

Maven test resources

In a Maven project, it is recommended that you keep your test resources in src/test/resources, separate from src/main/resources. However, a lot of times, or most of the time, the resources are pretty much the same, such as service.xml, dao.xml, log4j.properties etc. When you work on a new DAO in TDD fashion, you would add the definition in src/test/dao.xml first and copy it to src/main/dao.xml once it works as expected. It becomes a hassle to maintain both places. I would say why not share the main resources with test. You can do it literally this way: tell test to use main as resouces.

<testResources>
<testResource>
<filtering>false</filtering>
<directory>src/mail/resources</directory>
</testResource>
</testResources>

Spring ContextLoaderListener ClassNotFoundException

I ran a Java web application with Maven, Tomcat in Eclipse. When the application started, Eclipse console has the exception:
java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener

Of course, I did not forget to define Spring dependency in Maven pom.xml. But when I checked the deployment at
ECLIPSE_WORKSPACE\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\APPLICATION\WEB-INF\lib
, there was no Jar indeed. So it looked like something went wrong with Eclipse/Tomcat/Maven deployment.

I did a couple of things to make it work.
1. Get rid of duplicated classes. For example, the dependency on spring-aspects also brings in spring-beans and spring-core, which are already part of spring dependency. Tip: use "mvn dependency:tree" to the dependency tree. So I need to exclcude it by
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>2.5.6</version>
<!-- exclude spring-beans which is part of spring-2.5.6.jar -->
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
</exclusions>
</dependency>
2. Right click project > Maven > Update Project Configuration. Disable and re-enable Maven dependency management if necessary.

Now I found all the required jars in the right place. I started the application and no error!

This seems to be a glitch with Eclipse Maven plugin. I need to keep an eye on it.