Category Archives: adabas

Adabas D, hibernate and compound primary keys

lastly, My (least) favourite application here at work, that beauty that uses Adabas D as the database server, also makes liberal use of compound keys. However, in our useage, one portion of that key is always fixed, so when I started trying to replace a lot of the raw jdbc with hibernate as I mentioned earlier, I just put the fixed portion as a regular column, and labelled the varying column with the @Id notation. This worked just fine for reads, and for most of the basic writes we were doing at the time. (Where the write simply changed a field in the table) However, when we tried to update an object property, (By object I mean, myObject.complicatedChild = blah, not just myObject.integerField = wop) it all failed.

Error: ASSIGNMENT IMPOSSIBLE, CHAR VALUE TOO LONG
SQLState:  22001
ErrorCode: -2010

Excellent…..

SAP isn’t very helpful on what that means, it seems to just try and say that, well, you tried to put too big a char value into a char column. Like hell I said, but went off to hibernate debugging to see just what exactly was going on. Which led me to discover that the hibernate code simply wasn’t working!

The generated hibernate code:

update TABLE set
FIXED_PART_OF_KEY=3,
ID_OF_OTHER_OBJECT=4
where REGULAR_PART_OF_KEY ='somekey'

This by itself was failing! but if you take out the FIXED_PART_OF_KEY from the update though, it all works just fine! (This was actually a longer process of elimination, with a lot more rows initially) So, even though there is only one row where the regular part of the key matched “somekey” I went ahead and converted to fully using compound keys across the project, suspecting some inanity from within.

And low and behold, it all started working again. Hooray!  I use the @IdClass method, as it seems to fit our code best.

So:

  1. add @IdClass to original entity
  2. remove @Column attributes from the original ID entity, and put them in the new IdClass
  3. put @Id attributes on both columns in the original entity
  4. add equals and hashcode implementations to the IdClass, and mark as @Embeddable
  5. Add a constructor to the IdClass to deal with the “fixed” portion of the key

Lastly, any other object that was referencing this just by the regular part of the key now needs to be updated as well. so @JoinColumn get’s replaced with @JoinColumns, and the dangling property for the unused fixed portion of the key is deleted.

Moral of the story? Don’t use Adabas D, it’s archaic and has a terribly old jdbc driver. Don’t use Compound Keys if you have a choice. It just causes extra pain.

Versions used: hibernate 3.2.6GA and java 6. JDBC driver for adabas provided by SAG.

Adabas D, Cirpack and Hibernate

It’s more possible than you think!

Use org.hibernate.dialect.SAPDBDialect as the hibernate dialect, and it seems to be good to go. I’ve had to use @IdClass and create @Embeddable key classes for all the cirpack compound keys, but for simple read and edit, this has let me use hibernate, instead of raw JDBC. Hooray for that!

I haven’t figured out a pretty way of dealing with Adabas columns specified as “int” that are only ever used as booleans, but I can live with that for now.

Unfortunately, you _do_ have to actually specify the dialect, as hibernate won’t work this one out on it’s own. Tested with a 2001 dated version of adabasd.jar, and hibernate 3.2.6GA