views:

522

answers:

1

In using Hibernate's JPA implementation, I noticed an interesting optimization behavior. Within the same transaction, the initial JPA query's WHERE clause is used for subsequent queries involving the results of the initial query.

For example, person has lastName and a set of owned books.

// (1) get person by last name
Query q = entityManager.createQuery("SELECT p FROM Person p WHERE p.firstName = :lastName");
q.setParameter("lastName", "Smith");
List<Person> persons = q.getResultList();

// (2) get books owned by some arbitrary person in persons
Person person = persons.get(n);
Collection<Book> books = person.books;

(1) translates to the SQL:

SELECT ... FROM Person WHERE lastName = 'Smith'

When (2) is run and accesses Person's books, it generates the SQL:

SELECT ... FROM Person_Book book0_ WHERE book0_.personId IN (SELECT ... FROM ... WHERE lastName = 'Smith')

Somehow the WHERE clause from (1) is remembered and used in subsequent queries (2) involving the retrieved person. What is this behavior in Hibernate called and how can I configure it?

Follow up: I'm using subselect on person's books. This explains the behavior that I'm seeing.

+1  A: 

Extracted from this link:

The last form of fetching I want to cover is subselect fetching. Subselect fetching is very similar to batch size controlled fetching, which I just described, but takes the 'numerical complications' out of the equation. Subselect fetching is actually a different type of fetching strategy that is applied to collection style associations. Unlike join style fetching, however, subselect fetching is still compatible with lazy associations. The difference is that subselect fetching just gets "the whole shootin' match" as a co-worker of mine would say, rather than just a batch. In other words, it uses subselect execution to pass the ID set of the main entity set into the select off of the association table:

select * from owner

select * from pet where owner_id in (select id from owner)

SourceRebels