Of the dangers of using Spring Security, Hibernate and paging

Here’s a tricky one; we need to do paging on one of our listing pages. The obvious solution was the following, which is a common pattern:

@Secured(value={Roles.PERSON_READ})
public List<Person> getPeople(int offset, int max) {
   Criteria criteria = getSession().createCriteria(Person.class);
   criteria.setFirstResult(offset;
   criteria.setMaxResults(max);
   return criteria.list();
}

Can you see it? The bug I mean? See it? How about now? Now?

The problem lies in the @Secured annotation. This little guy is SOOOOOO useful for us, but it will burn you once in a while. This annotation will proxy the method and remove any objects which you aren’t allowed to get back. i.e.: It will filter the returned list.

I guess you see it now: If I ask Hibernate to give me rows from 20 to 50, I am in no way garanteed to get back 30 results since Spring will remove items from my list AFTER the query has run and Hibernate has created the list.

The solution? I guess that really depends on your own requirements. Given our own volume and requirements, pulling out all the data on each page request is acceptable (we have a query cache enabled, so it’s not as bad as it may sound).