I'm using the filtering capabilities present in hibernate 3.0 (filter, filter-def) and find that they provide an elegant solution to providing different visibilities based upon context.

The problem that I'm running into is that the filtering only occurs on the initial query of the data. If an object is cached (either in the first or second level cache), adjusting the filters (turning on/off, or updating query parameters values) has no effect.

E.g.,

If I have a category object that points to a collection of products, these products could be filtered by "start date". If I enable the filter for the session and request the category the products are properly filtered. If later in the session I disable the filter I am still only getting back the initially filtered products.

I realize that this is happening because the filtering really does happen in the select from the database and since the object is cached the filtering is not happening again.

Especially with a second level cache where most objects will be cached in memory, I'm not sure if I can assume filtering will ever return the correct results.

What you are saying in true of the first level cache. Enabling and then disabling of filters on the same session with the effect you are seeming to want is not supported. We had discussed this exact scenario when developing the filters and determined that the behavior you are seeing is the correct one. The reason is that the first level cache is a cache associated with the currernt unit of work. Part of that responsibility is "uniqueing" of data. Uniqueing refers to the assertion that the same entity loaded multiple times from the same session always return the same object instance. Allowing that same entity instance to have different physical collection instances in that scenario depending upon which filters happened to be in effect when the given load occurred logically breaks uniqueing.

FYI, enabled filters always force a bypass of the second-level cache both for write and for read. The above discussion is strictly in terms of the first level cache.

So how do you get around this? I have an EJB application which is using Hibernate SessionFactory bound to EJB container's JTA. So session boundary is pretty much equivalent to transaction boundary. I also have a situation where I change filter parameters within single session, and like in the case described above, the query results are always the same (even when parameters are different) because Hibernate returns data from level 1 cache (the entity containing the collection is always the same).

Since I'm writing DAO layer that will be used by others to maintain persistence of their data, I don't think I can close/clear/reopen session just to flush collection data from the cache. What if they load other objects, update them, then call my method and I flush the session/cache? They will save their modified objects thinking they will be updated, but since Hibernate cache will not know about those objects (the session has been flushed), those objects will be inserted instead.

Is there a way to update the collection data without clearing the session? And if not, what can be done in this situation to get the expected results?