Thanks a lot for taking time to read my post.
Please could you help me.
I want to have a oneToMany relationship in my database such as:
RelationShip Between Objects in DB
I am using Spring, JPA, Mappers and Repos to work with these values.
Eveything saves correctly and is working.
Only thing is the save in the database of a "CaserneJpa" when it contains "PompierJpa" and "CamionJpa" entities it doesn’t save the caserne_id into the pompier line in the pompiers table.
I know my repos are working properly (saving into DB works) so I assume it’s coming from the OneToMany relationship.
My JPA Objects:
@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
So I created a test code that creates a caserne object with pompiers and camions to see if it manages to generate properly, it did indeed create the tables and added the values into all the tables but with missing information
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));
}
When I use it, it all goes whell I don’t get any errors, and the tables are created properly as I said. We can see the caserne_id integer and intervention_id in the creation of the tables.
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
(?, ?, ?, ?, ?)
Result
This is my camions table in Postgresql
Camion Table
We can see that it was generated and filled properly, except for the caserne_id.
When the object was created there was a link, so I don’t get why it is lost.
What I tried
I tried playing around with the oneToMany and manyToOne by changing the cascade and other things but nothing seems to be working.
Thanks again for your help.
2
Answers
Thanks David you made me understand my mistake.
I used your code to add an @AfterMapping method for both my Mappers
Bidirectional association should be updated on both sides:
The easiest way to do this is to add some helper methods
.addCamion(CamionJpa camion)
and.addPompier(PompierJpa pompier)
:Then you can change the code to: