我有同樣的問題,我希望能夠建立密鑰而不是使用所有這延遲加載的東西。我覺得冬眠到如此脆弱,錯誤和神祕的幽靈班到處都是。到目前爲止,這並不能簡化我的生活。試想一下:
模型(非常簡單):
Portfolio {
...
@OneToMany(cascade = {CascadeType.ALL}, fetch=FetchType.EAGER)
@MapKey(name="symbol")
public Map<String,Position> positions;
}
Position {
String symbol; int quantity;
}
Trade {
String symbol; int quantity; // price,etc
...
@ManyToOne() // looser coupling here.
public Portfolio portfolio;
}
測試用例(注:全「enterTrade()」做的是堅持貿易在貿易表 在投資組合調整位置大小, '撤銷貿易()'只是恢復):
Trade trade1 = new Trade("GOOG", 25, portfolio);
Trade trade2 = new Trade("GOOG", 50, portfolio);
portfolio = portfolioDAO.enterTrade(trade1);
portfolio = portfolioDAO.enterTrade(trade2);
portfolio = portfolioSource.undoTrade(trade1, user);
portfolio = portfolioSource.undoTrade(trade2, user);
Assert.assertFalse(portfolio.getPositions().containsKey("GOOG"),
"after both trades net a position of zero");
這個測試應該正常嗎?錯誤!神祕地,投資組合中仍然有25個GOOG股。
的基本問題是trade2對象指向變得陳舊組合對象。最後的撤銷交易()操作使用仍然擁有75股GOOG的投資組合。請注意,Trade2永遠不會陳舊,因爲只有persist()已經被執行。但是當在Portfolio上執行update()時,會創建額外的副本,而不是更改原始對象(就像'persist()'所做的那樣)。我很難理解爲什麼這個設計不會被認爲是愚蠢和容易出錯的。這是一個簡單的例子。這不像我們正在談論的併發訪問問題或任何幻想。哦,當我嘗試刷新trade2時,得到LazyInitializationException,這完全是莫名其妙的。
所以,我的解決辦法是讓每一位需要刷新才能使用的密鑰是明確的:
Trade {
...
@ManyToOne(targetEntity=Portofio.class)
@JoinColumn(referenceColumnName="id")
public Long portfolio_id;
}
或什麼的。儘管我在這裏表達了很多挫折,但我很樂意聽到如何解決這些問題的誠實解釋。謝謝。
是但我需要經由SOAP運送這些對象到客戶端,以便客戶端需要有一種方法,其中將約聯繫實體即乙進一步的信息可以,所以我需要要麼提供一個裁判B(其是指具有另一查詢用於SOAP通信的對象模型)或'完整'對象A即對象A的所有字段加上'完整'對象B – Chetan 2009-10-21 10:38:02
聽起來就像你需要一個DAO(Dataaccess對象)。 無論是休眠還是別的什麼能夠持久對象,而無需對實例的引用...你總是可以有兩個映射一類 - 一個RealA和partialA一個正確映射和對方只是作爲純粹的價值。您可以使用entity-name爲同一個類使用多個映射。 – 2009-10-25 19:09:04