Pencils Down

This weblog is about my experiences in software development

Browsing Posts published in April, 2009

One of our developers had the following type of code in place:

Parent parent = new Parent();
dao.create(parent);
Child child = new Child();
parent.getChildren().add(child);
dao.saveOrUpdate(parent);
dao.create(child);

All of this code worked!  We never noticed the error until we put a Hibernate wrapper in play that has asserts for all kinds of extraneous conditions.  In the above code the child has not been created in Hibernate yet.

So, why did it work in straight Hibernate?  We think it didn’t work and only gave a silent error/exception.  All of this would be cleaned up later as a cleanup task by the create(child) call or the even later flush() call.

Of course, once we switched the order of the create(child) call with the saveOrUpdate(parent) it all worked.

We had noticed similar silent errors for delete() calls as well.

IBM offered to buy Sun at twice the going rate per share.  Sun baulked, supposedly based on wanting more money.  At first blush it sounds like the bonehead move of the year.  But then it doesn’t seem likely price is really the issue.

Sun has nice machines, but they are old school at this point.  Why not just buy a cheap Intel box that runs Linux?  No dealing with Solaris admins or costly hardware additions.

IBM has a good franchise in high-end machines so that seems like a good fit.  IBM has a definite commitment to Java across the company.  Again, a good fit

Overall it would seem this might be a good idea.

Then you start to think about the people at Sun versus the people at IBM: California dreaming vs. Armonk business blue suits.  There is just no way these people could get along.  The Sun people must have been starting protests in the halls as soon as the word got out.

One of our developers came up with some sample code like the following:

//create an entity

Entity e = new Entity();

e.setEntityName(“x”);

EntityId id = dao.create(e);

//attempt to find it

Entity e2 = dao.createQuery(“from Entity where entityName=’x').list.get(0);

//???? e2 is null !!!!!!

//look a different way

Entity e3 = dao.findById(id);

//???? e3 is correctly loaded

The Hibernate cache is id based. So, HQL queries ignore the cache when looking around for matches and go direct to the db (e2), unless id’s are involved (e3).

The choices are then:

- If you need to reference cache objects by other than id (as above), keep a map as you progress

HashMap<String,EntityId> map.put(“x”,id);

Entity e4 = dao.findById(map.get(“x”));

- or flush() as needed so the HQL will ‘work’

I think most of the time this (keeping id’s around) works. For example most DTOs and UI representations are maintaining the id of the object and later retrieving by that id. Unfortunately, I know there are a couple of pain points where the id is not the key of interest so additional coding will have to be used.

Also, flushing continually defeats the whole purpose of having a long running session/transaction.  So, that option is of limited use as well.

This error is a catchall for anything else that might be wrong with your test class.  First make sure any of the below problems are not occurring. 

Your unit test code is running JUnit4.  At least one test method must have the @Test annotation.  Otherwise this error occurs.

If the class you are testing has @Required setters for Spring injections they must be set otherwise JUnit will mask the missing required exception as a no runnable methods exception.

If you are initializing your mock objects outside of the @Begin method you will get this error.

If you are attempting to mock the same class more than once you will get this error.