Столько всего можно сказать, что аж пальцы разбегаются.
Во-первых, классика - не занимайтесь преждевременной оптимизацией. Вы ведь сделали замеры расхода ресурсов, перед тем как оптимизировать? Этот запрос хотя бы пару раз в секунду выполняется, не реже, нет? Вы ведь точно уверены, что именно это место "жрет" не менее 20% времени от общего времени обработки процесса? И вы ведь в курсе о том, что любые программные кеши - ничто в сравнении с тем, как умеет кешировать любая "приличная" СУБД?
Во-вторых - построение HQL-запросов. Насколько мне известно, для One-To-Many нет разницы между сущностью и её ID. Вы замапили сущность, а не её ID, получив возможность доступа к объекту целиком при вычитывании из БД. Но это вам не мешает использовать просто ID при указании критериев выборки. Вам вовсе не нужно читать сущность из БД прежде чем передать ее в HQL-запрос, т.к. Hibernate-у не нужна сущность целиком, он всё равно "возьмет" лишь ID. Т.е., у вас есть ID, но в маппинге указана сущность - в HQL можно передать эмуляцию - создать new Proveder(), указать ему ID и передать в HQL объект Proveder без чтения его из БД.