代码示例:
@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 个动作。
问题是:
是否可以仅获取包含具有所需日期的操作的事件,并且每个事件仅包含一个包含具有请求日期的操作的列表?