簡體   English   中英

OneToMany 關系未正確保存到 Postgresql

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM