2011-02-02 63 views
2

我在將數據轉換爲json時遇到問題。使用JSONArray.fromObject將Hibernate實體轉換爲json

Session session = sessionFactory.openSession();  
Affiliate affiliate = (affiliate) session.get(Affiliate , pk); 
session.close(); 
JSONArray.fromObject(affiliate); 

調試器顯示行被提取。
,但我得到試圖轉換到JSON字符串時,此異常:

Exception in thread "main" net.sf.json.JSONException: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.affiliates.hibernate.Affiliate.employees, no session or session was closed 
at net.sf.json.JSONObject._fromBean(JSONObject.java:959) ... 

這是我加盟實體

@Entity(name="AFFILIATE") 
    @Inheritance(strategy=InheritanceType.SINGLE_TABLE) 
    public class Affiliate extends HibernateBean{ 

     @Id 
     @GeneratedValue(strategy=GenerationType.IDENTITY) 
     @Column(name="AFFILIATE_ID") 
     private long id; 

     @ManyToOne(targetEntity = Affiliate.class) 
     @JoinColumn(name="PARENT_ID") 
     private Affiliate parent; 



     @ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY) 
     @JoinTable(name="EMPLOYEES_AFFILIATES" , joinColumns = {@JoinColumn(name="AFFILIATE_ID")},inverseJoinColumns={@JoinColumn(name="EMPLOYEE_ID")}) 
     private Set<Employee> employees = new HashSet<Employee>(0); 

getters and setters... 

    } 

感謝

回答

6

employees收集被標記爲FetchType.LAZY,因此它的牽強懶散,並且在會話關閉時無法提取。

您有幾種選擇:

  • 如果收集需要每次加載Affiliate對象,將其標記爲預先抓取:

    @ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER) 
    
  • 如果你需要集合只在在這種情況下,指示Hibernate加載它:

    • 隨着JOIN FETCH條款:

      Affiliate affiliate = (Affiliate) session.createQuery(
          "from Affiliate a join fetch a.employees where a.id = :id") 
          .setParameter("id", pk).uniqueResult() 
      
    • 隨着Hibernate.initialize()

      Affiliate affiliate = (Affiliate) session.get(Affiliate , pk); 
      Hibernate.initialize(affiliate.getEmployees()); 
      
    • 隨着Fetch Profiles

  • 響應之前已準備好,請不要關閉會話。使用Open Session in View模式。

+0

謝謝,我不明白一件事,取懶意味着emplyees將是空的,不是? ...因爲如果我正在寫affiliate.setEmployees(null),它工作正常。這是我理解提取懶惰假設要做的,將emplyees設置爲null。 – fatnjazzy 2011-02-02 14:15:04

0

如果您不更改數據庫,切勿更改實體。他們應該匹配。將實體更改爲渴望實體會破壞整個延遲加載的想法,並且在您的代碼中可能會有其他地方因爲它而引入性能問題。這就是說,如果你改變實體,那麼每個人在每次使用該實體時都必須加載所有的數據。

你想要的是一個嵌套事務。在執行JSON轉換的方法調用的開始處開始您的事務,並在方法結束時結束它。通過簡單地向包含此JSON轉換的方法調用添加事務註釋來實現此目的。

完成此操作後,事務將不會在需要信息時發生並且可能發生延遲加載。可能在代碼中還有其他地方完成此操作。尋求他們,並用它們作爲示例,從而解決您的解決方案。

當然,如果您將在很多地方使用此功能,您可能需要實際將其推入DAO中,以便重複使用。