为啥在看到 PersistentBag 的实体中使用 JPA 列出(@OneToMany)

Posted

技术标签:

【中文标题】为啥在看到 PersistentBag 的实体中使用 JPA 列出(@OneToMany)【英文标题】:Why List(@OneToMany) with JPA in Entity seen PersistentBag为什么在看到 PersistentBag 的实体中使用 JPA 列出(@OneToMany) 【发布时间】:2018-09-21 13:33:20 【问题描述】:

我有两个实体如下 Personel.java 和 PersonelEgitimDurum.java List personelEgitimDurumList 是 Personel 中的 PersistentBag,如​​下所示;

[enter image description here][1] 


  [1]: https://i.stack.imgur.com/Q3IC2.png

Personel.java如下;

    @Entity
@Table(name="personel")
public class Personel extends BaseEntity 

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="kisi_id")
    private Kisi kisi;

    @Column(name="personel_tipi",length = 2,nullable = false)
    private int personelTipi;

    @Column(name="sicil_no",length = 100,nullable = false)
    private String sicilNo;

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "personel", cascade =CascadeType.ALL,orphanRemoval = true)
    private List<PersonelEgitimDurum> personelEgitimDurumList= new ArrayList<PersonelEgitimDurum>();

    @Column(name="khk_onay",length = 1)
    private int khkOnay;

PersonelEgitimDurum.java 如下;

    @Entity
@Table(name = "personel_egitim_durum", indexes = @Index(name = "index_personel_egitim_durum", columnList = "id"))
public class PersonelEgitimDurum extends BaseEntity 

    @ManyToOne(cascade=CascadeType.PERSIST,fetch=FetchType.EAGER)
    @JoinColumn(name="personel_id",nullable = false, updatable = true)
    private Personel personel;

    @Column(name = "ogrenim_durumu")
    private String ogrenimDurumu;

    @Column(name = "okul_id", length = 3)
    private Long okulId;

    @Column(name = "universite_bolum_id", length = 4)
    private Long universiteBolumId;

    @Column(name = "mezuniyet_tarihi")
    private Date mezuniyetTarihi;

    @Column(name = "aciklama", length = 500)
    private String aciklama;

PersonelServiceImpl.java如下;

@Service
@Transactional
public class PersonelServiceImpl implements PersonelService 
@Override
    public PersonelDTO findPersonelByKimlikNo(String kimlikNo) 
        Kisi kisi=kisiDAO.findKisiByKimlikNo(kimlikNo);
        Personel personel=personelDao.findPersonelByKisi(kisi);
        PersonelDTO personelDTO=mapper.toDto(personel);
        return personelDTO;
    

问题是 PersonelServiceImpl 中 findPersonelByKimlikNo 的人员包括 personelEgitimDurumList 是 PersistentBag 作为图像。所以 mapStruct 不会将实体转换为 dto。

错误日志如下;

java.lang.***Error: null
at org.hibernate.collection.internal.PersistentBag.size(PersistentBag.java:261) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.kktcmeb.personel.kktcmebpersonel.mapper.PersonelMapperImpl.personelEgitimDurumListToPersonelEgitimDurumDTOList(PersonelMapperImpl.java:159) ~[classes/:na]
at org.kktcmeb.personel.kktcmebpersonel.mapper.PersonelMapperImpl.toDto(PersonelMapperImpl.java:53) ~[classes/:na]
at org.kktcmeb.personel.kktcmebpersonel.mapper.PersonelMapperImpl.personelEgitimDurumToPersonelEgitimDurumDTO(PersonelMapperImpl.java:144) ~[classes/:na]
at org.kktcmeb.personel.kktcmebpersonel.mapper.PersonelMapperImpl.personelEgitimDurumListToPersonelEgitimDurumDTOList(PersonelMapperImpl.java:161) ~[classes/:na]
at org.kktcmeb.personel.kktcmebpersonel.mapper.PersonelMapperImpl.toDto(PersonelMapperImpl.java:53) ~[classes/:na]

有人知道这种情况吗?请帮忙

【问题讨论】:

哪一个?在 Personel.java ||在 PersonelEgitimDurum.java 中 @ikarayel 抱歉:(没有任何改变! 您在 PersonelEgitimDurum 和 Personel 之间存在循环依赖关系,忽略循环字段。您可以通过 Mapping#ignore 忽略它们,就像我之前的代码示例 @JsonIgnore Spring boot Mapstruct *** Error的可能重复 我不想忽略列表,因为当更新到 personel 的 aktif 时,personelEgitimDurum 的 aktif 字段在 personelEgitimDurumList 中更新 【参考方案1】:
@Entity
@Table(name="personel")
**@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")**
        public class Personel extends BaseEntity 

            @OneToOne(cascade = CascadeType.ALL)
            @JoinColumn(name="kisi_id")
            private Kisi kisi;

            @Column(name="personel_tipi",length = 2,nullable = false)
            private int personelTipi;

            @Column(name="sicil_no",length = 100,nullable = false)
            private String sicilNo;

            @OneToMany(fetch = FetchType.EAGER, mappedBy = "personel", cascade =CascadeType.ALL,orphanRemoval = true)
            private List<PersonelEgitimDurum> personelEgitimDurumList= new ArrayList<PersonelEgitimDurum>();

            @Column(name="khk_onay",length = 1)
            private int khkOnay;
        

添加到实体头部->@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")

@Entity
@Table(name = "personel_egitim_durum", indexes = @Index(name = "index_personel_egitim_durum", columnList = "id"))
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
    public class PersonelEgitimDurum extends BaseEntity 

        @ManyToOne(cascade=CascadeType.PERSIST,fetch=FetchType.EAGER)
        @JoinColumn(name="personel_id",nullable = false, updatable = true)
        private Personel personel;

        @Column(name = "ogrenim_durumu")
        private String ogrenimDurumu;

        @Column(name = "okul_id", length = 3)
        private Long okulId;

        @Column(name = "universite_bolum_id", length = 4)
        private Long universiteBolumId;

        @Column(name = "mezuniyet_tarihi")
        private Date mezuniyetTarihi;

        @Column(name = "aciklama", length = 500)
        private String aciklama;
    

【讨论】:

以上是关于为啥在看到 PersistentBag 的实体中使用 JPA 列出(@OneToMany)的主要内容,如果未能解决你的问题,请参考以下文章

如何在mysql中使字段区分大小写

在android中使按钮半透明[重复]

为啥vmware里的虚拟机cpu占用率高?

如何在 Ionic 2 中使状态栏颜色可变

如何在 swift 中使文本字段功能在 tableview 中

将 TabView 放在 NavigationView 中使标题透明