orderItems могут быть двух типов: StandardOrderItem иSpecificOrderItem
Я не хочу, чтобы они загружались, чтобы избежать исключения LazyInitialization.
Так и должно быть вот так
orderService.findOrderByIdAndEntityGraph(productionOrderId,
Map.of("orderItems",
new JPAUtils.JoinNode(
StandardOrderItem.class,
Map.of("components", new JPAUtils.JoinNode(EMPTY_MAP))
)));
ПосколькуSpecificOrderItem do ton содержит «компоненты»,
которые я хочу получить.
Так что, к сожалению, метод Join ленив, выборка нетерпится, но критерийBuilder.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;
}
}
Usage:
orderService.findOrderByIdAndEntityGraph(productionOrderId,
Map.of("orderItems",
new JPAUtils.JoinNode(
StandardOrderItem.class,
Map.of("components", new JPAUtils.JoinNode(EMPTY_MAP))
)));
Explanation:
orderItems can be 2 types, StandardOrderItem and SpecificOrderItem
I wan't to get them fetching to aviod LazyInitialization exception.
It should be like this
orderService.findOrderByIdAndEntityGraph(productionOrderId,
Map.of("orderItems",
new JPAUtils.JoinNode(
StandardOrderItem.class,
Map.of("components", new JPAUtils.JoinNode(EMPTY_MAP))
)));
ПосколькуSpecificOrderItem do ton содержит «компоненты»,
которые я хочу получить.
Так что, к сожалению, метод Join ленив, выборка нетерпится, но критерийBuilder.treat() работает только с объединениями, что приводит к ошибкам при объединении "компонентов"
orderItems могут быть двух типов: StandardOrderItem иSpecificOrderItem Я не хочу, чтобы они загружались, чтобы избежать исключения LazyInitialization. Так и должно быть вот так [code]orderService.findOrderByIdAndEntityGraph(productionOrderId, Map.of("orderItems", new JPAUtils.JoinNode( StandardOrderItem.class, Map.of("components", new JPAUtils.JoinNode(EMPTY_MAP)) ))); [/code] ПосколькуSpecificOrderItem do ton содержит «компоненты», которые я хочу получить. Так что, к сожалению, метод Join ленив, выборка нетерпится, но критерийBuilder.treat() работает только с объединениями, что приводит к ошибкам при объединении "компонентов" [code]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); }
// 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;
orderService.findOrderByIdAndEntityGraph(productionOrderId, Map.of("orderItems", new JPAUtils.JoinNode( StandardOrderItem.class, Map.of("components", new JPAUtils.JoinNode(EMPTY_MAP)) )));
Explanation: orderItems can be 2 types, StandardOrderItem and SpecificOrderItem
I wan't to get them fetching to aviod LazyInitialization exception.
It should be like this
orderService.findOrderByIdAndEntityGraph(productionOrderId, Map.of("orderItems", new JPAUtils.JoinNode( StandardOrderItem.class, Map.of("components", new JPAUtils.JoinNode(EMPTY_MAP)) ))); [/code] ПосколькуSpecificOrderItem do ton содержит «компоненты», которые я хочу получить. Так что, к сожалению, метод Join ленив, выборка нетерпится, но критерийBuilder.treat() работает только с объединениями, что приводит к ошибкам при объединении "компонентов"
orderItems могут быть двух типов: StandardOrderItem иSpecificOrderItem
Я не хочу, чтобы они загружались, чтобы избежать исключения LazyInitialization.
Так и должно быть вот так
orderService.findOrderByIdAndEntityGraph(productionOrderId,
Map.of(...
Мне нужно реплицировать этот запрос в код JPA CriteriaBuilder :
....
where
article.client_id = 1
and article.price > 0
and (
article.code like '%this is statement%'
or article.oem_code like '%this is statement%'
or (
article.description like...
Мне нужно реплицировать этот запрос в код JPA CriteriaBuilder :
....
where
article.client_id = 1
and article.price > 0
and (
article.code like '%this is statement%'
or article.oem_code like '%this is statement%'
or (
article.description like...
orderItems может быть 2 типа, StandardOrderItem и completorOderItem .
Я хочу получить их, чтобы избежать Lazyinitialization .
Это должно быть похоже на это:
orderService.findOrderByIdAndEntityGraph(productionOrderId,
Map.of( orderItems ,
new...
Я использую этот скрипт для выборки из списка файлов в каталоге и использую вызов с начальным значением random.sample(population, k).
Я ожидаю, что выборка 100 элементов с k=100 при использовании начального числа гарантирует, что при последующей...