hinbernate懶載入異常org.hibernate.LazyInitializationException: could not initialize proxy
阿新 • • 發佈:2019-02-08
DataGridJSONModel json = new DataGridJSONModel();
PageHolder<IP> holder = ipdao.findPage(page, rows);
List<IP> list = holder.getList();
json.setRows(list);
json.setTotal(holder.getTotal());
return json;
在將返回物件json轉換為JSON語句時報錯
org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: could not initialize proxy - no Session (through reference chain: com.liyunet.common.json.DataGridJSONModel["rows"]->java.util.ArrayList[0]->com.liyunet.domain.IP["attachments"]->com.liyunet.domain .IPAttachments_$$_jvst7f7_1c["id"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: could not initialize proxy - no Session (through reference chain: com.liyunet.common.json.DataGridJSONModel["rows"]->java.util.ArrayList[0]->com.liyunet.domain.IP["attachments"]->com.liyunet.domain.IPAttachments_$$_jvst7f7_1c["id"])
org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:276)
org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:100)
... ...
可以看出類IP中attachments屬性初始化代理失敗,原因是沒有session(session已關閉)。下面是在實體類IP中的定義程式碼
@OneToOne(fetch = FetchType.LAZY)//懶載入
@JoinColumn(name = "attachements_id")
private IPAttachments attachments;
所以,實際上返回的物件json中rows中物件IP的屬性attachments是個代理,所以要初始化。
有三種方法解決此問題:
1. 遍歷傳遞給rows的list,使用Hinbernate.initialize(attachments);初始化attachments欄位。
list.forEach(ip -> {
IPAttachments attachments = ip.getAttachments();
Hibernate.initialize(attachments);
});
2. 使用hql語句立即載入attachments欄位。
修改查詢list的hql語句為:
String hql = "from IP ip inner join fetch ip.attachments order by ip.points desc";
3.使用VO,即將物件IP中需要的幾個欄位查詢出來儲存到一個實體類中,POJO,這樣session關閉之前就會載入,便不會懶載入異常。
class VO{
private String id;
...
}
另外,還有過濾器法,這個還沒有搞懂,暫時擱置。