Tips of? hibernate +weblogic 8.1 + oracle 9.2 / db2 8.1
bromon原創(chuàng) 請(qǐng)尊重版權(quán)
?????? 最近的工作都是在webligc 8.1 + hibernate的平臺(tái)上做開發(fā),涉及的數(shù)據(jù)庫(kù)是oracle 9.2和db2 8.1。對(duì)于這兩個(gè)數(shù)據(jù)庫(kù)我的了解都遠(yuǎn)遠(yuǎn)不夠,所以開發(fā)中遇到很多問題,還好問題都解決了,很感謝阿古。有的問題也許大家都會(huì)遇到,列出我的解決辦法,供大家參考。
一、weblogic 8.1下的數(shù)據(jù)庫(kù)連接池配置
weblogic 8.1下配置連接池是很容易的,通過console全鼠標(biāo)操作。以前我做過很多次了,駕輕就熟,很快搞定。編寫好pojo和hbm,test一下,結(jié)果拋出了一個(gè)SQLException,具體信息我沒有記錄,大概意思是說(shuō):“事務(wù)沒有被提交,因?yàn)樗幱谝粋€(gè)分布式事務(wù)中,當(dāng)分布式事務(wù)結(jié)束后它會(huì)被提交。”打開oracle,確實(shí)沒有看到測(cè)試數(shù)據(jù),整個(gè)環(huán)境中我沒有使用JTA,也不存在分布式數(shù)據(jù)庫(kù)。Google了一下,看見別人的建議有:
1、????????????? 選擇jdbc驅(qū)動(dòng)的時(shí)候,不要使用xa系列驅(qū)動(dòng)。這個(gè)其實(shí)大家都知道,xa系列驅(qū)動(dòng)是為JTA準(zhǔn)備的,我在配置連接池的時(shí)候也確實(shí)沒有選擇這類驅(qū)動(dòng)。排除。
2、????????????? 修改startWeblogic.cmd,不要啟動(dòng)pointbase。查看startWeblogic.cmd后沒有發(fā)現(xiàn)有啟動(dòng)pointbase的跡象,在端口列表中也沒有發(fā)現(xiàn)。排除。
后來(lái)找到的解決辦法是,配置webloigc的data source時(shí),有這么一個(gè)選項(xiàng):
Honor Global Transactions
它的相關(guān)說(shuō)明是:
Specifies whether this data source will participate in existing global (XA) transactions. Unchecking this option while creating the data source should be done rarely and with care. This option can not be changed once the data source is created.
?????? 就是它了,把它去掉,try again,passed。?
?????? 上述問題在oracle和db2中都存在。
二、時(shí)間字段的處理
開發(fā)過程中涉及到了時(shí)間的存儲(chǔ)和查詢,相關(guān)的處理要依靠oracle和db2自己的函數(shù),有小小區(qū)別。
一個(gè)hibernate中對(duì)oracle進(jìn)行時(shí)間查詢的例子:
from scene.pojo.TaskInfo as ti where and ti.taskStartTime>=to_date('"+start+"','yyyy-MM-dd HH:mi:ss') and ti.taskEndTime<=to_date('"+end+"','yyyy-MM-dd HH:mi:ss')";
?????? 其中的start和end變量為java.util.Date()。使用了oracle的to_date函數(shù)來(lái)做日期轉(zhuǎn)換,很多java程序員也許會(huì)和我一樣,直覺的采用”yyyy-MM-dd HH:mm:ss”的格式作為時(shí)間的正則表達(dá)式,但是在oracle中會(huì)引起錯(cuò)誤:”O(jiān)RA 01810 格式代碼出現(xiàn)兩次”。原因是sql中不區(qū)分大小寫,MM和mm被認(rèn)為是相同的格式代碼,所以oracle的sql采用了mi代替分鐘。
?????? DB2中的查詢語(yǔ)句是:
from scene.pojo.TaskInfo as ti where and ti.taskStartTime>=timestamp('"+s+"') ?and ti.taskEndTime<=timestamp('"+e+"')";
?????? DB2中的函數(shù)是timestamp,無(wú)須指定時(shí)間格式。
三、Hibernate的lazy loading
Lazy loading是進(jìn)行集合映射時(shí)很有用處的優(yōu)化選項(xiàng),但是使用起來(lái)容易遇到問題。比如在我們的應(yīng)用中,user->post形成一對(duì)多的映射,User中有一個(gè)包含post的List。同時(shí)系統(tǒng)采用了一個(gè)HibernateSession來(lái)管理session,它的邏輯是每進(jìn)行一次數(shù)據(jù)庫(kù)操作,就開新的session,操作完成后立即關(guān)閉該session。這樣做的好處是可以嚴(yán)格關(guān)閉session,避免菜鳥級(jí)的錯(cuò)誤,但是hibernate.org并不推薦這么做。因?yàn)檫@不適合lazy loading,也不適合跨方法的事務(wù)。
回到我們的例子,在User中,有多個(gè)屬性:name,password,phone等,還有一個(gè)List類型的posts。當(dāng)我們對(duì)posts使用lazy laoding的時(shí)候,hibernate會(huì)在獲得User對(duì)象的時(shí)候,僅僅返回name,password,phone等基本屬性,當(dāng)你訪問posts的時(shí)候,它才會(huì)從數(shù)據(jù)庫(kù)中提取posts需要的數(shù)據(jù),這就是所謂lazy laoding。但是在我們的系統(tǒng)中,session是被立即關(guān)閉的,也就是在讀取了name,password,phone等基本屬性后,session已經(jīng)close了,再進(jìn)行lazy loaiding就會(huì)有異常。
解決辦法是在close session之前,調(diào)用Hibernate.initialize(user.getPosts()),告訴系統(tǒng),user.getPosts()是需要lazy laoding的。但是這樣做會(huì)破壞HibernateSession類的封裝,郁悶。
后來(lái)采用所謂的OpenSessionInView模式,把session的周期交給servlet filter來(lái)管理,每當(dāng)有request進(jìn)來(lái),就打開一個(gè)session,response結(jié)束之后再關(guān)閉它,這樣可以讓session存在于整個(gè)請(qǐng)求周期中。但是在實(shí)際操作過程中,發(fā)現(xiàn)一下問題:
Lazy laoding應(yīng)該是兩條select構(gòu)成的,但是在使用了OpenSessionInView模式后,系統(tǒng)執(zhí)行了一條select,session就被關(guān)閉了。相同的代碼,放到普通環(huán)境中,就執(zhí)行正常,目前這個(gè)問題已經(jīng)在java eye掛了很久,無(wú)人解答。望高人指點(diǎn)。
posted on 2005-07-11 17:31
Sometimes Java 閱讀(331)
評(píng)論(0) 編輯 收藏 所屬分類:
Tech Flow