在Java/Hibernate的應用我有兩個類Cat
和Kitten
在雙向關係如下描繪慢得多:雙向變得比單向
public class Cat {
...
@OneToMany(mappedBy="cat", fetch = FetchType.LAZY)
@OnDelete(action = OnDeleteAction.CASCADE)
@LazyCollection(LazyCollectionOption.EXTRA)
@Getter
@Setter
private List<Kitten> kittens = new LinkedList();
public void addKitten(Kitten k) {
kittens.add(k);
}
...
}
public class Kitten {
...
@ManyToOne(fetch=FetchType.LAZY)
@Getter
@Setter
private Cat cat;
...
}
在一個巨大的環20000 Kitten
是添加到先前創建的不同Cat
個實體。在for循環的重要代碼如下所示:
....
Kitten k = new Kitten();
k.setAttribut("foo");
k.setCat(currentCat); // (a) line
currentCat.addKitten(k); // (b) line
daoFactory.getKittenDao().save(k);
...
的代碼工作,但不知何故,性能非常慢。在以前的迭代中(單向),應用程序要快得多。由於最終版本應該在100000Kitten
上工作,所以必須有一種改進方法。如果我以上述代碼爲基準測試時間,大約需要40秒。如果我通過刪除線(a)或(b)來模擬單向,則兩種情況下都需要10秒鐘(但如果訪問對象後會產生裂縫)。
所以我的問題是: 難道我錯過的東西,或者是雙向的關係,在Hibernate中非常緩慢的內部維護?由於模擬單向速度要快得多,所以我期望雙向的運行時間大約爲15秒。
更新:
保存實體的代碼是一個SAX解析器的DefaultHandler裏面執行。因此,在解析XML結構,首先Cat
保存在startElement()
功能後來就Kitten
將被保存在另一個startElement()
通話。 關於@Bartun的建議/問題:我看了一下批處理。問題是,通過使用DAO和startElement()
函數,很難說什麼時候有50個實體被保存來刷新會話。一個計數器可以做到這一點。但是,它沒有通過建立雙向性來解釋性能影響。 事務管理春天@Transactional
上使用啓動XML解析功能。
你有個人資料來看看你在哪裏出血嗎? – efekctive
只是猜測,嘗試persist()而不是save()。 – Steve11235
@ Steve11235堅持使它更糟糕。那麼運行時間是50秒。 – Thanthla