Suppose I create a single customer with three associated orders as follows:
Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Customer customer = new Customer(); customer.setForename("Hedley"); customer.setSurname("Proctor"); session.save(customer); Order order1 = new Order(); order1.setOrderTotal(29.99); order1.setCustomer(customer); Order order2 = new Order(); order2.setOrderTotal(8.99); order2.setCustomer(customer); Order order3 = new Order(); order3.setOrderTotal(15.99); order3.setCustomer(customer); session.save(order1); session.save(order2); session.save(order3); session.flush();
As you can see, I’ve called flush() on the session, so the data has been sent to the database. Now let’s write a query that will pick out this customer, and assert that they have three orders:
Criteria criteria = session.createCriteria(Customer.class); criteria.add(Restrictions.eq("forename","Hedley")); criteria.add(Restrictions.eq("surname","Proctor")); List results = criteria.list(); Customer customer1 = (Customer) results.get(0); assertEquals(customer1.getOrders().size(),3);
This assertion will fail! Why? Because this criteria query just returns the customer object that you already have, which is in the session. Despite the fact that in the database the orders table really does have the correct foreign keys to the customers, because Hibernate has flushed all of the objects to the database, it doesn’t think that the session is dirty, so will happily return the Customer object that is the in session. What should you do to prevent confusion like this? The answer suggested by Java Persistence with Hibernate is that when you have a bidirectional association you should always have a helper method to add items to it, that will set both sides of the association, so you will never get this discrepancy between the session objects and the contents of the database.
This article is part of a series on Hibernate. You might be interested in some of the others:Hibernate query limitations and correlated sub-queries Bespoke join conditions with Hibernate JoinFormula Inheritance and polymorphism One-to-many associations One-to-one associations Many-to-many associations