我不得不從數據庫中檢索數據的方法:如何獲得的數據沒有得到「無法初始化代理 - 沒有會話」異常
public static List<ClassA> getAll() {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Criteria criteria = session.createCriteria(ClassA.class);
List result = criteria.list();
tx.commit();
return result;
} catch (HibernateException ex) {
transactionRollBack(tx);
log.error(ex.getMessage());
} finally {
session.close();
}
return null;
}
用例:
List<ClassA> results = getAll();
for (ClassA result : results) {
System.out.println(result); //"could not initialize proxy - no Session" is thrown here
}
如果我理解正確的Hibernate文檔,這是因爲會話已關閉。但是我怎樣才能獲得數據和關閉會話(因爲它需要在下一個即將開始的事務之前關閉)?
更新
這裏是ClassA的內容包括toString()
:
@Entity
@Table(name = "classA")
public class ClassA implements Serializable {
private static final long serialVersionUID = 5163856045361200311L;
private int id;
private String name;
private Set<ClassB> classB = new HashSet<ClassB>(0);
public ClassA() {}
public ClassA(int id, String name) {
this.id = id;
this.name = name;
}
public ClassA(String name) {
this.name = name;
}
public ClassA(ClassA classA) {
this.id = classA.getId();
this.name = classA.getName();
}
@Id
@GeneratedValue(strategy = AUTO)
@Column(name = "id", nullable = false, unique = true)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Column(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@OneToMany(fetch = LAZY, mappedBy = "classA_id")
public Set<ClassB> getClassB() {
return classB;
}
public void setClassB(Set<ClassB> classB) {
this.classB = classB;
}
@Override
public String toString() {
return "ClassA{ id=" + id + ", name='" + name + ", classB =" + classB + '}';
}
}
看來這個問題是與ClassB
,但我不明白它是什麼。下面是ClassB
:
@Entity
@Table(name = "classB")
public class ClassB implements Serializable{
private static final long serialVersionUID = -8481028941663340911L;
private int id;
private Date date;
private ClassA classA_id;
private int classA_counter;
public ClassB() {}
public ClassB(ClassB rec) {
this.id = rec.getId();
this.date = rec.getDate();
this.classA_id = rec.getClassA_id();
this.classA_counter = rec.classA_counter();
}
@Id
@GeneratedValue
@Column(name = "id", nullable = false)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Temporal(DATE)
@Column(name = "date")
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
@ManyToOne(fetch = LAZY)
@JoinColumn(name = "classA_id", nullable = false)
public ClassA getCLassA_id() {
return classA_id;
}
public void setClassA_id(ClassA classA_id) {
this.classA_id = classA_id;
}
@Column(name = "classA_counter", columnDefinition = "int default 0")
public int getClassA_counter() {
return classA_counter;
}
public void setClassA_counter(int classA_counter) {
this.classA_counter = classA_counter;
}
@Override
public String toString() {
return "ClassB { id=" + id + ", date=" + date + ", classA_id=" + classA_id.getName() + ", classA_counter=" + classA_counter +'}';
}
}
我更新了我的消息。我的'toString()'實現有什麼問題? – Dragon
重新閱讀我的答案。 ClassA調用的toString()嘗試打印它包含的一組ClassB實例的內容。所以Hibernate試圖加載這個集合。但會議閉幕。所以你會得到這個例外。不要從ClasA的toString()方法中打印ClassB的集合。 –