UPDATE: Oddly enough, we are unable to reproduce the error in a JUnit testcase (running in Eclipse). It only occurs in a Tomcat environment, with all other circumstances equal. Could this be a class-loader problem?
Hibernate version: 3.1.2
We have an exotic (legacy) database that uses an extensive table-per-subclass strategy, using discriminators. It involves a multi-level inheritance strategy, so bear with me:
- There is an
abstract "root" class, with it's own table.
- The root table contains a discriminator column (string).
(here it gets tricky)
- The first letter of the discriminator indicates a subclass, with it's own table.
- The second letter
might indicate another subclass, again with a seperate table. There are subclasses that are first descendants of the root object, but a lot are another level deeper, in effect using three tables in total.
abstract class A - table a
class AB extends A - join table ab - discriminator = "b*"
class ABC extends AB - join table abc - discriminator = "bc*"
class ABD extends AB - join table abd - discriminatro = "bd*"
class AE extends A - join table AE - discriminator = "e*"
etc.
We have 8 "first level" subclasses (of which some are not extended) and about 6 second level subclasses.
Top-level , we use a formula discriminator on the top-level object
Code:
formula="substr(typecode, 0, 2)"
and this works reasonably well.
However, it seems Hibernate is having serious problems determining type for some of the second level subclasses. The problem is that there is no way (that we can tell) to indicate that the
first character in the discriminator points to a first level class, while using the second character to drill a level deeper. When trying to ommit the discriminator-value on some of these "intermediate" classes, the subclasses seem to loose type (when using a query)! The net effect is that the results of queries on the root type sometimes contain objects that are instances of the
abstract superclass, which do not load completely and cannot be cast to their proper (second level) type. Individually however, they load just fine. (It is pretty odd that Hibernate succeeds in instantiating an abstract class, but this probably has to do with CGLIB...)
Considering the amount of tables involved, join strategies are not really an option, so we really have to to this entire thing lazy loading (fetch="select" on the subclass joins).
A possible solution would be to have
Code:
discriminator-value
accept some kind of regexp values (in addition to or in replacement of formula's in the discriminator itself). Basically, a formula can only have
one outcome on which Hibernate has to be able decide the specific subclass, whereas in our case this outcome still has to be differentiated to multiple sub-subclasses. It is simply not possible to use either the first character of the discriminator
or the second character, since both substrings have their own specific meaning and inheritance consequences.
Any ideas?
[/code]