【发布时间】:2015-02-19 22:38:02
【问题描述】:
有两个实体
@Entity
public class Event{
...
@ManyToMany(fetch = FetchType.LAZY)
private Set<EventGroup> eventGroups;
}
@Entity
public class EventGroup {
...
@ManyToMany(fetch = FetchType.LAZY)
private Set<Event> events;
}
我需要获取具有给定 ID 的 EventGroups 的事件。 使用 spring 数据 CrudRepository。
@Repository
public interface EventRepository extends CrudRepository<Event, Long>, JpaSpecificationExecutor {
}
我在打电话
eventRepository.findAll(buildSpecification(filter);
这就是我构建规范的方式:
private Specification<Event> buildSpecification(final EventFilter filter) {
final Specification<Event> specification = new Specification<Event>() {
@Override
public Predicate toPredicate(Root<Event> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
root = criteriaQuery.distinct(true).from(Event.class);
Predicate predicate = cb.conjunction();
if (filter.getEventGroupIds() != null) {
Join<Event, EventGroup> join = root.join(Event_.eventGroups);
predicate.getExpressions().add( join.get(EventGroup_.id).in(filter.getEventGroupIds()) );
}
return criteriaQuery.where(predicate).getRestriction();
}
};
return specification;
}
但是结果查询是
SELECT DISTINCT
event0_.id AS id1_1_,
event0_.createdAt AS createdA2_1_,
event0_.date AS date3_1_,
event0_.image_id AS image_id6_1_,
event0_.moderated AS moderate4_1_,
event0_.name AS name5_1_,
event0_.owner_id AS owner_id7_1_
FROM Event event0_
CROSS JOIN Event event1_
INNER JOIN Event_EventGroup eventgroup2_ ON event1_.id = eventgroup2_.Event_id
INNER JOIN EventGroup eventgroup3_ ON eventgroup2_.eventGroups_id = eventgroup3_.id
WHERE eventgroup3_.id IN (15)
这个交叉连接破坏了一切。
我该怎么办?有没有其他方法可以获取?
【问题讨论】:
-
您不需要执行
JOINAT ALL - 只需使用root.get(Event_.eventGroups)检索事件组并使用cb.in( ... )顺便说一句: 你有Repository,为什么还要使用CrudRepository? -
谢谢!但是这样我应该传递 eventGroups 而不是 eventGroupsIds。但这不是问题。你的意思是@Repository 注释吗?我只是按照春天的指示)
-
如果您将
PRIMARYKEYs 保留在代码中的某个集合中,您将做错事——这是糟糕的应用程序设计。您应该保留分离的实体 - 如果您的实体数量很少,这也非常有效 -
我从前端获得 EventGroupIds。所以我觉得还可以。
-
你实际上是在互联网上传输主键??那是....我听说过的最糟糕的应用程序设计,它一上线就会被黑。
标签: java spring-data spring-data-jpa