I'm having a problem with Hibernate entities inheritance where it creates a copy of fk column of a many-to-one relation without updating it.
@Data
@Entity
public class Vehicle {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(mappedBy = "vehicle")
private Set<Human> owner;
}
@Data
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Integer age;
@ManyToOne
private Vehicle vehicle;
}
@Data
@Entity
public class Human extends Person {
private String fullName;
}
With this entities it creates:
create table human (
full_name varchar(255),
id bigint not null,
vehicle_id bigint,
primary key (id)
) engine=InnoDB
create table person (
id bigint not null auto_increment,
age integer,
vehicle_id bigint,
primary key (id)
) engine=InnoDB
create table vehicle (
id bigint not null auto_increment,
primary key (id)
) engine=InnoDB
alter table human
add constraint FKqctp8ycdo4mm7fsou0v4jalx3
foreign key (id)
references person (id)
alter table person
add constraint FKgo297ke05qjubymwq6unmcnot
foreign key (vehicle_id)
references vehicle (id)
Why it declares Human.vehicle_id? I don't need it and hibernate dosn't sync it with Person.vehicle_id. The worst part is when hibernate Join Human with Vehicle it check Human.vehicle_id = Vehicle.id How can I resolve this issue? I can't change InheritanceType because it will be huge migration.
Test case:
final var car = Vehicle.builder().build();
vehiclesRepo.save(car);
final var mario = Human.builder()
.fullName("Mario Rossi")
.age(20)
.vehicle(car)
.build();
humansRepo.save(mario);
Vehicle
id|
--+
1|
Person
id|age|vehicle_id|
--+---+----------+
2| 20| 1|
Human
full_name |id|vehicle_id|
-----------+--+----------+
Mario Rossi| 2| |
-- generated query for findAll
select
human0_.id as id1_1_,
human0_1_.age as age2_1_,
human0_1_.vehicle_id as vehicle_3_1_,
human0_.full_name as full_nam1_0_
from
human human0_
inner join
person human0_1_
on human0_.id=human0_1_.id
select
vehicle0_.id as id1_2_0_
from
vehicle vehicle0_
where
vehicle0_.id=?
select
owner0_.vehicle_id as vehicle_3_0_0_,
owner0_.id as id2_0_0_,
owner0_.id as id1_1_1_,
owner0_1_.age as age2_1_1_,
owner0_1_.vehicle_id as vehicle_3_1_1_,
owner0_.full_name as full_nam1_0_1_,
vehicle1_.id as id1_2_2_
from
human owner0_
inner join
person owner0_1_
on owner0_.id=owner0_1_.id
left outer join
vehicle vehicle1_
on owner0_1_.vehicle_id=vehicle1_.id
where
owner0_.vehicle_id=?
owner0_.vehicle_id=? here is where it fails the join because vehicle_id in human table is never populated, in this test scenario it's a bit better than real one because it actually made the join right and fails only in where conditions, in real use case it just use on 1=1 in join.

