With Hibernate joined-subclasses, is it possible to duplicate columns in super and sub-tables *and* keep them in sync?

StackOverflow https://stackoverflow.com/questions/6047273

  •  15-11-2019
  •  | 
  •  

Question

So I have an interesting situation. I've inherited a big mess of code where the original developer decided to forego using inheritance in favor of enums and switch statements...it's a perfect example of this anti-pattern Now it's time to refactor, and I've decided the best way to go about it is to pull out a superclass backed by a table with shared columns and then use the joined subclass inheritance strategy. So far so good...

Now the tricky part is that this code has already been deployed to a production system. Accordingly, my refactored code has to be backwards-compatible with the schema/data out there, and I can't start dropping redundant columns off of the subclass tables until one release in the future. Like it or not, I'm going to have duplicated columns between the parent and child tables for one release cycle.

Luckily for me, hibernate doesn't flip out when it sees that there are duplicate columns between parent and child tables. But the bad news is that it doesn't update said duplicated columns in both tables. The column in the parent table gets updated, but the one in the child is left stale.

For backward-compatibility with the current code, I'd like for the column to be updated in both tables. That way, updates to the entities aren't lost if we have to rollback the release and go back to the old schema. While I know that I could take care of this via triggers, I'm looking for a code-only solution because triggers have a nasty habit of flying under the radar.

Is there anyone out there who can tell me a way to convince hibernate to hit both columns?

A very contrived example of my classes is:

@Entity
@Table(name = "superclass")
@Inheritance(strategy = InheritanceType.JOINED)
public class SuperClass {

    @Id @Generated
    Long id;
    boolean duplicate;
}

@Entity
@Table(name = "subclass")
public class SubClass extends SuperClass {
    String otherProperty;
}

With the tables to match:

CREATE TABLE superclass (
    id INT PRIMARY KEY AUTO_INCREMENT,
    duplicate BOOLEAN
);

CREATE TABLE subclass (
    id INT NOT NULL,
    duplicate BOOLEAN,
    otherProperty VARCHAR(255),
    FOREIGN KEY (id) REFERENCES superclass(id)
);

When inserting a new SubClass entity, the duplicate column on the subclass table will be NULL.

Thanks a bunch!

Was it helpful?

Solution

How about defining two properties in your code, mapping one to each column, then keeping them in sync in the code? One is the real property, and one is a sort of shadow property. It's not pretty, but it should be confined to the implementation of one class (or one class and its superclass).

When you are able to drop the column, you can remove the shadow property.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top