Я получил три хороших ответа, которые были одинаково полезны, и к настоящему моменту ни один из них не проскользнул на вершину путем публичного голосования, поэтому я объединяю их здесь для единого всеобъемлющего ответа:
а) Изменить запрос
Вы можете загрузить весь график сразу, изменив запрос, тем самым предоставив провайдеру JPA возможность понять, что у него уже есть все в памяти и нет необходимости возвращаться в БД:
List<Node> nodes = em.createQuery(
"SELECT DISTINCT n FROM Node n LEFT JOIN FETCH n._rgOutbound")
.getResultList();
(через axtavt )
b) Использовать поля только для чтения для ФК
Загрузка FK в их собственные поля, как описано в вопросе, также будет работать, если, как требует поставщик JPA, поля объявлены только для чтения, что делается следующим образом:
@Column(name = "ixNodeTo", insertable = false, updatable = false)
(через bravocharlie )
в) Использовать доступ к собственности
Если вы используете доступ к свойству вместо доступ к полю , провайдер JPA также получает шанс понять, что у него уже есть FK и ему не нужно извлекать ссылочный объект , Короче говоря, доступ к свойству означает, что вы помещаете аннотации JPA на получатель, тем самым «обещая» провайдеру JPA, что ваш получатель не пойдет и получит доступ к остальной части объекта. Подробнее в этот вопрос . Это будет работать для Hibernate, и для Eclipselink, это будет работать (предполагается в оригинальном ответе, подтвержденном мной экспериментально) с включенным ткачеством. (через Pascal Thivent )
Кроме того, как Паскаль указывает в своем ответе , @ManyToOne
, в отличие от моего первоначального поста, не ленивая загрузка, а готовая загрузка по умолчанию, и изменения, которые также потребуют ткачества .