2012-12-13 35 views
4

我目前正在使用休眠和彈簧的測驗工具。實際上,我把它作爲一個Sakai LMS工具來構建,這會讓這個問題更加複雜化,但讓我看看我能否推廣。休眠寫後跟讀取原因找不到對象

我目前的情況是當用戶進入一個StartQuiz頁面,當他們在頁面上提交表單時,初始化一個Attempt對象(由hibernate存儲)。它填充以下對象:

<class name="org.quiztool.model.Attempt" table="QT_ATTEMPTS"> 
    <cache usage="transactional" /> 

    <id name="id" type="long"> 
     <generator class="native"> 
      <param name="sequence">QT_ATTEMPTS_ID_SEQ</param> 
     </generator> 
    </id> 
    <many-to-one name="quizId" class="org.quiztool.model.Quiz" cascade="none" /> 
    <property name="score" type="int" not-null="true" /> 
    <property name="outOf" type="int" not-null="true" /> 

    <list name="responses" cascade="none" table="QT_RESPONSES" lazy="false"> 
     <key column="id"/> 
     <index column="idxr"/> 
     <many-to-many class="org.quiztool.model.QuizAnswer" /> 
    </list> 

    <list name="questionList" cascade="none" table="QT_ATTEMPT_QUESTIONS" lazy="false"> 
    <key column="id"/> 
     <index column="idxq"/> 
    <many-to-many class="org.quiztool.model.QuizQuestion" /> 
    </list> 

    <property name="userId" type="string" length="99" /> 

    <property name="siteRole" type="string" length="99" /> 
    <property name="startTime" type="java.util.Date" not-null="true" /> 
    <property name="finishTime" type="java.util.Date" />   
</class> 

它隨機挑選出一組問題,並設置開始時間和其他一些屬性,然後通過Hibernate保存對象後,用戶將TakeTheQuiz頁面重定向。

在TakeTheQuiz頁面上,它通過作爲請求參數傳遞的ID加載嘗試對象,然後將其打印並格式化爲html表單,供用戶填寫測驗。約2/5的併發用戶不會看到任何問題。嘗試對象加載,其問題爲空。

我的理論是,Attempt對象中的問題列表要麼不是立即插入數據庫(只要對象進入休眠緩存,就可以了,我可以從緩存中獲取它,不知道該怎麼做)或者它保存到數據庫,但是我在TakeTheQuiz頁面上加載的對象正在從緩存中讀取一個不完整的對象。

不可否認,我的Hibernate知識是有限的,所以如果有人能幫助我理解可能發生的情況以及如何解決問題,請告訴我。

回答

1

我發現答案很簡單。看起來我的保存功能是懶惰地向數據庫提交的。一旦我在每次交易結束時強制提交該對象,問題就解決了。

我最後寫它看起來像這樣我自己的Hibernate的Session代碼:

Session session = getSession(); 
session.beginTransaction(); 
session.saveOrUpdate(attempt); 
session.getTransaction.commit(); 
session.close(); 

問題解決了。

0

我的理論是隨機挑選問題的那段代碼有問題。你確定它有效嗎?請粘貼一些你的代碼。

第二個理論是您的事務邊界有問題。你什麼時候沖洗會議?你的交易什麼時候進行?嘗試一下,並將會話上的FlushMode設置爲始終。這會改變什麼嗎?

+0

我已經在現在放置了一些調試代碼,用於檢查隨機函數發生器和嘗試對象保存後,但在重定向到TakeTheQuiz頁面之前。問題列表包含保存之後和下一頁加載之前的問題。你還想看代碼嗎,還是這樣掩飾它? –

+0

好的。無論如何,我不確定加載對象時的實際操作以及事務邊界的外觀。你嘗試了FlushMode.ALWAYS嗎? – sorencito

+0

此外,我不太瞭解你對緩存的擔憂。你是通過他們的ID加載嘗試我們使用某種查詢? – sorencito