Я использую спящий JPA, Spring Data JPA и Query DSL.Я пытаюсь создать запрос, который отфильтрует элементы во вложенной коллекции, но я не получаю желаемого результата.
Вот компоненты JPA:
@Entity
public class Item implements Serializable
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "Item_ID")
private long id;
@OneToMany(mappedBy = "item")
private Set<Operation> operations;
}
@Entity
public class Operation implements Serializable
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "Operation_ID")
private Long id;
@ManyToOne(optional = false)
@JoinColumn(name = "Item_ID")
private Item item;
@Column(name = "Name")
@Size(max = 255)
private String name;
}
Для краткости я опустил аннотации графа сущностей.
Мой репозиторий:
public interface ItemRepository extends JpaRepository<Item, Long>, QuerydslPredicateExecutor<Item>
{
}
И, наконец, мой предикат:
final QItem item = QItem.item;
itemRepository.findAll(item.operations.any().name.eq(operationName), PageRequest.of(1, 10));
Это создает SQL, который выглядит следующим образом:
select ...
from [Item] item0_
left outer join [Operation] operations2_ on item0_.[Item_ID]=operations2_.[Item_ID]
where exists (
select 1 from [Operation] operations1_
where item0_.[Item_ID]=operations1_.[Item_ID]
and operations1_.[Name]=?
)
Я вижу, что он возвращает все элементы, которые включают по крайней мере одну операцию, которая имеетимя, которое соответствует operationName
.Тем не менее, Set внутри каждого Item
включает в себя все операции, которые имеет элемент, я хотел бы, чтобы те также были отфильтрованы по operationName
, в идеале с sql, который похож на это:
select ...
from [Item] item0_
left outer join [Operation] operations2_ on item0_.[Item_ID]=operations2_.[Item_ID]
where operations1_.[Name]=?
Iпытался это:
final QOperation operation = QOperation.operation;
itemRepository.findAll(operation .name.eq(operationName), PageRequest.of(1, 10));
Однако это вызывает исключение org.hibernate.hql.internal.ast.QuerySyntaxException: неверный путь: 'operation.name' [выбрать элемент из com.stackoverflow.example.Itemitem
Я предполагаю, что это потому, что item является корнем пути для запроса, и что выражение пути должно начинаться с item и идти вплоть до операций, но я не могу понять, как это сделать.
Заранее спасибо