В JPA режим извлечения указывается для каждого атрибута постоянства, либо с помощью аннотации, либо в файле сопоставления xml.
Таким образом, независимый от JPA поставщика способ достижения вашей цели состоит в том, чтобы иметь отдельный файл сопоставления для каждого уровня DAO. К сожалению, для этого потребуется отдельный PersistenceUnit для каждого файла сопоставления, но вы можете, по крайней мере, использовать одни и те же классы сущностей и один и тот же запрос JPQL.
Далее следуют скелеты кода.
persistence.xml:
<persistence>
<persistence-unit name="dao-eager">
<mapping-file>orm-eager.xml</mapping-file>
</persistence-unit>
<persistence-unit name="dao-lazy">
<mapping-file>orm-lazy.xml</mapping-file>
</persistence-unit>
</persistence>
orm-eager.xml:
<entity-mappings>
<entity class="ErrorCode">
<attributes>
<basic name="name" fetch="EAGER"/>
</attributes>
</entity>
</entity-mappings>
orm-lazy.xml:
<entity-mappings>
<entity class="ErrorCode">
<attributes>
<basic name="name" fetch="LAZY"/>
</attributes>
</entity>
</entity-mappings>
Тогда это просто вопрос создания EntityManagerFactory для соответствующего модуля персистентности в ваших слоях DAO.
На самом деле вам не нужны два файла сопоставления, вы можете указать LAZY или EAGER в качестве аннотации в Entity, а затем указать противоположное в файле сопоставления xml (вам все равно понадобятся два модуля постоянства).
Может быть немного больше кода, чем приведенное выше решение Hibernate, но ваше приложение должно быть переносимым на других поставщиков JPA.
Кроме того, OpenJPA предоставляет функциональность, аналогичную описанной выше для решения Hibernate, с использованием FetchGroups (концепция, заимствованная из JDO).
Последнее замечание, FetchType.LAZY, является подсказкой в JPA, провайдер может загружать строки в случае необходимости.
Обновлено по запросу.
Рассмотрим сущность, подобную этой:
@Entity
public class ErrorCode {
// . . .
@OneToMany(fetch=FetchType.EAGER) // default fetch is LAZY for Collections
private Collection myCollection;
// . . .
}
В этом случае вам все равно понадобятся два постоянных модуля, но вам понадобится только orm-lazy.xml. Я изменил имя поля, чтобы отразить более реалистичный сценарий (по умолчанию только коллекции и BLOB-объекты используют FetchType.LAZY). Таким образом, полученный файл orm-lazy.xml может выглядеть так:
<entity-mappings>
<entity class="ErrorCode">
<attributes>
<one-to-many name="myCollection" fetch="LAZY"/>
</attributes>
</entity>
</entity-mappings>
И файл persistence.xml будет выглядеть так:
<persistence>
<persistence-unit name="dao-eager">
<!--
. . .
-->
</persistence-unit>
<persistence-unit name="dao-lazy">
<!--
. . .
-->
<mapping-file>orm-lazy.xml</mapping-file>
</persistence-unit>
</persistence>