【问题标题】:failed to lazily initialize a collection of role ManyToMany relation未能懒惰地初始化角色多对多关系的集合
【发布时间】:2016-05-11 13:30:08
【问题描述】:

我有一个实体问题和一个实体测试,两个实体之间存在多对多关系。 当我想查看一个测试的问题时,就会出现这个错误。

failed to lazily initialize a collection of role:     
tn.esen.entities.Test.questions, could not initialize proxy - no Session

这是两个实体的 JPA 实现。 问题:

 package tn.esen.entities;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.GeneratedValue;
 import javax.persistence.GenerationType;
 import javax.persistence.Id;

 import javax.persistence.ManyToMany;
 import javax.persistence.ManyToOne;
 import javax.persistence.OneToMany;

 import java.io.Serializable; 
  import java.util.Collection;
  import java.util.Date;
  @Entity
  public class Question implements Serializable {
@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((contenu == null) ? 0 :       
 contenu.hashCode());
    result = prime * result + ((dateCreation == null) ? 0 :      
 dateCreation.hashCode());
    result = prime * result + ((niveauDeDifficulte == null) ? 0 :        
  niveauDeDifficulte.hashCode());
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Question other = (Question) obj;
    if (contenu == null) {
        if (other.contenu != null)
            return false;
    } else if (!contenu.equals(other.contenu))
        return false;
    if (dateCreation == null) {
        if (other.dateCreation != null)
            return false;
    } else if (!dateCreation.equals(other.dateCreation))
        return false;
    if (niveauDeDifficulte == null) {
        if (other.niveauDeDifficulte != null)
            return false;
    } else if (!niveauDeDifficulte.equals(other.niveauDeDifficulte))
        return false;
    return true;
}

/**
 * 
 */
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id_question")     
private int id;
private String contenu;    
private String niveauDeDifficulte;
    private Date dateCreation;
    @OneToMany(mappedBy="question",fetch = FetchType.EAGER)
    private Collection <Reponse> reponses; 
    @ManyToOne
     private Categorie categorie;
    @ManyToOne
     private Administrateur administrateur;
    @ManyToMany(mappedBy = "questions",fetch = FetchType.EAGER)
    private Collection<Test> tests;
   public Question(){
   super();
 }

    @Override
   public String toString() {
  return "Question [id=" + id + ", contenu=" + contenu + ",       
  niveauDeDifficulte=" + niveauDeDifficulte + "]";
  }

  public int getId() {
  return id;
}

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

  public String getContenu() {
return contenu;
 }

  public void setContenu(String contenu) {
this.contenu = contenu;
 }

  public String getNiveauDeDifficulte() {
   return niveauDeDifficulte;
    }       

        public void setNiveauDeDifficulte(String niveauDeDifficulte) {
    this.niveauDeDifficulte = niveauDeDifficulte;
      }


    public Date getDateCreation() {
     return dateCreation;
    }

    public void setDateCreation(Date dateCreation) {
     this.dateCreation = dateCreation;
     }


      public Collection<Reponse> getReponses() {
    return reponses;
    }

    public void setReponses(Collection<Reponse> reponses) {
    this.reponses = reponses;
    }

  public Categorie getCategorie() {
     return categorie;
   }

   public void setCategorie(Categorie categorie) {
   this.categorie = categorie;
  }

 public Administrateur getAdministrateur() {
return administrateur;
 }

    public void setAdministrateur(Administrateur administrateur) {
  this.administrateur = administrateur;
  }

   public Collection<Test> getTest() {
    return tests;
  }

  public void setTest(Collection<Test> tests) {
   this.tests = tests;
 }

   public Question(String contenu, String niveauDeDifficulte, Date    
  dateCreation) {
super();
this.contenu = contenu;
this.niveauDeDifficulte = niveauDeDifficulte;
this.dateCreation = dateCreation;
 } 

