Wednesday, July 20, 2005

Using commons EqualsBuilder in JUnit tests

A common JUnit test w/ databases is to create an object (or hierarchy of objects), save them, and then retrieve them back. You want to see if what you put in is what you get out.

These tests can be cumbersome to write, becuase comparing the inserted object with the fetched object will require the following test for each attribute of the class.


assertEquals( insertedObj.getAttribute1(),
fetchedObj.getAttribute1() );


So if there are 20 attributes, you have 20 assertEquals() to perform. And if you should happen to have a collection of child objects too, well, you've really got your work cut out for you.

So one way around this is to use the commons EqualsBuilder class and it's reflectionEquals() method.


import org.apache.commons.lang.builder.EqualsBuilder;
....
public void testStuff()
{
assertTrue("Compare inserted obj w/ fetched obj",
EqualsBuilder.reflectionEquals(insertedObj, fetchedObj));
}


This will do a full comparison of the objects on all of their attributes, instead of using their equals methods. And if you have a collection in your class, it will take the collections and compare them. At the collection level, however, it reverts back to the equals() method on the children of the respective collections (95% sure about that).

Monday, July 04, 2005

Hibernate 2.1.x, calling save() on same object twice causes two INSERTS

Hibernate is not performing as I would expect. When I am saving for the second time, it generates a second insert statement (as opposed to an UPDATE for the 2nd call). It probably has something to do with the specifics of my situation. I am....
  • creating an object

  • saving it within a session

  • later, i try updating this same object handle within the same session (i.e. no re-retrieve)

I really would like to do everything with the save() method, but it seems the solution (for now) lies in which API call I use.
  • save() seems geared towards new instances

  • update() seems geared towards existing ones

Theoretically, there should only be one call, and hibernate should determine this for me. There are references to a method called saveOrUpdate(), but it should only be used when sharing objects across sessions.