How to specify column names in Hibernate/JPA when inheritance is involved?

12,352

It can possible with @MappedSuperclass (Designates a class whose mapping information is applied to the entities that inherit from it. A mapped superclass has no separate table defined for it.) Vehicle class :

@MappedSuperclass
public class Vehicle {
    @Id
    @GeneratedValue
    Long id;
    Long maxSpeed;
    String make;
    String model;
}

Motorcycle subclass

 @Entity
    @AttributeOverrides({
            @AttributeOverride(name = "id", column = @Column(name = "motorcycle_id"))
    })
    public class Motorcycle extends Vehicle {
        Boolean isTwoStroke;
    }
Share:
12,352
smeeb
Author by

smeeb

Updated on June 04, 2022

Comments

  • smeeb
    smeeb about 2 years

    I think I'm trying to have my cake and eat it too here, but we'll see if there's a plausible solution to what I'm looking for. I have a Spring Boot/JPA/Hibernate app that will be talking to MySQL as its backing store. I have several cases where my entity classes form, from an OOP perspective, a parent/child hierarchy like so:

    // Groovy pseudo-code!
    class Vehicle {
      Long id
      Long maxSpeed
      String make
      String model
    }
    
    class Motorcycle extends Vehicle {
      Boolean isTwoStroke
    }
    
    class Car extends Vehicle {
      Boolean hasLeatherInterior
    }
    

    etc. Normally, outside of JPA, I might design their respective tables like so:

    CREATE TABLE motorcycles (
      motorcycle_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
      motorcycle_max_speed BIGINT UNSIGNED,
      motorcycle_make VARCHAR(50) NOT NULL,
      motorcycle_model VARCHAR(50) NOT NULL,
      motorcycle_is_two_speed BIT NOT NULL,
    
      # PK, FK, UC, index constraints down here (omitted for brevity)
    );
    
    CREATE TABLE cars (
      car_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
      car_max_speed BIGINT UNSIGNED,
      car_make VARCHAR(50) NOT NULL,
      car_model VARCHAR(50) NOT NULL,
      car_has_leather_interior BIT NOT NULL,
    
      # PK, FK, UC, index constraints down here (omitted for brevity)
    );
    

    Ideally I'd like to keep this table design as-is, with the names of the "parent vehicle" columns staying exactly as I have the, above. But if I'm understanding the Hibernate/JPA APIs correctly, then I don't think its possible without making some sort of sacrifice. I think I either need to sacrifice inheritance at the app-layer so that I can name the columns in the child classes exactly as I have them in the DB:

    @Entity
    class Motorcycle {    // No longer extends Vehicle :-(
      @Id
      @GeneratedValue(strategy=GenerationType.IDENTITY)
      @Column(name = "motorcycle_id")
      Long id
    
      @Column(name = "motorcycle_max_speed")
      Long maxSpeed
    
      @Column(name = "motorcycle_make")
      String make
    
      @Column(name = "motorcycle_model")
      String model
    
      @Column(name = "motorcycle_is_two_speed")
      Boolean isTwoStroke
    }
    
    @Entity
    class Car {    // No longer extends Vehicle :-(
      @Id
      @GeneratedValue(strategy=GenerationType.IDENTITY)
      @Column(name = "car_id")
      Long id
    
      @Column(name = "car_max_speed")
      Long maxSpeed
    
      @Column(name = "car_make")
      String make
    
      @Column(name = "car_model")
      String model
    
      @Column(name = "car_has_leather_interior")
      Boolean hasLeatherInterior
    }
    

    Or I think I can keep app-layer inheritance, but then would need to refactor my DB tables like so:

    CREATE TABLE motorcycles (
      id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
      max_speed BIGINT UNSIGNED,
      make VARCHAR(50) NOT NULL,
      model VARCHAR(50) NOT NULL,
      motorcycle_is_two_speed BIT NOT NULL,
    
      # PK, FK, UC, index constraints down here (omitted for brevity)
    );
    
    CREATE TABLE cars (
      id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
      max_speed BIGINT UNSIGNED,
      make VARCHAR(50) NOT NULL,
      model VARCHAR(50) NOT NULL,
      car_has_leather_interior BIT NOT NULL,
    
      # PK, FK, UC, index constraints down here (omitted for brevity)
    );
    

    So I ask: is it possible for me to keep my app-layer inheritance (and have Motorcycle and Car inherit those properties from Vehicle) and keep my DB table columns named using my preferred convention?