Thursday, September 01, 2005

Hibernate inheritance mapping with hsqldb

Hibernate supports three inheritance mapping strategies:
  • table per class hierarchy
  • table per subclass
  • table per concrete class
The first two are pretty straightforward. Basically the first strategy maps the whole class hierarchy into one table, and classes are differentiated by a discriminator column. The second strategy maps the base class into one table, and additional attributes in subclasses are mapped to additional tables joined back to the base table with foreign keys. These two strategies can be combined together, and they are probably the most used in practice.

The third strategy is a little bit trickier. Each concrete class gets its own table, and all the inherited attributes are mapped to that table as well. The tricky part is you cannot use identity database type as the primary key, only sequence is allowed. The reason for this is that all the tables are unioned together so the primary keys have to be shared between the tables.

HSQLDB is a light-weight pure-java database that can be run in-memory and very useful for unit testing. It actually supports sequences, in addition to the identity type. If you specify "native" as the primary key generator, hibernate assumes you are using identity, and the third strategy would fail. So you have to specify "sequence" as the generator:

<id name="id" type="long" column="PAYMENT_ID">
<generator class="sequence" name="my_sequence">
</id>
In addition, when you create the hsqldb tables, you also need to create the sequence:

create table dual_my_sequence (zero integer);
insert into dual_my_sequence values (0);
create sequence my_sequence start with 1;

Since hsqldb lacks the equivenlant of a DUAL table in oracle, you have to create an associated table with one row to select on the sequence:

select my_sequence next value from dual_my_sequence;

There you have it how to configure table per concrete class in hsqldb.

3 Comments:

Anonymous Anonymous said...

It pretty much covers Replica related stuff.

5:29 PM  
Anonymous Devender said...

We have been using HSQL with Hibernate for sometime now, just change the properties for Hibernate to create DDL for unit tests and test our apps aganist the in memory HSQL, the tests run really fast. Some DAO's that we use have some SQLs that are very specific to Oracle, those we just put them in a seperate package and run them as part of integration test aganist Oracle. Check into DB unit, helps create data in HSQL

3:16 AM  
Anonymous Michael Jensen said...

If you don't like the idea of creating a new DUAL table for each sequence, then it's extremely simple to create your own HSQLDialect:

public class MyHSQLDialect extends HSQLDialect {

public String getSequenceNextValString(String sequenceName) {
StringBuffer sb = new StringBuffer(64);
sb.append("select next value for ");
sb.append(sequenceName);
sb.append(" from DUAL");
return sb.toString();
}

}

This will return a query like this
"select next value for SEQ from DUAL"

2:22 PM  

Post a Comment

<< Home