【问题标题】:JSON failed to lazily initialize a collection of rolesJSON 无法延迟初始化角色集合
【发布时间】:2019-12-18 08:40:38
【问题描述】:

我正在对具有关系表中属性的多对多关系中的 CRUD 操作进行练习。

我正在附加我的实体,希望您能帮助我。

当我去询问zetautente和zetamessaggio表上的元素列表时,就会出现上述错误。

即使我去要求上述两个表之一的单个元素,也会发生同样的错误..

@Entity(name = "ZetaMessaggio")
@Table(name="zetamessaggio")
public class ZetaMessaggio implements Serializable {

    private static final long serialVersionUID = -2387302703708194311L;

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "zetamessaggio_seq")
    @SequenceGenerator(name = "zetamessaggio_seq",sequenceName = "zetamessaggio_seq",allocationSize = 1)
    private Long id;

    @Column(name = "titolo")
    private String titolo;

    @Column(name = "testo")
    private String testo;

    @OneToMany(
            mappedBy = "zetaMessaggio",
            cascade = CascadeType.ALL,
            orphanRemoval = true
    )
    @JsonManagedReference(value="zetaMessaggio")
    private List<ZetaMessaggioUtente> zetaUtente = new ArrayList<ZetaMessaggioUtente>();


    public ZetaMessaggio() {
    }

    public ZetaMessaggio(String titolo, String testo)
    {
        this.titolo = titolo;
        this.testo = testo;
    }


    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getTitolo() {
        return titolo;
    }

    public void setTitolo(String titolo) {
        this.titolo = titolo;
    }

    public String getTesto() {
        return testo;
    }

    public void setTesto(String testo) {
        this.testo = testo;
    }

    public List<ZetaMessaggioUtente> getZetaUtente() {
        return zetaUtente;
    }

    public void setZetaUtente(List<ZetaMessaggioUtente> zetaUtenti) {
        this.zetaUtente = zetaUtenti;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;

        if (o == null || getClass() != o.getClass())
            return false;

        ZetaMessaggio other = (ZetaMessaggio) o;
        return  Objects.equals(new Long(this.id), new Long(other.id))
                && Objects.equals(this.titolo, other.titolo)
                && Objects.equals(this.testo, other.testo);
    }

    @Override
    public int hashCode() {
        return Objects.hash(    new Long(this.id)
                , this.testo
                , this.titolo
        );
    }
}


@Entity(name = "ZetaMessaggioUtente")
@Table(name = "zetamessaggioutente")
public class ZetaMessaggioUtente implements Serializable {

    private static final long serialVersionUID = 4060038267093084727L;

    @EmbeddedId
    private ZetaMessaggioUtenteId id;

    @Column(name="data")
    private String data;

    @ManyToOne(fetch = FetchType.LAZY)
    @MapsId("idMessaggio")
    @JoinColumn(name = "idMessaggio")
    @JsonBackReference(value = "zetaMessaggio")
    private ZetaMessaggio zetaMessaggio;

    @ManyToOne(fetch = FetchType.LAZY)
    @MapsId("idUtente")
    @JoinColumn(name = "idUtente")
    @JsonBackReference(value = "zetaUtente")
    private ZetaUtente zetaUtente;

    private ZetaMessaggioUtente() {}

    public ZetaMessaggioUtente(ZetaMessaggioUtenteId id)
    {
        this.id = id;
    }

    public ZetaMessaggioUtente(ZetaMessaggio messaggio, ZetaUtente utente)
    {
        this.zetaMessaggio = messaggio;
        this.zetaUtente = utente;
        this.id = new ZetaMessaggioUtenteId(messaggio.getId(), utente.getId());
    }

    public ZetaMessaggioUtenteId getId() {
        return id;
    }

    public void setId(ZetaMessaggioUtenteId id) {
        this.id = id;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public ZetaMessaggio getZetaMessaggio() {
        return zetaMessaggio;
    }

    public void setZetaMessaggio(ZetaMessaggio zetaMessaggio) {
        this.zetaMessaggio = zetaMessaggio;
    }

    public ZetaUtente getZetaUtente() {
        return zetaUtente;
    }

    public void setZetaUtente(ZetaUtente zetaUtente) {
        this.zetaUtente = zetaUtente;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;

        if (o == null || getClass() != o.getClass())
        {
            return false;
        }

        ZetaMessaggioUtente other = (ZetaMessaggioUtente) o;
        return  Objects.equals(zetaMessaggio, other.zetaMessaggio)
                && Objects.equals(zetaUtente, other.zetaUtente)
                ;
    }

    @Override
    public int hashCode()
    {
        return Objects.hash(zetaMessaggio, zetaUtente);
    }
}


@Embeddable
public class ZetaMessaggioUtenteId implements Serializable {

