ロールのコレクションを遅延初期化できませんでした:コム...ポジョ学生。phonenos、セッションまたはセッションが閉じられていませんでした
-
27-10-2019 - |
質問
私は注釈を使って休止状態のマッピングを学んでいます。私は一つのセクションを完了しました。つまり親テーブルを保存するときに子クラスを自動的に挿入できます。 を参照してください。.
しかし、私はマスターテーブルをフェッチしているときに子テーブルを取得しませんでした。また、エラーが発生します
failed to lazily initialize a collection of role: com.pojo.one2many.unidirectional.Student.phonenos, no session or session was closed
私のコードはあなたを確認するためにここに追加されています。それを通過してください。そして、私に偉大なアドバイスを与えます。学生。ジャバ。(親クラス)
@Entity
@Table(name="STUDENT")
public class Student {
private int studentid;
private String studentName;
private Set <Phone> phonenos;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="studenId")
public int getStudentid() {
return studentid;
}
public void setStudentid(int studentid) {
this.studentid = studentid;
}
@Column(name="studenName")
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name="studenId")
public Set<Phone> getPhonenos() {
return phonenos;
}
public void setPhonenos(Set<Phone> phonenos) {
this.phonenos = phonenos;
}
電話だjava(子クラス)
@Entity
@Table(name = "PHONE")
public class Phone {
private int phoneid;
private String phoneNo;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "phoneId")
public int getPhoneid() {
return phoneid;
}
public void setPhoneid(int phoneid) {
this.phoneid = phoneid;
}
@Column(name = "phoneno")
public String getPhoneNo() {
return phoneNo;
}
public void setPhoneNo(String phoneNo) {
this.phoneNo = phoneNo;
}
私のdaoクラス
public List<Student> getAllStudent() {
List<Student> studentList = null;
try {
DetachedCriteria criteria = DetachedCriteria.forClass(Student.class);
studentList = (List<Student>)getHibernateTemplate().findByCriteria(criteria);
if(studentList != null && ! studentList.isEmpty()){
for(Student st :studentList){
System.out.println(" st name : "+st.getStudentName());
if(st.getPhonenos() != null && ! st.getPhonenos().isEmpty()){
for(Phone ph : st.getPhonenos()){
System.out.println(" ph no : "+ ph.getPhoneNo());
}
}else{
System.out.println(" phone number is null");
}
}
}else{
System.out.println(" student null");
}
} catch (DataAccessException e) {
e.printStackTrace();
}
return studentList;
}
アウトプットは
failed to lazily initialize a collection of role: com.pojo.one2many.unidirectional.Student.phonenos, no session or session was closed
ここでは、単方向(外部キー)の1対多マッピング(ジョイントテーブルではなく、双方向)を使用しています。
私の質問を夏にする
1)親テーブルを取得するときに子テーブルを取得する方法、その逆
2)熱心で怠惰なフェッチとは何ですか。
3)一方向、双方向、および結合テーブル一対多マッピングの場合、どちらがより多くのパワーフルであるか。
解決
1)
これらのクラスのエンティティが取得されるたびにこれを実際に実行する場合は、次のように指定します FetchMode.EAGER
の中で @OneToMany
協会。 @ManyToOne
デフォルトでは熱望しています。特定の状況でのみこれらのエンティティを取得する必要がある場合、これはほとんど効果がない可能性があることに注意してください。その場合は、あなたがやっているようにそれを行う必要がありますが、取得したセッションを確認してください Student
オブジェクトはまだ開いています。Springを使用していることを確認して、DAO/サービスに注釈を付けてみましたか @Transactional
, 、メソッドの実行中にセッションが生き続けるように?またはあなたは使ってみましたか Hibernate.execute()
, 、このように:
getHibernateTemplate().execute(new HibernateCallback(){
@SuppressWarnings("unchecked")
public Object doInHibernate(Session s) throws HibernateException, SQLException {
Criteria c = s.createCriteria(Student.class);
List<Student> studentList = c.list();
for(Student st :studentList){
st.getPhoneNos();
}
}
});
2)この質問を見てください: Java永続性におけるFETCHTYPE LAZYとEAGERの違いは何ですか?.
3)それは必要とするものをによって決まります。関連付けを1つの方法でのみナビゲートする必要がある場合は、その方法でのみ単方向を定義します。両方が必要な場合は、両方を行います。結合テーブルは、データベース設計と関係があります。あなたがFKを持っているしたい場合 Phone
への参照を持つ表 Student
電話が属している、またはあなたが持っていると結合テーブルを持っているしたいです Phones
すべての Student
.