I'd recommend a hybrid of your last two approaches. Add an averageRating attribute to the Book class, mark it as transient and use something like this to lookup a Book instance with JPQL (I'm sure HQL supports something similar):
Code:
SELECT new Book( b, AVG( r)) FROM Book b IN( b.ratings) r
With a constuctor on Book to copy the persistent properties out.
This doesn't pollute your code with a bunch of helper objects and methods that only really care about the average rating, only requiring Book to initialize itself from another Book instance.
--
Tim