DBUnit is a very effective tool for testing persistence layer code. But before we can test any persistence code, we need to “seed” the database with some test data. This is where a dataset comes into picture. I personally like to store this data in an XML file (XML dataset) and load it before a test is run. XML datasets can be easily created by exporting data from an existing database. Here are three simple steps for doing this:
- Create a connection to the database. Using plain JDBC, here is what the code would look like:
Class.forName("com.mysql.jdbc.Driver");
Connection jdbcConnection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","user","pwd");
IDatabaseConnection connection = new DatabaseConnection(jdbcConnection);
- Create a QueryDataSet object and add a query for extracting the data:
QueryDataSet dataSet = new QueryDataSet(connection);
dataSet.addTable("Person", "SELECT * FROM PERSON");
- Save the extracted data into an XML file.
FlatXmlDataSet.write(dataSet, new FileOutputStream("person.xml"));
Each XML element in the dataset created will correspond to a row in the table with the element name being the name of the table. Here is a portion of dataset generated:
<Person ID=”9″ First_NAME=”JOHN” LAST_NAME=”DOE”/>
<Person ID=”10″ First_NAME=”JUDY” MIDDLE_NAME=”B” LAST_NAME=”TEST”/>
<Person ID=”11″ First_NAME=”JANE” MIDDLE_NAME=”S” LAST_NAME=”DOE”/>
An interesting thing to keep in mind is that when DBUnit is used to load this dataset into a database, it would read the first element to figure out the table metadata. Now, if the first element does not have a column (MIDDLE_NAME in this case) included, it would make DBUnit ignore that column in all other elements. This behavior can be avoided by generating a DTD that contains table column information. This is done using the following code:
FlatDtdDataSet.write(dataSet, new FileOutputStream("person.dtd"));
Once the DTD is in place, it can be included in the dataset doctype declaration. In this example, it would look something like: <!DOCTYPE dataset SYSTEM “person.dtd”>
Putting it all in a single method:
public void generateDataSet() throws Exception
{
Class.forName("com.mysql.jdbc.Driver");
Connection jdbcConnection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","mysql");
IDatabaseConnection connection = new DatabaseConnection(jdbcConnection);
QueryDataSet dataSet = new QueryDataSet(connection);
dataSet.addTable("Person", "SELECT * FROM PERSON");
FlatDtdDataSet.write(dataSet, new FileOutputStream("person.dtd"));
FlatXmlDataSet.write(dataSet, new FileOutputStream("person.xml"));
jdbcConnection.close();
}
One one of my recent side projects, I needed to define a set of Spring Beans programatically using a BeanFactoryPostProcessor. Most of the posts online talked about using RootBeanDefinition class. In Spring API, I came across GenericBeanDefinition class that provides an convenient way for bean definitions.
Here is a code sinppet that defines a bean of type String:
String beanName = "testBean";
String beanValue= "testing";
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(String.class);
beanDefinition.setLazyInit(false);
beanDefinition.setAbstract(false);
beanDefinition.setAutowireCandidate(true);
ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues();
beanDefinition.setConstructorArgumentValues(constructorArgumentValues);
constructorArgumentValues.addIndexedArgumentValue(0, beanValue, "java.lang.String");
beanDefinition.setConstructorArgumentValues(constructorArgumentValues);
registry.registerBeanDefinition(beanName, beanDefinition);
If you don’t provide the type (java.lang.String here) as one of the parameters in your ArgumentValue and deploy it as part of a web application, you will run in to wierd propertyeditor issues.
As I was googling, I came across this in the search results:
Interesting idea from google.
Here is a code snippet from a custom JSP tag I ran into today:
try
{
out.write(hoursSelectHTML.toString());
out.flush();
}
catch (IOException e)
{
logger.error("Exception writing to the output stream... ", e);
}
finally
{
try
{
out.close();
}
catch (IOException e)
{
// Simply ignore this exception
}
}return SKIP_BODY;
|
If you are still wondering what is wrong with it, pay attention to the part where the stream is being closed 😉
I was recently in a discussion where I shared that ORM might not be a good tool for applications whose main focus is to:
- provide UI for editing data in the database tables
- simply generate reports of the database data
I feel that ORM is a great tool when you have a solid domain model but from what I have seen, you really don’t need a domain model to “interface” database tables.
Any thoughts??
When running unit tests in a Spring-JPA application, I ran in to out of memory issue. The exact error was:
2008-05-01 14:43:32,944 DEBUG org.springframework.test.context.junit4.SpringMethodRoadie –
Test method public void
…repository.ApplicationHibernateRepositoryTest.testFindApplication() threw exception:
java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: Java heap space
Exception in thread “Thread-2” java.lang.OutOfMemoryError: Java heap space
The cause was that I had an entity with too many relationships to other entities.
A slight overlook fron my side caused all these relationships to be eagerly loaded (added to the fact that this is the default behavior for some associations in JPA).
I just went back and declared the relationships to be lazily loaded (using fetch=FetchType.LAZY) and the error just disappeared.
I believe it is possible to increase heap size for running Junit tests but in this case, I really didn’t need all the entities loaded eagerly.
Locations in Kindle have been a source of little confusion. Put simply, locations are virtual page numbers. Since the font size in Kindle can be changed, each size would create different sets of pages. A location on the other hand is a particular place in a book and is of fixed length. Thus in the event of a font change, a location will not change. Interestingly, non textual elements of a book such as cover have also locations. So when Kindle displays the first page of the book, the location does not start with 1.
A location’s content is smaller than the Kindle screen and hence the bottom of the screen shows a range of locations that are being rendered. For example, the screen in the picture below is displaying content from locations 1399, 1400, 1401, 1402, 1403 and 1404.
To go to a specific location in the book, I simply go to Menu -> “Go to Location” and type in the location number. Also, I found that it is the only way to see how many locations your book has.
Another neat feature in Kindle is the ability to bookmark locations. To bookmark the currently displayed virtual page, simply move the wheel all the way to the top and select it. You will see that the top-right hand corner now shows a fold.
More on locations: Kindle Forum