How to specify column names in Hibernate/JPA when inheritance is involved?
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;
}
smeeb
Updated on June 04, 2022Comments
-
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
andCar
inherit those properties fromVehicle
) and keep my DB table columns named using my preferred convention?