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>

它随机挑选出一组问题并设置开始时间和其他一些属性,然后在通过休眠保存对象后将用户重定向到 TakeTheQuiz 页面。

在 TakeTheQuiz 页面上,它通过作为请求参数传递的 ID 加载尝试对象,然后将其打印并格式化为 html 表单供用户填写测验。大约 2/5 的并发用户将看不到任何问题。尝试对象加载,它的问题是空的。

我的理论是 Attempt 对象中的问题列表要么没有立即插入到数据库中(只要对象进入休眠缓存就可以了,然后我可以从缓存中获取它,我看不到出怎么做)或者它正在保存到数据库中,但是我在 TakeTheQuiz 页面上加载的对象正在从缓存中读取一个不完整的对象。

诚然,我的 Hibernate 知识有限,所以如果有人可以帮助我了解这里可能发生的情况以及如何解决它,请告诉我。

4

2 回答 2

1

我发现答案很简单。似乎我的保存功能正在懒惰地提交数据库。一旦我在每个事务结束时强制提交该对象,问题就解决了。

我最终编写了自己的休眠会话代码,如下所示:

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

问题解决了。

于 2012-12-18T19:37:16.510 回答
0

我的理论是随机选择问题的代码有问题。你确定它有效吗?请粘贴您的一些代码。

第二个理论是你的事务边界有问题。你什么时候刷新会话?您的交易何时提交?试一试,将会话上的 FlushMode 设置为 ALWAYS。这会改变什么吗?

于 2012-12-13T20:46:46.550 回答