Моя рекомендация: не используйте нетерпеливое извлечение. Это приводит к несогласованности и иногда странным запросам. Кроме того, трудно оптимизировать производительность, когда вы используете нетерпеливую выборку. В упомянутом случае я бы создал разные методы для вызова базы данных с некоторыми выборочными соединениями или графами сущностей.
Я не использую HBM (или другое отображение на основе XML). Я использую аннотации, почему не могу предоставить вам ответ с отображением XML ( HBM, похоже, в любом случае устарел ).
Мой предпочтительный способ - использовать API критериев JPA вместо JPQL. Некоторые люди говорят, что JPQL более понятен, но я предпочитаю API-интерфейс Criteria-safe, который менее подвержен ошибкам. Я предпочитаю графы сущностей, потому что их проще использовать динамически, чем выборочные объединения. Тем не менее, другие опции также работают.
Сначала я бы настроил классы сущностей, соответствующие Статья Влада Михальчи . (Я делаю вывод о однонаправленных отношениях.)
@Entity
@Table(name = "DATA_ELEMENT")
public class DataElement {
@Id
@GeneratedValue
@Column(name = "ID")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "FILTER_ID")
private Filter filter;
//Constructors, getters and setters...
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof DataElement )) return false;
return id != null && id.equals(((DataElement) o).getId());
}
@Override
public int hashCode() {
return 56;
}
}
Аналогично для FilterAudit
(также FetchType.LAZY
) ...
И затем Filter
(не так интересно, потому что это однонаправленный).
@Entity
@Table(name = "FILTERS")
public class Filter {
@Id
@GeneratedValue
@Column(name = "M_ID")
private Long id;
// Other attributes omitted...
//Constructors, getters and setters...
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Filter )) return false;
return id != null && id.equals(((Filter) o).getId());
}
@Override
public int hashCode() {
return 14;
}
}
Теперь соответствующая часть для инициализации отложенных нагрузок (или нет) реализуется в этом случае с помощью API-критериев JPA и графиков сущностей.
public DataElement findByIdWithFilter(long id) {
EntityGraph<DatElement> graph = entityManager.createEntityGraph(DataElement.class);
graph.addAttributeNodes("filter");
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<DatElement> cq = cb.createQuery(DatElement.class);
Root<DatElement> root = cq.from(DatElement.class);
cq.where(cb.equal(root.get("id"), id));
TypedQuery<DatElement> typedQuery = entityManager.createQuery(cq);
typedQuery.setHint("javax.persistence.fetchgraph", graph);
DatElement response = null;
try {
response = typedQuery.getSingleResult();
}
catch(NoResultException nre) {}
return response;
}
Для извлеченияобъект того же класса без его связи, просто опустите граф сущности.
public DataElement findByIdWithoutFilter(long id) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<DatElement> cq = cb.createQuery(DatElement.class);
Root<DatElement> root = cq.from(DatElement.class);
cq.where(cb.equal(root.get("id"), id));
return entityManager.createQuery(cq).getSingleResult();
}