假設某 POJO 有屬性如下: private Set users = new HashSet(0); @OneToMany(fetch = FetchType.LAZY, mappedBy = "xuser") public Set getUsers() { return this.users; ...
假設某 POJO 有屬性如下:
private Set<User> users = new HashSet<>(0); @OneToMany(fetch = FetchType.LAZY, mappedBy = "xuser") public Set<User> getUsers() { return this.users; }
如果我們使用jackson將其序列化,運行時會報錯:
failed to lazily initialize a collection of role ...
解決方法一:
通過 Hibernate 的 OpenSessionInViewFilter 使得 FetchType 為 LAZY 的屬性在序列化時為空,在 web.xml 中添加代碼如下:
<filter> <filter-name>openSession</filter-name> <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class> <init-param> <param-name>singleSession</param-name> <param-value>false</param-value> </init-param> </filter> <filter-mapping> <filter-name>openSession</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
儘管 users 為空,但欄位依然保留,對應輸出:
{...,"users":[],...}
解決方法二:
在屬性的 get 方法之前加上註解 @JsonIgnore,如此在轉換為 JSON 時該欄位被忽略:
import com.fasterxml.jackson.annotation.JsonIgnore;
…
private Set<User> users = new HashSet<>(0); @JsonIgnore @OneToMany(fetch = FetchType.LAZY, mappedBy = "xuser") public Set<User> getUsers() { return this.users; }
…
註意引入的類是 com.fasterxml.jackson.annotation.JsonIgnore,如果使用 org.codehaus.jackson.annotate.JsonIgnore 則不能生效,見 Spring @JsonIgnore not working 。
解決方法三:
fetch = FetchType.LAZY 改為 fetch = FetchType.EAGER,但這樣會導致每次查詢資料庫都要立即提取 OneToMany 的所有對象,所以非常不推薦。