title: Reloading objects from database, not cache, after stored procedure updates database?
body: <p>I am using Hibernate to access an Oracle database.</p>
  
  <p>I think I am having some trouble with Hibernate's first-level (or session) cache. I have tables representing accounts: the ACCOUNT table, the INVOICE table, and the PAYMENTS table. 
  There are procedures defined in the Oracle database so that adding a PAYMENT will automatically update columns in the associated INVOICE and ACCOUNT tables.</p>
  
  <p>The problem I have is when I use Hibernate to do something like the following:</p>
  
  <pre><code>Account account = accountDao.get(accountId);
  assertEquals(0.00, account.getBalance());
  
  // Saving a payment will trigger stored procedures that 
  // will update the account balance.
  paymentDao.save(createPaymentForAccount(accountId, 20.00));
  
  account = accountDao.get(accountId);
  assertEquals(20.00, account.getBalance()); 
  </code></pre>
  
  <p>The final assertion will fail because <code>account.getBalance()</code> returns <code>0.00</code> rather than <code>20.00</code>.</p>
  
  <p>I want the second call to <code>accountDao.get(...)</code> to hit the database, and get the new ACCOUNT object back. But Hibernate appears to return the account object already in its cache (when I inspect the debug output for the lookup call, I see <code>number of objects hydrated: 0</code>).</p>
  
  <p>I assume that Hibernate is unaware that the database has changed because of the stored procedure call, which is why it uses the object in its cache. </p>
  
  <p>So I began thinking about solutions. One is to remove any ACCOUNT and PAYMENT objects from the hibernate session cache whenever a PAYMENT is saved. This will force a database fetch (with the newly updated values) for any ACCOUNT or INVOICE operation.</p>
  
  <p>I tried the following:</p>
  
  <pre><code>public void save(Payment payment) {
    getSession().persist(payment);
    getSessionFactory().evict(Invoice.class);
    getSessionFactory().evict(Account.class);
  }
  </code></pre>
  
  <p>But the hibernate trace log showed that nothing happened. I think that <code>sessionFactory.evict(...)</code> operates on the second-level cache, which is not enabled and so there's nothing to evict.</p>
  
  <p>Next I tried evicting all ACCOUNT and INVOICE objects from the session cache by evicting each instance I could find:</p>
  
  <pre><code>public void save(Payment payment) {
    getSession().persist(payment);
    for (Invoice invoice: lookupInvoices()) { // e.g. "from Invoice" query
      getSession().evict(invoice);
    }
    for (Account account: lookupAccounts()) { // e.g. "from Account" query
      getSession().evict(account);
    }
  }
  </code></pre>
  
  <p>This seems to work, but is horribly inefficient, because it loads all instances into the hibernate session cache before evicting them, when all I really want to do is evict any current instances in the session.</p>
  
  <p>I cannot see any way of clearing the first-level cache of all objects of a specified type, so what other solutions are available?</p>