以下是我刚刚遇到的另一个原因:在同一事务中多次调用存储过程时缓存以前的结果。简化代码,如下所示。
//Begin transaction
SessionFactory sf = HibernateSessionFactory.getFactory();
Session dbSession = sf.getCurrentSession();
dbSession.beginTransaction();
//First call to stored procedure
Query query = dbSession.getNamedQuery("RR_CUST_OPP_DATA");
query.setString("custName", "A");
List<ShipSummaryRow> shipSummaryRows = query.list();
//Second call to stored procedure
Query query = dbSession.getNamedQuery("RR_CUST_OPP_DATA");
query.setString("custName", "B");
List<ShipSummaryRow> shipSummaryRows = query.list();
//Commit both
dbSession.getTransaction().commit();
在第一次调用后没有 clear(),则第一次调用的结果集行将复制到第二次调用的结果集中。我使用的是Oracle 11gR2。
复制此 Bug 的关键是在同一事务中进行两次调用。由于我使用的是视图模式中的开放会话,因此两个调用都自动发生在同一事务中(因为原始代码在存储每个调用结果的循环中调用proc)。因此,我称之为错误;else可以被认为是一个功能,但即使这样,clear()也没有在代码示例中被调用,说明它应该被调用。session.flush() 什么也没做。映射文件,如下所示。因此,我已将 clear() 添加到所有过程调用的末尾。尚未使用我的自定义 SQL 调用进行测试。这是微不足道的事情;惊讶于错误的存在。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.jfx.rr.model.ShipSummaryRow">
<id name="id" type="integer"/>
<property name="shipQtrString" not-null="true" type="string"/>
<property name="shipAmount" not-null="true" type="double"/>
</class>
<sql-query callable="true" name="RR_CUST_OPP_DATA">
<return class="com.jfx.rr.model.ShipSummaryRow">
<return-property column="SHIPPED_ID" name="id"/>
<return-property column="SHIP_QTR" name="shipQtrString"/>
<return-property column="SHIPPED_AMOUNT" name="shipAmount"/>
</return>
{ call RR_DASHBOARD_REPORTS_PKG.RR_CUST_OPP_DATA(?, :custName) }
</sql-query>
</hibernate-mapping>