views:

45

answers:

2

I have currently existing database and hibernate mapping for it. There is a central table and corresponding entity (PersistentObject). Many of the other tables and entities refer to PersistentObject via @ManyToOne or @OneToOne mapping.

Now I'd like to make current PersistentObject abstract and introduce two sub classes Sub1Object and Sub2Object that inherit from PeristentObject.

I can't change the table where PersistentObject is stored, otherwise adding new tables etc is possible. The table contains enough information so that I can use e.g @DiscriminatorColumn to separate Sub1Object and Sub2Object rows if needed.

Is it possible make this change so that my current HQL queries still work without modifications? I have lot of queries like from PersistentObject where foo = ? and from OtherEntity other where other.persistentObject = ?. I'd like that those queries start returning concrete subclasses instead of the super class. I don't want to code separate queries for Sub1Object and Sub2Object.

Is this at all possible? What inheritance strategy I should use?

+1  A: 

You must use table-per-class-hierarchy strategy, because you want to use discriminator column :) As for me, hibernate should work with what you described without any problem. Mapping subclasses as hiberante-aware classes and providing proper discriminator should be enough.

Just be warning, that sometimes instanceof directive will not work, because you will get proxy object, but you can use Hibernate.getClass(Obj...) to check.

Bartek Jablonski
Thanks. I have no requirement to use discriminator column, it is just available if needed.
Juha Syrjälä
+2  A: 

I can't change the table where PersistentObject is stored, otherwise adding new tables etc is possible. The table contains enough information so that I can use e.g @DiscriminatorColumn to separate Sub1Object and Sub2Object rows if needed.

You CAN use a JOINED inheritance strategy (with or without a discriminator). For the top class:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "DISC")
public abstract PersistentObject {

    @Id @GeneratedValue
    private Long id;

    ...
}

And for example:

@Entity
public class Sub1Object extends PersistentObject {
    ...
}

This won't change the existing table.

Is it possible to make this change so that my current HQL queries still work without modifications? I have lot of queries like from PersistentObject where foo = ? and from OtherEntity other where other.persistentObject = ?. I'd like that those queries start returning concrete subclasses instead of the super class.

They will work and will return instances of all persistent classes that extend that class.

Pascal Thivent
Are you sure that the JOINED strategy should work with discriminator column? I tried it and it seems that value for discriminator field is never set.
Juha Syrjälä
I double checked and Hibernate Core supports it, see [9.1.3. Table per subclass: using a discriminator](http://docs.jboss.org/hibernate/core/3.3/reference/en/html/inheritance.html#inheritance-tablepersubclass-discriminator), the JPA spec mentions it, see section **9.1.30 DiscriminatorColumn Annotation**, but it appears that Hibernate Annotations ignores it, see [ANN-140](http://opensource.atlassian.com/projects/hibernate/browse/ANN-140).
Pascal Thivent
Thanks for checking it out. I really wanted to use JOINED with discriminator column. Now I have to use SINGLE_TABLE inheritance with a clumsy mapping to additional table.
Juha Syrjälä