gpt4 book ai didi

java - JPA Criteria API 过滤器子实体

转载 作者:行者123 更新时间:2023-11-30 06:19:40 25 4
gpt4 key购买 nike

代码示例:

    @Entity
public class Event {

@Id
@GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy="event")
private List<Actions> actions;

}


@Entity
public class Action {

@Id
@GeneratedValue
private Long id;
private String name;
private Date date;
@ManyToOne
@JoinColumn(name = "event_id")
private Event event;

}

public class EventSpecification {

public static Specification<Event> findByCriteria(EventSearchCriteria criteria) {

return (root, criteriaQuery, criteriaBuilder) -> {
List<Predicate> predicates = new ArrayList<>();

criteria.getDate().ifPresent(date -> {
Join<Event, Action> join = root.join(Event_.actions);
predicates.add(criteriaBuilder.equal(join.get(Action_.date), criteria.getDate().get()));
});

return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
};
}
}
...

eventRepository.findAll(EventSpecification.findByCriteria(searchCriteria))

在我的数据库中,我有下一个:

Event Table
id, name
1, 'event_1'
2, 'event_2'

Action Table
id, name, date, event_id
1, 'action_event_1_1', '01-01-2018', 1
2, 'action_event_1_2', '01-01-2018', 1
3, 'action_event_1_3', '01-02-2018', 1

4, 'action_event_2_1', '01-03-2018', 2

使用我的规范代码与 data='01-01-2018',结果我得到相同事件对象的列表,列表的大小是连接对象的计数,满足子句 Action.date = criteria.date :

[{id=1, name=event_1, actions=[all 3 actions]},
{id=1, name=event_1, actions=[all 3 actions]}]

我需要得到下一个结果:

{id=1, name=event_1, actions=[only two actions with date '01-01-2018']}

我尝试添加

criteriaQuery.groupBy(root.get(Event.id));

它修复了结果列表的大小 -

{id=1, name=event_1, actions=[all 3 actions]}

但我仍然得到事件 1 的所有 3 个操作。

问题是:

是否可以仅获取包含具有所需日期的操作的事件,以便每个事件仅包含具有请求日期的操作的列表?

最佳答案

我找到了下一个解决方案:

public static Specification<Event> findByCriteria(EventSearchCriteriacriteria) {

return (root, criteriaQuery, criteriaBuilder) -> {
List<Predicate> predicates = new ArrayList<>();

criteria.getDate().ifPresent(date -> {
criteriaQuery.distinct(true);
Join<Event, Action> join = (Join<Event, Action>)root.fetch(Event_.actions);
predicates.add(criteriaBuilder.equal(join.get(Action_.date), criteria.getDate().get()));
});

return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
};
}

可能Join<Event, Action> join = (Join<Event, Action>)root.fetch(Event_.actions);不是最好的解决方案,因为我的 IDE 会警告我有关转换的问题,但这是我找到的唯一可行的解​​决方案。

顺便说一句,如果不使用 Criteria API,它也能完美运行:

@EntityGraph(value = "Event.actions", type = EntityGraph.EntityGraphType.LOAD)
@Query("select distinct e from Event e join e.actions a where a.date = (:date)")
List<Event> findAllWithActionsByDate(@Param("date") Date date);

但是避免使用 Criteria API 不适合我的情况。

关于java - JPA Criteria API 过滤器子实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48431944/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com