    private static final long serialVersionUID = -7372159721389421199L;

    @Column(name = "idMessaggio")
    private Long idMessaggio;

    @Column(name = "idUtente")
    private Long idUtente;

    private ZetaMessaggioUtenteId(){}

    public ZetaMessaggioUtenteId(Long idMessaggio,Long idUtente){
        setIdMessaggio(idMessaggio);
        setIdUtente(idUtente);
    }

    public Long getIdMessaggio() {
        return idMessaggio;
    }

    public void setIdMessaggio(Long idMessaggio) {
        this.idMessaggio = idMessaggio;
    }

    public Long getIdUtente() {
        return idUtente;
    }

    public void setIdUtente(Long idUtente) {
        this.idUtente = idUtente;
    }

    @Override
    public boolean equals(Object o)
    {
        if (this == o) return true;

        if (o == null || getClass() != o.getClass())
        {
            return false;
        }

        ZetaMessaggioUtenteId other = (ZetaMessaggioUtenteId) o;
        return Objects.equals(new Long(this.idMessaggio), new Long(other.idMessaggio)) &&
                Objects.equals(new Long(this.idUtente), new Long(other.idUtente))
                ;
    }

    @Override
    public int hashCode()
    {
        return Objects.hash(    new Long(this.idMessaggio)
                , new Long(this.idUtente)
        );
    }
}


@Entity(name = "ZetaUtenti")
@Table(name = "zetautenti",uniqueConstraints = {@UniqueConstraint(columnNames = {"Id"})})
public class ZetaUtente implements Serializable {

    private static final long serialVersionUID = -5338956772143977741L;

    @Id
    @Column(name="id")
    @GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "zetautenti_seq")
    @SequenceGenerator(name = "zetautenti_seq",sequenceName = "zetautenti_seq",allocationSize = 1)
    private Long id;

    @Column(name = "nome")
    private String nome;

    @Column(name = "cognome")
    private String cognome;

    @OneToMany(
            mappedBy = "zetaUtente",
            cascade = CascadeType.ALL,
            orphanRemoval = true
    )
    @JsonManagedReference(value="zetaUtente")
    private List<ZetaMessaggioUtente> zetaMessaggio = new ArrayList<ZetaMessaggioUtente>();


    public ZetaUtente() {
    }

    public ZetaUtente(String nome, String cognome)
    {
        this.nome = nome;
        this.cognome = cognome;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        id = id;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getCognome() {
        return cognome;
    }

    public void setCognome(String cognome) {
        this.cognome = cognome;
    }

    public List<ZetaMessaggioUtente> getZetaMessaggio() {
        return zetaMessaggio;
    }

    public void setZetaMessaggio(List<ZetaMessaggioUtente> zetaMessaggi) {
        this.zetaMessaggio = zetaMessaggi;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;

        if (o == null || getClass() != o.getClass())
            return false;

        ZetaUtente other = (ZetaUtente) o;
        return  Objects.equals(new Long(this.id), new Long(other.id))
                && Objects.equals(this.nome, other.nome)
                && Objects.equals(this.cognome, other.cognome);
    }

    @Override
    public int hashCode() {
        return Objects.hash(    new Long(this.id)
                , this.nome
                , this.cognome
        );
    }
}

【问题讨论】:

    标签: json spring hibernate


    【解决方案1】:

    默认@OneToMany@ManyToMany关系是惰性的,所以你需要处理接收惰性数据。

    网上有很多建议,你问这个问题很奇怪,但是如果很快,你就没有几个方法可以偷懒:

    • 反模式:OpenSessionInViewenable_lazy_load_no_trans

    • 最流行的方式:使用@Transactional注解(自动将对象附加到会话池)或手动启动事务、获取集合、关闭事务

    • 类似方式:Hibernate.initialize(&lt;get collection method&gt;)

    • 手动方式:使用自己的SQL请求“JOIN FETCH ...

    • 替代方式:使用@Fetch(FetchMode.SUBSELECT)(不能说什么)

    • 方法不对(但最快的临时解决方案):使用FetchMode.EAGER进行收集

    【讨论】:

      【解决方案2】:

      Collections默认是懒加载的,如果你不知道这个可以查看链接Lazy loading of collection

      要使您的代码正常工作,您需要在 OneToMany 中添加以下内容:

      fetch = FetchType.EAGER
      

      【讨论】:

      • 仅仅将获取策略从 LAZY 设置为 EAGER 并不是最好的主意。您应该小心处理那些延迟加载的集合,并且只在必要时加载它们。检查您的交易。
      • OP 是否在这里询问最佳实践?关于如何修复代码 - 请仔细阅读问题。
      猜你喜欢
      • 2022-01-05
      • 2018-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-06
      • 2015-07-02
      • 2016-06-04
      相关资源
      最近更新 更多