Создание предиката QueryDSL для отношения один ко многим - PullRequest
0 голосов
/ 12 декабря 2018

Я использую спящий 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 и идти вплоть до операций, но я не могу понять, как это сделать.

Заранее спасибо

...