Hibernate確實(shí)功能強(qiáng)悍,但在易用性、性能上存在缺陷。如果團(tuán)隊(duì)中沒(méi)有一個(gè)精通Hibernate的高手,不適合使用Hibernate。
1. 復(fù)雜的實(shí)體狀態(tài)
3種實(shí)體狀態(tài)的設(shè)計(jì)是種種復(fù)雜性問(wèn)題的根源。在持久化狀態(tài)下不需要save就自動(dòng)同步到數(shù)據(jù)庫(kù)既無(wú)必要又容易造成煩惱。
2. Lazy Load 與 Eager Load
Lazy Load的概念聽(tīng)起來(lái)不錯(cuò),用起來(lái)就不那么妙了,也直接導(dǎo)致產(chǎn)生了Open Session In View這種妥協(xié)方案。此外,在domain類中定義的FetchType只針對(duì)get/load/loadAll有效,對(duì)Query是無(wú)效的,需要再次定義。
3. Open Session In View
Lazy Load引發(fā)的一個(gè)有較多副作用的解決方案。
4. 級(jí)聯(lián)
級(jí)聯(lián)是一個(gè)很好很OO的概念,但往往增加了復(fù)雜度。
5. 批量更新與緩存不一致
Hibernate引入了一級(jí)緩存和二級(jí)緩存,提供了性能的同時(shí)帶來(lái)了緩存一致性的問(wèn)題。批量更新或者其他系統(tǒng)對(duì)數(shù)據(jù)庫(kù)的更新容易造成緩存不一致。
6. 配置繁瑣
Hibernate最初只能使用xml進(jìn)行配置,后來(lái)終于引入了Annotation和CoC(約定優(yōu)于配置)來(lái)簡(jiǎn)化配置,但這種變革并不徹底。Hibernate默認(rèn)把userName映射userName,但實(shí)際開(kāi)發(fā)中,把userName映射為user_name的情況更多些。
7. HQL
HQL是一個(gè)類SQL對(duì)象查詢語(yǔ)言,但正是因?yàn)镠QL與SQL的相似性,往往容易造成混淆,同時(shí)HQL難以調(diào)試,本質(zhì)創(chuàng)建了一種語(yǔ)言,增加學(xué)習(xí)成本。
8. 太多的查詢方案
HQL、QBC、SQL,就不能統(tǒng)一點(diǎn),簡(jiǎn)潔點(diǎn)?
9. N+1次查詢
10. 性能問(wèn)題
總之,Hibernate立足于作一個(gè)完整的自動(dòng)化的能夠適應(yīng)各種環(huán)境的ORM,因此帶來(lái)了100%的復(fù)雜性。但我們實(shí)際需要的只是一個(gè)簡(jiǎn)單的能夠以20%時(shí)間解決80%問(wèn)題的框架,具有對(duì)象-關(guān)系映射,能自動(dòng)生成SQL,能夠讓新手盡快工作就足夠了,也許ActiveRecord是一個(gè)選擇。