测试:

   package tn.esen.entities;


    @Entity
    public class Test implements Serializable {
  /**
   * 
   */
    private static final long serialVersionUID = 1L;
  @Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String duree;
private String typeDePreparation;
private String lieu;
private int nbrQuestionFacile;
private int nbrQuestionMoyen;
private int nbrQuestionDifficle;
@OneToMany(mappedBy = "test")
private Collection<Resultat> resultats;
@ManyToMany
private Collection<Question> questions;

@ManyToOne
private ResponsableTechnique responsableTechnique;

public Test() {
    super();
}

public int getId() {
    return id;
}

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



public String getDuree() {
    return duree;
}

public void setDuree(String duree) {
    this.duree = duree;
}

public Collection<Question> getQuestions() {
    return questions;
}

public void setQuestions(Collection<Question> questions) {
    this.questions = questions;
}

 public Test(String duree, String typeDePreparation, String lieu, int 
 nbrQuestionFacile, int nbrQuestionMoyen,
        int nbrQuestionDifficle) {
    super();
    this.duree = duree;
    this.typeDePreparation = typeDePreparation;
    this.lieu = lieu;
    this.nbrQuestionFacile = nbrQuestionFacile;
    this.nbrQuestionMoyen = nbrQuestionMoyen;
    this.nbrQuestionDifficle = nbrQuestionDifficle;
}

public ResponsableTechnique getRésponsableTechnique() {
    return responsableTechnique;
}

  public void setRésponsableTechnique(ResponsableTechnique       
  résponsableTechnique) {
    this.responsableTechnique = résponsableTechnique;
}

public String getTypeDePreparation() {
    return typeDePreparation;
}

public void setTypeDePreparation(String typeDePreparation) {
    this.typeDePreparation = typeDePreparation;
}

public String getLieu() {
    return lieu;
}

public void setLieu(String lieu) {
    this.lieu = lieu;
}

public int getNbrQuestionFacile() {
    return nbrQuestionFacile;
}

public void setNbrQuestionFacile(int nbrQuestionFacile) {
    this.nbrQuestionFacile = nbrQuestionFacile;
}

public int getNbrQuestionMoyen() {
    return nbrQuestionMoyen;
}

public void setNbrQuestionMoyen(int nbrQuestionMoyen) {
    this.nbrQuestionMoyen = nbrQuestionMoyen;
}

public int getNbrQuestionDifficle() {
    return nbrQuestionDifficle;
}

public void setNbrQuestionDifficle(int nbrQuestionDifficle) {
    this.nbrQuestionDifficle = nbrQuestionDifficle;
}

public Collection<Resultat> getResultats() {
    return resultats;
}

public void setRésultats(Collection<Resultat> resultats) {
    this.resultats = resultats;
}

}
}

【问题讨论】:

  • 您应该在执行查询以获取测试的地方发布代码。因为那是您必须调整并告诉您的 db-provider 获取所有问题的部分。
  • 这是一个简单的选择查询。 test.getQuestions
  • 不,我不是说你如何调用 test.getQuestions()。我的意思是你用来从数据库加载测试对象的java代码。在该查询中,您可以指定应获取所有问题。但是如何取决于你是使用 CriteriaApi、HQL 还是其他的东西。
  • 我从 Bindings 加载它

标签: java jpa


【解决方案1】:

当您获得Test 并稍后访问Test.questions 时,离开事务后,当Test 实体分离且尚未初始化/获取问题时,您将获得lazy initialization exception。您可以进行特定的提取,或者根据您的配置,您可以在退出事务之前调用Test.getQuestions().size()

参考:How to solve lazy initialization exception using JPA and Hibernate as provider

LazyInitializationException in JPA and Hibernate

Hibernate LazyInitializationException using Spring CrudRepository

【讨论】:

  • 我正在调用 Bindings 的测试问题,所以我不能这样做?你知道这是获取问题还是其他问题?
猜你喜欢
  • 2011-07-21
  • 2014-09-25
  • 1970-01-01
  • 1970-01-01
  • 2019-01-24
  • 2015-08-08
相关资源
最近更新 更多