Recently I came across this line of code:
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mm a");
Unfortunately, this code belongs to a class whose instances will be used by multiple threads. Even though the API documentation for SimpleDateFormat mentions it being not thread safe, somehow it failed to get the developers attention.
As I got to think more about this, a @ThreadSafe JavaDoc element might be useful for API writers to convey their intent more clearly. Perhaps the generated JavaDoc for a thread safe class can use a different color or font making the distinction more visual.
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.