2010-02-08 93 views
1

我有一個家長(程序)pojo與他們的孩子(訂戶)有多對多的關係。與休眠的多對多關係的循環序列化

問題是,當它串行化程序,它也串行化方案的用戶,其中包括他們的串行化程序,其中涉及連載他們的用戶,直到它已連載數據庫中的每一個程序&用戶。

的ERD樣子:計劃< - >用戶

這意味着什麼數據(JSON)的微小17KB塊返回已成爲一個6.9MB的回報。這樣就反過來吹出了連續數據然後返回的時間。

爲什麼我的父母返回孩子返回父母回國孩子?我怎樣才能阻止這個,所以我只能得到每個程序的訂閱者?我假設我的註釋做錯了,也許?我想保持多對多的關係,但沒有深度嵌套的數據檢索。

(注:?我已經事先嚐試添加儘可能多的懶註解我能找到的只是爲了看看有沒有什麼幫助它不也許我做了錯誤的太)

Program.java

@Entity 
@Table(name="programs") 
public class Program extends Core implements Serializable, Cloneable { 
    ... 
    @ManyToMany() 
    @JoinTable(name="program_subscribers", 
     joinColumns={@JoinColumn(name="program_uid")}, 
     inverseJoinColumns={@JoinColumn(name="subscriber_uid")}) 
    public Set<Subscriber> getSubscribers() { return subscribers; } 
    public void setSubscribers(Set<Subscriber> subscribers) { this.subscribers = subscribers; } 

Subscriber.java

@Entity 
@Table(name="subscribers") 
public class Subscriber extends Core implements Serializable { 
    ... 
    @ManyToMany(mappedBy="subscribers") 
    public Set<Program> getPrograms() { return programs; } 
    public void setPrograms(Set<Program> programs) { this.programs = programs; 

}

實施

public Collection<Program> list() { 
    return new Programs.findAll(); 
} 

回答

-1

Bozho和ponkin都在正確的軌道上。我需要停止串行化數據,但最大的問題是我無法改變序列化發生的pojo - > toJSON類/方法。我還擔心在toJSON()方法上投入時間,因爲考慮到我在序列化過程中遇到了這樣的性能問題,我想要一個在我得到數據之前就會發生的修復,而不是之後的修復。

而且由於許多一對多雙向設計的本質我已經上市,我總是有這樣的循環程序/用戶/程序/ ...問題。

分辨率:(現在ATLEAST)我已刪除了Subscriber.getProgram()方法和創建對ProgramDAO取景器方法,該方法由用戶返回程序。

public List<Program> findBySubscriber(Subscriber subscriber) { 
    String hql = "select p " + 
    "from Program p " + 
    " join p.subscribers s " + 
    "where s = :sub" 
    ;  

    Query q = getSession().createQuery(hql); 
    q.setEntity("sub", subscriber); 

    List<Program> l = q.list(); 
    return l; 
} 

對於任何CRUD工作,我想我只是要循環Programs.getSubscribers,或編寫更多的hql輔助方法。

3

你沒有提到你正在使用JSON序列化框架,所以我會承擔JAXB。無論如何,這個想法是以某種方式使Subscriber.getPrograms(..)瞬變,以便它不被序列化。 Hibernate負責這些「循環」,但其他人卻不這樣做。所以:

@XmlTransient 
@ManyToMany(..) 
public Set<Program> getPrograms()... 

如果您使用其他框架,它可能有不同的註釋/配置用於指定瞬態字段。像transient關鍵字一樣。

另一種方法是自定義您的映射器以手動處理循環,但這很乏味。

+0

這是一個手我下來的項目,我不是100%有什麼用JSON序列化。我看到com.sdicons.json.mapper.JSONMapper.SimpleMapperHelper引用。我們有一個方法public JSONValue toJSON(Object pojo)會拋出MapperException異常{}。 (猜它的推出自己的序列化) – 2010-02-08 22:50:11

+0

另外,如果我註釋getPrograms()@XmlTransient這將意味着我永遠無法返回用戶程序? – 2010-02-08 22:54:43

+0

是的。另一個是自定義您的映射器以手動處理週期。 – Bozho 2010-02-09 06:36:14

1

1)「你的」序列化是如何工作的。我的意思是它是JAXB或自定義序列化或別的。 2)幾乎所有的框架都可以讓你設置序列化的深度。我的意思是你可以設置例如深度在2. 3)我建議你不要序列化與兒童的對象,標記他們(兒童)瞬態,並分別序列化。