Hibernate/JPA中涉及继承时如何指定列名?

sme*_*eeb 5 java groovy inheritance hibernate jpa

我想我想在这里鱼和熊掌兼得,但我们会看看是否有一个合理的解决方案来满足我正在寻找的问题。我有一个 Spring Boot/JPA/Hibernate 应用程序,它将与 MySQL 作为其后备存储进行通信。我有几种情况,从 OOP 的角度来看,我的实体类形成了一个父/子层次结构,如下所示:

// 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
}
Run Code Online (Sandbox Code Playgroud)

通常,在 JPA 之外,我可能会像这样设计各自的表:

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)
);
Run Code Online (Sandbox Code Playgroud)

理想情况下,我希望保持此表设计不变,“父车辆”列的名称与我上面的名称完全相同。但如果我正确理解 Hibernate/JPA API,那么我认为在不做出某种牺牲的情况下这是不可能的。我认为我要么需要牺牲应用程序层的继承,以便我可以完全按照数据库中的名称命名子类中的列:

@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
}
Run Code Online (Sandbox Code Playgroud)

或者我认为我可以保留应用程序层继承,但随后需要重构我的数据库表,如下所示:

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)
);
Run Code Online (Sandbox Code Playgroud)

所以我问:我是否可以保留我的应用程序层继承(并拥有MotorcycleCar继承这些属性Vehicle保留使用我的首选约定命名的数据库表列?

Bhu*_*yal 5

可以使用 @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.) 车辆类:

@MappedSuperclass
public class Vehicle {
    @Id
    @GeneratedValue
    Long id;
    Long maxSpeed;
    String make;
    String model;
}
Run Code Online (Sandbox Code Playgroud)

摩托车小类

 @Entity
    @AttributeOverrides({
            @AttributeOverride(name = "id", column = @Column(name = "motorcycle_id"))
    })
    public class Motorcycle extends Vehicle {
        Boolean isTwoStroke;
    }
Run Code Online (Sandbox Code Playgroud)