I've employed hibernate's table-per-class-hierarchy as outlined here.
I've got a simple 1-tier hierarchy where the parent includes a number of attributes and the child(ren) include more of the same. There are also relationships to the the object. For example:
@Table(uniqueConstraints = { @UniqueConstraint(columnNames = {"name"}) })
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING, length = 1)
abstract class X {
...
Long id;
String name;
List<A> a;
...
}
class Y extends X {
...
String getType() { return "Y"; }
...
}
class Z extends X {
...
String getType() { return "Z"; }
...
}
class A {}
What I need to do is "update" a persisted instance of Y to an instance of Z maintaining integrity. If I issue delete Y; create Z, I get unique constraint violations (due to hibernate's ordering of deletes to follow creates/updates) but have found no strategy to "update" Y to Z.
AFAIK, there's no way to do that without bypassing the session completely, since it would mean that a Java object changes its concrete type, which is impossible. And even then, if a concurrent transaction updates the same entity at the same time, you'd better have optimistic concurrency. And if another transaction refreshes the entity or lazy loads it, and the type has changed, you will have problems.
In short, if you need to do this, it probably means that you shouldn't have inheritance in the first place. Consider mapping the table as a single entity, with a type column, and optional fields.