- 09 Aug 2008 -

When writing a dbunit test for the CohortServiceTest, I encountered this non-informative error:

org.dbunit.dataset.NoPrimaryKeyException: COHORT_MEMBER

In the Cohort mapping file the cohort_member table is mapped like any hibernate collection:

<set name="memberIds" cascade="none" lazy="true" table="cohort_member">
    <key column="cohort_id" />
    <element column="patient_id" type="integer" />
</set>

It looks normal enough.  Cohort.memberIds is a list of integers defined by the cohort_member table.

Hibernate automatically creates the schema in our test hsqldb because we have hbm2ddl set to “auto”.  The problem arose here because hibernate wasn’t creating a dual primary key on the member_ids table.  Digging through the code, I found that Hibernate only assumes the primary keys are the columns that set to “not null”.

The corrected mapping with both columns set to be not-null:

<set name="memberIds" cascade="none" lazy="true" table="cohort_member">
    <key column="cohort_id" not-null="true"/>
    <element column="patient_id" type="integer" not-null="true"/>
</set>

Now hibernate creates the table with primary keys and hsql is happy again.

This is in the openmrs category tagged as , , , ,

4 comments »

While migrating from JUnit 3.x to the new 4.x framework, one method I found that was missing was Spring‘s getLoadCount() method on the
AbstractDepenpendencyInjectionTest. The value returned allowed us to tell whether a test was running by itself or in a group a tests (like with the ant junit-report target or right-clicking on /test/src and choosing run-as junit test).

Having this method was useful for two reasons:

  1. A test like CreateInitialDataSet that is meant to be configured and run alone.  If this test sees that its being run in a group, it returns early and doesn’t actually run the test
  2. The module tests needed to have the application context refreshed before running.  To do this, I made the previous test mark the context as “dirty” so that the test directly following it would have a fresh app context.

There were actually two separate solutions:

  1. All tests extend BaseContextSensitiveTest for convenience methods and setup.  Every junit class will invoke this class and its constructor.  By adding a static variable loadCount and incrementing that in the constructor, I am able to know how many tests have been run up to that point.
  2. The application context doesn’t need to be marked as dirty.  The dummy method could actually be removed without replacement.

This is in the openmrs category tagged as , ,

Add a comment »