orderItems может быть 2 типа, StandardOrderItem и completorOderItem .
Я хочу получить их, чтобы избежать Lazyinitialization .
Это должно быть похоже на это: < /p>
orderService.findOrderByIdAndEntityGraph(productionOrderId,
Map.of("orderItems",
new JPAUtils.JoinNode(
StandardOrderItem.class,
Map.of("components", new JPAUtils.JoinNode(EMPTY_MAP))
)));
Потому что CompletorOderItem do ton содержит «компоненты», которые я хочу получить. , fetch - это стремление, но CriteriaBuilder.treat () работает только с соединениями, что вызывает ошибки при соединении «компонентов»
public static T getBySpecificationWithGraph(
EntityManager entityManager,
Specification specification,
Map joins,
Class clazz
) {
CriteriaQuery criteriaQuery = prepareCriteriaQuery(entityManager, specification, joins, clazz);
return entityManager.createQuery(criteriaQuery).getSingleResult();
}
public static Specification fieldEquals(String fieldName, V value) {
return (root, criteriaQuery, criteriaBuilder) ->
criteriaBuilder.equal(root.get(fieldName), value);
}
private static CriteriaQuery prepareCriteriaQuery(
EntityManager entityManager,
Specification specification,
Map joins,
Class clazz
) {
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(clazz);
Root ownerRoot = criteriaQuery.from(clazz);
// Apply fetch logic with TREAT
prepareFetch(joins, ownerRoot, null, criteriaBuilder);
criteriaQuery.select(ownerRoot)
.where(specification.toPredicate(ownerRoot, criteriaQuery, criteriaBuilder));
return criteriaQuery;
}
private static void prepareFetch(
Map joins,
From fetch,
CriteriaBuilder criteriaBuilder
) {
joins.forEach((key, value) -> {
Fetch childFetch = null;
Join childJoin = null; // Declare childJoin for TREAT usage
// Apply TREAT logic only on Fetches or Joins
if (fetch == null) {
if (value.getType() != null) {
// First, attempt to treat it as a collection join
try {
// If the relationship is a collection (e.g., @OneToMany)
SetJoin setJoin = root.joinSet(key, JoinType.LEFT);
childJoin = criteriaBuilder.treat(setJoin, value.getType());
root.fetch(key, JoinType.LEFT); // Ensure the association is fetched eagerly
} catch (IllegalArgumentException | ClassCastException e) {
// If it's not a collection, treat it as a singular join (e.g., @ManyToOne, @OneToOne)
try {
Join join = root.join(key, JoinType.LEFT);
childJoin = criteriaBuilder.treat(join, value.getType());
root.fetch(key, JoinType.LEFT); // Ensure the association is fetched eagerly
} catch (IllegalArgumentException | ClassCastException ex) {
throw new RuntimeException("Unable to apply TREAT to the join: " + key, ex);
}
}
} else {
// If no type is provided, just fetch the relationship
childFetch = root.fetch(key, JoinType.LEFT);
}
} else {
childFetch = fetch.fetch(key, JoinType.LEFT);
}
// Handle recursive joins and fetches for deeper relationships
Objects.requireNonNull(value);
Map next = value.getJoins();
if (!next.isEmpty()) {
// Use childJoin for TREAT case or childFetch for normal cases
if (childJoin != null) {
prepareFetch(next, childJoin, null, criteriaBuilder); // Continue joining with TREAT
} else {
prepareFetch(next, root, childFetch, criteriaBuilder); // Continue fetching
}
}
});
}
@Getter
public static class JoinNode {
private final Class type;
private final Map joins;
public JoinNode(Class type, Map joins) {
this.type = type;
this.joins = joins;
}
public JoinNode(Map joins) {
this.joins = joins;
this.type = null;
}
}
< /code>
Использование: < /p>
orderService.findOrderByIdAndEntityGraph(productionOrderId,
Map.of("orderItems",
new JPAUtils.JoinNode(
StandardOrderItem.class,
Map.of("components", new JPAUtils.JoinNode(EMPTY_MAP))
)));
Подробнее здесь: https://stackoverflow.com/questions/790 ... cific-type
Критерии настойчивости извлекают с удовольствием конкретного типа ⇐ JAVA
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение