2011-12-13 OpenMRS University

If people are in agreement, I would like to address some proposed issues relating to Hibernate from the wiki/notepad page:
? How to extend an OpenMRS object
? How to set up a relationship with an OpenMRS object
? How to do subclasses correctly
These are of current interest to me due to the following use case:
1. The current Order object does not have a column for urgency ("stat" orders)
2. The current Order object only allows for a single specimen per order, when there are cases when multiple specimens must be taken for a single order

I believe this issue has previously been addressed in https://openmrs.atlassian.net/wiki/display/docs/Extending+a+Table+Through+a+Module but I find this hard to comprehend (perhaps because it is too specific to the Encounter use case). Also, it appears that it supplants the core Encounter table with a module-defined Encounter table. I am concerned that this may not be the best practice because it means that other modules cannot also extend Encounter.

I have been thinking in terms of two tables, one which would be an auxiliary orders table that would contain the urgency field and have a 1-1 relationship with orders, and the other of which would be a relationship table that would relate orders table rows to 0:n specimen rows. I would prefer to leave core blissfully ignorant of these tables. My questions:
(1) What are the right Hibernate declarations for these tables?
(2) How much of the audit info should be included in each table?
(3) Is it a good idea to write the DAO layer so that the two tables appear as a single table or should only the methods associated with the auxiliary table be addressed?
(4) How should the save be handled?

LabOrder.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="org.openmrs.module.jsslab.LabOrder" table="jsslab_order">
	<id name="orderId" column="order_id">
		<generator class="foreign">
		<param name="property">order</param>
		</generator>
	</id>
	
	<one-to-one name="order" class="org.openmrs.Order" constrained="true" />
   	<property name="urgent" type="java.lang.Boolean" column="urgent" not-null="true" />
   	<many-to-one name="retestOf" class="org.openmrs.module.jsslab.LabOrder" not-null="false" column="retest_of" />
	<property name="physicianRetest" type="java.lang.Boolean" not-null="false" column="physician_retest" />
	<property name="retestReason" type="java.lang.String" column="retest_reason" length="255" />

	<property name="uuid" type="java.lang.String" column="uuid" length="38" unique="true" />

	<set name="specimens" inverse="true" >
		<key column="order_id" not-null="true" />
		<one-to-many class="org.openmrs.module.jsslab.LabOrderSpecimen" />
	</set>
	
</class>
</hibernate-mapping>

LabOrderSpecimen.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="org.openmrs.module.jsslab.LabOrderSpecimen" table="jsslab_order_specimen" >
        <id name="orderSpecimenId" type="int">
            <column name="order_specimen_id" />
            <generator class="native" />
        </id>

		<many_to_one name="labSpecimen" type="org.openmrs.module.jsslab.LabSpecimen" column="lab_specimen_id" not-null="true" />
		<many_to_one name="labOrder" type="org.openmrs.module.jsslab.LabOrder" column="lab_order_id" not-null="true" />
				
      	<many-to-one name="creator" class="org.openmrs.User" not-null="true" column="creator"/>
		<property name="dateCreated" type="java.util.Date" column="date_created" not-null="true" length="19" />
		<many-to-one name="changedBy" class="org.openmrs.User" column="changed_by" />
		<property name="dateChanged" type="java.util.Date" column="date_changed" />		
		<property name="voided" type="java.lang.Boolean" column="voided" length="1" not-null="true" />
		<property name="dateVoided" type="java.util.Date" column="date_voided" length="19" />
		<property name="voidReason" type="java.lang.String" column="void_reason" length="255" />
		<property name="uuid" type="java.lang.String" column="uuid" length="38" unique="true" />

    </class>
</hibernate-mapping>