Hibernate provides (at least) two options for getting around the N+1 query problem. The one is setting the FetchMode to Subselect, which generates a select with a IN-clause
I found this article to be helpful. I believe batch-fetching can be applied on both the collection and the parent, while subselect can only be applied on a collection.
In case of a fetching strategy for collections, a subselect will be executed once (because the batch-size is effectively infinity), while with batch-fetching the SQL statement might be executed multiple times.
I don't use subselect, because it is hard to control. In a very large system which has complex business logic and a large team working on it, it is too hard to say which queries are used. Subselect may work in specific cases where you exactly know which query is performed.
Batch fetching has some big advantages. It is not always the fastest, but usually fast enough. On the other hand it is very stable, doesn't have any side effects and is completely transparent to the business logic. I never use batch values higher then 100. It is sufficient to reduce the N+1 to some reasonable amount of queries.