【问题标题】:cross join in spring-data-jpaspring-data-jpa 中的交叉连接
【发布时间】: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)

这个交叉连接破坏了一切。

我该怎么办?有没有其他方法可以获取?

【问题讨论】:

  • 您不需要执行JOIN AT ALL - 只需使用root.get(Event_.eventGroups) 检索事件组并使用cb.in( ... ) 顺便说一句: 你有Repository,为什么还要使用CrudRepository?
  • 谢谢!但是这样我应该传递 eventGroups 而不是 eventGroupsIds。但这不是问题。你的意思是@Repository 注释吗?我只是按照春天的指示)
  • 如果您将PRIMARYKEYs 保留在代码中的某个集合中,您将做错事——这是糟糕的应用程序设计。您应该保留分离的实体 - 如果您的实体数量很少,这也非常有效
  • 我从前端获得 EventGroupIds。所以我觉得还可以。
  • 你实际上是在互联网上传输主键??那是....我听说过的最糟糕的应用程序设计,它一上线就会被黑。

标签: java spring-data spring-data-jpa


【解决方案1】:

解决了

    private Specification<Event> buildSpecification(final EventFilter filter) {
        final Specification<Event> specification = new Specification<Event>() {
            @Override
            public Predicate toPredicate(Root<Event> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
                cq.distinct(true);
                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 predicate;
            }
        };
        return specification;
    }

【讨论】:

    猜你喜欢
    • 2013-06-08
    • 2014-09-15
    • 2018-11-17
    • 2020-08-30
    • 1970-01-01
    • 2021-11-19
    • 2017-05-12
    • 1970-01-01
    • 2018-11-30
    相关资源
    最近更新 更多