![](/img/trans.png)
[英]How to correctly map a OneToMany relationship in Spring Boot?
[英]OneToMany relationship not saving correctly into Postgresql
非常感謝您花時間閱讀我的帖子。
請你能幫幫我嗎?
我想在我的數據庫中有一個 oneToMany 關系,例如: RelationShip Between Objects in DB
我正在使用 Spring、JPA、Mappers 和 Repos 來處理這些值。 Eveything 正確保存並正在工作。
唯一的問題是“CaserneJpa”在數據庫中的保存,當它包含“PompierJpa”和“CamionJpa”實體時,它不會將 caserne_id 保存到 pompiers 表的 pompier 行中。
我知道我的回購協議工作正常(保存到數據庫中)所以我假設它來自 OneToMany 關系。
我的 JPA 對象:
@Getter
@Setter
@Entity
@Table(name = "casernes")
public class CaserneJpa {
@Id
@Nonnull
private Integer id;
@Embedded
private CoordonneeJpa coordonnee;
@OneToMany(mappedBy="caserne", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<CamionJpa> camions;
@OneToMany(mappedBy="caserne", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<PompierJpa> pompiers;
}
@Getter
@Setter
@Entity
@Table(name = "interventions")
public class InterventionJpa {
@Id
@Nonnull
private UUID id;
private Integer idCapteur;
private Date date;
private CoordonneeJpa coordonnee;
@OneToMany(mappedBy="intervention", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<CamionJpa> camions;
@OneToMany(mappedBy="intervention", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<PompierJpa> pompiers;
}
@Getter
@Setter
@Entity
@Table(name = "camions")
public class CamionJpa {
@Id
@Nonnull
private Integer id;
private Integer places;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "caserne_id")
private CaserneJpa caserne;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "intervention_id")
private InterventionJpa intervention;
}
@Getter
@Setter
@Entity
@Table(name = "pompiers")
public class PompierJpa {
@Id
@Nonnull
private Integer id;
private String prenom;
private String nom;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "caserne_id")
private CaserneJpa caserne;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "intervention_id")
private InterventionJpa intervention;
}
TestCode所以我創建了一個測試代碼,它創建了一個 caserne object 與 pompiers 和 camions 來查看它是否設法正確生成,它確實創建了表並將值添加到所有表中但缺少信息
public void create() {
Pompier pompier = new Pompier();
Pompier pompier2 = new Pompier();
Camion camion = new Camion();
Camion camion2 = new Camion();
pompier.setId(1);
pompier.setNom("Gauchoux");
pompier.setPrenom("Xav");
pompier2.setId(2);
pompier2.setNom("Biosca");
pompier2.setPrenom("Coco");
camion.setId(1);
camion.setPlaces(2);
camion2.setId(2);
camion2.setPlaces(1);
ArrayList<Pompier> listPompier = new ArrayList<>();
listPompier.add(pompier);
listPompier.add(pompier2);
ArrayList<Camion> listCamion = new ArrayList<>();
listCamion.add(camion);
listCamion.add(camion2);
Coordonnee c = new Coordonnee();
c.setLatitude("1");
c.setLongitude("1");
Caserne caserne = new Caserne();
caserne.setId(1);
caserne.setCamions(listCamion);
caserne.setPompiers(listPompier);
caserne.setCoordonnee(c);
caserneRepository.save(caserneMapper.toCaserneJpa(caserne));
}
當我使用它時,一切順利,我沒有收到任何錯誤,並且按照我所說的那樣正確創建了表。 我們可以在創建表時看到 caserne_id integer 和 intervention_id。
Hibernate:
create table camions (
id integer not null,
places integer,
caserne_id integer,
intervention_id uuid,
primary key (id)
)
Hibernate:
create table casernes (
id integer not null,
latitude varchar(255),
longitude varchar(255),
primary key (id)
)
Hibernate:
create table interventions (
id uuid not null,
latitude varchar(255),
longitude varchar(255),
date timestamp(6),
id_capteur integer,
primary key (id)
)
Hibernate:
create table pompiers (
id integer not null,
nom varchar(255),
prenom varchar(255),
caserne_id integer,
intervention_id uuid,
primary key (id)
)
Hibernate:
alter table if exists camions
add constraint FKom9w5spol5vd1ix3oxfde4on0
foreign key (caserne_id)
references casernes
Hibernate:
alter table if exists camions
add constraint FKantgpwa0an7ktlsewuvjlbpnu
foreign key (intervention_id)
references interventions
Hibernate:
alter table if exists pompiers
add constraint FKjeg8ji8qlukn6gnrfs5p26tlu
foreign key (caserne_id)
references casernes
Hibernate:
alter table if exists pompiers
add constraint FK60xhoettofkdthm00wdt9rvmp
foreign key (intervention_id)
references interventions
...
Started EmergencymanagerApplication in 3.87 seconds (process running for 4.473)
Hibernate:
select
c1_0.id,
c2_0.caserne_id,
c2_0.id,
i1_0.id,
i1_0.latitude,
i1_0.longitude,
i1_0.date,
i1_0.id_capteur,
c2_0.places,
c1_0.latitude,
c1_0.longitude
from
casernes c1_0
left join
camions c2_0
on c1_0.id=c2_0.caserne_id
left join
interventions i1_0
on i1_0.id=c2_0.intervention_id
where
c1_0.id=?
Hibernate:
select
c1_0.id,
c2_0.id,
c2_0.latitude,
c2_0.longitude,
p1_0.caserne_id,
p1_0.id,
i1_0.id,
i1_0.latitude,
i1_0.longitude,
i1_0.date,
i1_0.id_capteur,
p1_0.nom,
p1_0.prenom,
i2_0.id,
i2_0.latitude,
i2_0.longitude,
i2_0.date,
i2_0.id_capteur,
c1_0.places
from
camions c1_0
left join
casernes c2_0
on c2_0.id=c1_0.caserne_id
left join
pompiers p1_0
on c2_0.id=p1_0.caserne_id
left join
interventions i1_0
on i1_0.id=p1_0.intervention_id
left join
interventions i2_0
on i2_0.id=c1_0.intervention_id
where
c1_0.id=?
Hibernate:
select
c1_0.id,
c2_0.id,
c2_0.latitude,
c2_0.longitude,
p1_0.caserne_id,
p1_0.id,
i1_0.id,
i1_0.latitude,
i1_0.longitude,
i1_0.date,
i1_0.id_capteur,
p1_0.nom,
p1_0.prenom,
i2_0.id,
i2_0.latitude,
i2_0.longitude,
i2_0.date,
i2_0.id_capteur,
c1_0.places
from
camions c1_0
left join
casernes c2_0
on c2_0.id=c1_0.caserne_id
left join
pompiers p1_0
on c2_0.id=p1_0.caserne_id
left join
interventions i1_0
on i1_0.id=p1_0.intervention_id
left join
interventions i2_0
on i2_0.id=c1_0.intervention_id
where
c1_0.id=?
Hibernate:
select
p1_0.id,
c1_0.id,
c2_0.caserne_id,
c2_0.id,
i1_0.id,
i1_0.latitude,
i1_0.longitude,
i1_0.date,
i1_0.id_capteur,
c2_0.places,
c1_0.latitude,
c1_0.longitude,
i2_0.id,
i2_0.latitude,
i2_0.longitude,
i2_0.date,
i2_0.id_capteur,
p1_0.nom,
p1_0.prenom
from
pompiers p1_0
left join
casernes c1_0
on c1_0.id=p1_0.caserne_id
left join
camions c2_0
on c1_0.id=c2_0.caserne_id
left join
interventions i1_0
on i1_0.id=c2_0.intervention_id
left join
interventions i2_0
on i2_0.id=p1_0.intervention_id
where
p1_0.id=?
Hibernate:
select
p1_0.id,
c1_0.id,
c2_0.caserne_id,
c2_0.id,
i1_0.id,
i1_0.latitude,
i1_0.longitude,
i1_0.date,
i1_0.id_capteur,
c2_0.places,
c1_0.latitude,
c1_0.longitude,
i2_0.id,
i2_0.latitude,
i2_0.longitude,
i2_0.date,
i2_0.id_capteur,
p1_0.nom,
p1_0.prenom
from
pompiers p1_0
left join
casernes c1_0
on c1_0.id=p1_0.caserne_id
left join
camions c2_0
on c1_0.id=c2_0.caserne_id
left join
interventions i1_0
on i1_0.id=c2_0.intervention_id
left join
interventions i2_0
on i2_0.id=p1_0.intervention_id
where
p1_0.id=?
Hibernate:
insert
into
casernes
(latitude, longitude, id)
values
(?, ?, ?)
Hibernate:
insert
into
camions
(caserne_id, intervention_id, places, id)
values
(?, ?, ?, ?)
Hibernate:
insert
into
camions
(caserne_id, intervention_id, places, id)
values
(?, ?, ?, ?)
Hibernate:
insert
into
pompiers
(caserne_id, intervention_id, nom, prenom, id)
values
(?, ?, ?, ?, ?)
Hibernate:
insert
into
pompiers
(caserne_id, intervention_id, nom, prenom, id)
values
(?, ?, ?, ?, ?)
結果
這是我在 Postgresql Camion Table中的 camions 表 我們可以看到它已正確生成和填充,除了 caserne_id。 創建 object 時有一個鏈接,所以我不明白為什么它丟失了。
我試過的
我嘗試通過改變級聯和其他東西來玩弄 oneToMany 和 manyToOne,但似乎沒有任何效果。
再次感謝您的幫助。
無論何時形成雙向關聯,應用程序開發人員都必須確保雙方始終保持同步。
最簡單的方法是添加一些輔助方法.addCamion(CamionJpa camion)
和.addPompier(PompierJpa pompier)
:
public class CaserneJpa {
...
@OneToMany(mappedBy="caserne", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<CamionJpa> camions = new ArrayList();
@OneToMany(mappedBy="caserne", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<PompierJpa> pompiers = new ArrayList();
...
public void addCamion(CamionJpa camion) {
this.camions.add(camion);
camion.setCaserne(this);
}
public void addPompier(PompierJpa Pompier) {
this.pompiers.add(pompier);
pompier.setCaserne(this);
}
}
然后你可以將代碼更改為:
public void create() {
Pompier pompier = new Pompier();
Pompier pompier2 = new Pompier();
Camion camion = new Camion();
Camion camion2 = new Camion();
pompier.setId(1);
pompier.setNom("Gauchoux");
pompier.setPrenom("Xav");
pompier2.setId(2);
pompier2.setNom("Biosca");
pompier2.setPrenom("Coco");
camion.setId(1);
camion.setPlaces(2);
camion2.setId(2);
camion2.setPlaces(1);
Coordonnee c = new Coordonnee();
c.setLatitude("1");
c.setLongitude("1");
Caserne caserne = new Caserne();
caserne.setId(1);
caserne.addCamion(camion);
caserne.addCamion(camion2);
caserne.addPompier(pompier);
caserne.addPompier(pompier2);
caserne.setCoordonnee(c);
caserneRepository.save(caserneMapper.toCaserneJpa(caserne));
}
謝謝大衛,你讓我明白了我的錯誤。
我用你的代碼為我的兩個映射器添加了一個@AfterMapping 方法
@Mapper
public interface CaserneMapper {
Caserne toCaserne(CaserneJpa caserneJpa);
CaserneJpa toCaserneJpa(Caserne caserne);
List<Caserne> toCaserne(List<CaserneJpa> caserneJpa);
List<CaserneJpa> toCaserneJpa(List<Caserne> caserne);
@AfterMapping
default void customMapForCamionJpa(Caserne caserne, @MappingTarget CaserneJpa caserneJpa) {
ArrayList<CamionJpa> listCamionJpa = (ArrayList<CamionJpa>) caserneJpa.getCamions();
for (CamionJpa camionJpa : listCamionJpa) {
camionJpa.setCaserne(caserneJpa);
}
ArrayList<PompierJpa> listPompierJpa = (ArrayList<PompierJpa>) caserneJpa.getPompiers();
for (PompierJpa pompierJpa : listPompierJpa) {
pompierJpa.setCaserne(caserneJpa);
}
}
@AfterMapping
default void customMapForListCamionJpa(List<Caserne> caserne, @MappingTarget List<CaserneJpa> caserneJpa) {
for (CaserneJpa itemCaserneJpa : caserneJpa) {
ArrayList<CamionJpa> listCamionJpa = (ArrayList<CamionJpa>) itemCaserneJpa.getCamions();
for (CamionJpa camionJpa : listCamionJpa) {
camionJpa.setCaserne(itemCaserneJpa);
}
ArrayList<PompierJpa> listPompierJpa = (ArrayList<PompierJpa>) itemCaserneJpa.getPompiers();
for (PompierJpa pompierJpa : listPompierJpa) {
pompierJpa.setCaserne(itemCaserneJpa);
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.