Criteria and HQL query also use session cache, but they DO a query on the database. Before hydrating the resultset to the fetched data it is checked, whether these objects have already be loaded. This is important to achieve "==" equality within a session:
Code:
Customer customer = session.get(Customer.class, 1L);
Query q = session.createQuery("from Customer c where c.id = :id");
q.setParameter("id", 1L);
//true
System.out.println(customer == q.uniqueResult());
//true
System.out.println(customer == session.createCriteria(Customer.class).add(Restrictions.idEq(1L)).uniqueResult());
Also notice that the session is flushed before querying, so that there would be no dirty objects in a session.