Search code examples
mysqlhibernatesessioncriteria

Changes done in a hibernate session in one method are not visible to select query using criteria within the same session


I have a table A with many columns including a column "c". In a method, I update the value of "c" for row "r1" to "c1" and in one of the subsequent methods (still running in the same thread), I try to read all rows with value of "c" equal to "c1" using hibernate's criteria.

The code snippet is shown below:

@Transactional
public void updateA(long id, long c1)
{
    Session currentSession = sessionFactory.getCurrentSession();
    A a1 = (A) currentSession.get(A.class.getName(), id);
    a1.setC(c1);
    currentSession.saveOrUpdate(a1);
}

@Transactional
public void getAllAsForGivenC(long c1)
{
    Criteria criteria = sessionFactory.getCurrentSession().createCriteria(A.class.getName());
    Criterion cValue= Restrictions.eq("c", "c1");
    criteria.add(cValue);
    return criteria.list();
}

But when the method getAllAsForGivenC executes, "r1" row is not returned. Both methods run in the same thread and use same hibernate session. Why is getAllAsForGivenC not able to see the row updated in updateA()? What am I doing wrong?

P.S: I run this on MySQL DB (if that matters)

Thanks in advance, Shobhana


Solution

  • Do session.flush() between your method calls and then try.

    e.g.

    updateA(1l, 2l);
    
    //do Flush
    session.flush();
    
    getAllAsForGivenC(2l);
    

    --Update--

    As the documentation says, The process flush occurs by default at the following points:

    • before some query executions
    • from org.hibernate.Transaction.commit()
    • from Session.flush()

    Except when you explicitly flush(), there are absolutely no guarantee about when the Session executes the JDBC calls, only the order in which they are executed.

    Flushing does not happen before every query! Remember, the purpose of the Hibernate session is to minimize the number of writes to the database, so it will avoid flushing to the database if it thinks that it isn’t needed.

    It would have been more intuitive if the framework authors had chosen to name it FlushMode.SOMETIMES.