cross join in spring-data-jpa

2019-08-31 05:43发布

There are two entity

@Entity
public class Event{
...
    @ManyToMany(fetch = FetchType.LAZY)
    private Set<EventGroup> eventGroups;
}

@Entity
public class EventGroup {
...
    @ManyToMany(fetch = FetchType.LAZY)
    private Set<Event> events;
}

I need to get Events which has EventGroups with given ids. Using spring data CrudRepository.

@Repository
public interface EventRepository extends CrudRepository<Event, Long>, JpaSpecificationExecutor {
}

Im calling

eventRepository.findAll(buildSpecification(filter);

This is how i build specification:

    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;
    }

But result query is

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)

This cross join corrupt everything.

What should i do? May be there is another way to get it?

1条回答
放荡不羁爱自由
2楼-- · 2019-08-31 06:17

Solved

    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;
    }
查看更多
登录 后发表回答