How to test HTML code with dbunit

Posted by Martin Homik | Posted in Java, WebApp | Posted on 22-04-2008

2

As you know, I am working with AppFuse, and one important part of AppFuse is testing. To do that, you need sample data which is imported into the database. The dbunit sample data specifications says, that you can use any parsed character data as value but it does not say how to add html snippets into the database. To do that, you have to escape html entities. Below is an example for a body value element of table storing blog posts:

  1. <value description="body">
  2. &amp;lt;p align="justify"&amp;gt;London is the largest urban area and capital of England and the United Kingdom. &amp;lt;p&amp;gt;
  3. </value>

How to display html snippets in Struts2

Posted by Martin Homik | Posted in Java, WebApp | Posted on 22-04-2008

8

The second problem, I solved today, was to display html snippets in Struts. These snippets were stored in a POJO. If you use the usual Struts property element for displaying data, it will escape html code. Hence, you have to turn off escaping:

  1. <s:property escape="false" value="body"></s:property>

Windows and Whitespaces

Posted by Martin Homik | Posted in Java | Posted on 08-04-2008

0

Sometimes, it is really tough to work on Windows. Because of sticking to old habits, errors occur and you have to find them. Today, I was using Maven for a project. Suddenly, the download of an Ant jar stopped with an exception. The reason was a whitespace in the path:

C:\Dokumente und Einstellungen\…

To correct it, I had to change the maven path in the settings to good old DOS style:

C:\Dokume~1\…

This is so annoying. The error is documented for AppFuse here and here.

Automatic time-stamping of persisted data

Posted by Martin Homik | Posted in Java, WebApp | Posted on 08-04-2008

2

In my scenario, I want to know when a persisted object has been modified. This information should be stored in the database. There are a few approaches to do that.

  • In the database — I’ve read this suggestion somewhere that you can set a trigger. However, not all databases support this feature. Moreover, database independence is crucial. Setting a trigger as Java Annotation or property would be more convenient.
  • AOP — Write a Spring aspect that intercepts calls to Hibernate/Database and add the current time-stamp to the appropriate field.
  • JPA @Version — This was a promising approach. Unfortunately, edited objects were not updated but newly inserted. See a description here.
  • JPA Listeners – by implementing JPA listeners and using @PrePersist annotations this would be the most convenient and elegant way to implement the requirement. For some reason, entity listeners don’t work with AppFuse/Hibernate. Speculations point to Hibernate not supporting this feature.
  • Hibernate Interceptor – Similar to an aspect, one could implement a Hibernate Interceptor. However this approach bind the application to a specific Persistence Framework and prevents other persistency options in future. While this is a nice decision, one has to bear in mind that JPA is a small subset of features provided by each persistence framework. Hibernate is by far much more expressive than JPA and offers much more support than other frameworks. I fear that in the future, I will decide in favour of Hibernate as it offers much more support.
  • Manual — probably the worst solution is to leave the developer in full control. That is, he has to care that a timestamp is added and modified whenever an object is edited. This approach error-prone as changing the modified time-stamp can be forgotten. Morever, there can be a delay between setting the modified time-stamp and the actual persist action to the database.

The only option left is to give Spring AOP a shot. Let’s go!

Search with SQL

Posted by Martin Homik | Posted in Java, WebApp | Posted on 07-04-2008

0

Today I came across a wonderful Hibernate extension called Hibernate Search. If you have ever developed a web application with Hibernate which offered search, then you might have experiences the painful text search implementation with SQL/HQL. The truth is, SQL does not address the problem of text search in a way as we are accustomed to from Google Search. Just writing generic queries using like expressions with wildcards does not fulfil performance requirements.

This problem is actually addressed by Lucene. However, in a web application were the domain model is a key part of the business logic, Lucene is not easy to integrate. Problem such as structural mismatch, synchronization mismatch, and retrieval mismatch have to be solved. To bridge the gap and to provide the best things from both worlds, Lucene is now integrated into Hibernate. Search queries can be issued against the database or against Lucene in a transparant way. Search performance increases a lot and the developer has a very comfortable way to state queries and to provide results.

Class Serialization

Posted by Martin Homik | Posted in Java | Posted on 26-03-2008

0

In the past two weeks or so I have been fighting with different IDEs such as Netbeans, Eclipse, and IntelliJ. Though Eclipse is highly customizable, it can give you a very hard time. In particular when you have a J2EE package and validation is turned on. Then you get hundreds of errors and warnings. Lucky me, I was able to change the settings for my webapp project and to ignore many of the issues.

However, I came across a serialVersionUID warning which has been annoying several times before. In principle, you have to set a public, static, and final field of type Long for each class that implements the Serializable interface. I never knew how to come up with a suitable value, but a strength of Eclipse is to provide QuickFixes for many issues. In my case, I just pressed the almighty Ctrl+1 combination which offered to add a serialVersionUID field including a pre-calculated Long value. Cool.

By the way, a good online resource is here.

Bug in Maven Surefire Plugin

Posted by Martin Homik | Posted in Java, WebApp | Posted on 26-03-2008

