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:
-
<value description="body">
-
&lt;p align="justify"&gt;London is the largest urban area and capital of England and the United Kingdom. &lt;p&gt;
-
</value>
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:
-
<s:property escape="false" value="body"></s:property>
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.
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!
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.