0

On March 18 i tuned on my Laptop in the office ran a Maven build command on my project and it suddenly stopped with exceptions that pointed to Spring’s Beanfactory which was unable to load a bunch of beans. This was strange, because the evening before everything passed my JUnit tests. What happened?

I consulted AppFuse’s User group and found a thread which described my problem. Unfortunately, no good solution has been proposed. The author pointed to a Jira Issue in which a work around is described, but well, it’s not a good solution. A few other guys joined in the discussion, but none was able to solve the problem.

Today morning, I digged a bit deeper in it. I recalled March 18. One thing you have to know about Maven is, that by default, prior to compiling, it checks for new jar versions every day and downloads them. So I looked into my local m2 repository and found out that Maven downloaded the latest surefire plugin. I went to its web site and found a Jira bug report describing exactly the problem. However, the problem is still unresolved. But now that I know which version of the plugin caused the problem, I told my Maven project description not to use it and to use a previous version instead. Just add the follwing snippet to your build plugins section:

  1. <plugin>
  2.    <groupId>org.apache.maven.plugins</groupId>
  3.    <artifactId>maven-surefire-plugin</artifactId>
  4.    <version>2.3</version>
  5. </plugin>

Guess what, it solved my problem. And that makes my day. :-)

Entity Versioning in AppFuse

Posted by Martin Homik | Posted in Java, WebApp | Posted on 26-03-2008

0

It’s time to write a few words about some things I have learned in the past week. The first thing I want to mention is versioning. So far, whenever I updated and persisted objects to the database, I calculated the modified time myself which is not that bad. But persistence layers such as Hibernate actually can do that for you. To prevent two users from writing to the database at the same time, locking techniques are provided. One such technique is called optimistic locking which is implemented by using versioning either with integers or with timestamps. If you select timestamps, the only thing you have to do is to specify which of the entity fields is supposed to be in charge of the version. Add a @Version JPA annotation to the field. Any persistence framework that is compliant to JPA will calculate the modified data for you and persist it to the database.

Find more explanations here and here.For Hibernate users the Java Persistence with Hibernate Book is the best choice.

The drawback of this approach is that once you edit an object, Hibernate creates a new revised object instead of altering the actual one. That’s a pity and does not serve my purpose in a current project. I am confused, because the book Hibernate in Action describes the versioning process differently: alterations are updates and no inserts. I am not able to resolve this issue.

Resolving Dependency Conflicts in Maven

Posted by Martin Homik | Posted in Java | Posted on 12-02-2008

0

Today, I ran into a problem which turned out to be a Maven dependency conflict. It all began with running a a set of JUnit tests on my AppFuse project with MySQL as backend. Even standard add/remove tests on the simplest class terminated with an InvalidDataAccessResourceUsageException caused by Hibernate. When I switched to PostgreSQL, all tests were successful.

At first, I thought that the error originated in MySQL or in my POM parameters, but I could not find anything on the net that confirmed my suspicion. Eventually, I came across a Hibernate Jira issue, which explains that particular behaviour. Hibernate did not specify any value for row id.

I searched AppFuse’s POM for a Hibernate dependency and found this: the POM itself does not state that it requires a specific Hibernate version. But it relies on AppFuse’s static repository and its dependencies which are implicitly present in my POM. However, I’ve been working with hyperjaxb3 recently which depends on an hibernate-entitymanager of version 3.3.1.ga which in turn includes a buggy Hibernate jar mentioned in the issue. As hyperjaxb3’s dependency versions are lower than those of AppFuse, Maven decided to use the lower version to get things running. Hence, the problem.

Now, to solve the problem you can either remove hyperjaxb3’s dependency or just change tge version to a version range.

  1. <dependency>
  2.    <groupid>org.hibernate</groupid>
  3.    <artifactid>hibernate-entitymanager</artifactid>
  4.    <version>[3.3.1.ga,]</version>
  5.    <scope>test</scope>
  6. </dependency>

The range means that Maven should use the latest available hibernate-entitymanager, but no older than that of version 3.3.1.ga.

Maven Archetypes

Posted by Martin Homik | Posted in Java | Posted on 11-02-2008

0

Assume you are a beginner and someone tells you to implement a JAR, J2EE, portlet or some other project. How should you start? How should you organize your project? To base your project on best-practice use Maven’s archetype plug in. Just select the project type you would like to have and let the Maven create the structure for you. Version 1.0-alpha-7 supports the following archetypes:

  • maven-archetype-archetype
  • maven-archetype-j2ee-simple
  • maven-archetype-mojo
  • maven-archetype-portlet
  • maven-archetype-profiles (currently under development)
  • maven-archetype-quickstart
  • maven-archetype-simple (currently under development)
  • maven-archetype-site
  • maven-archetype-site-simple
  • maven-archetype-webapp

Take some time and create different projects and explore its differences. It will provide you with a broader overview and you get the feeling for how to set up projects and what kind of files are needed for a project. A few more archetypes can be found here.

The latest snapshot of Version 2.0 provides even more archetypes and a much more convenient way to create projects. Try it!