Java spring数据jpa中的交叉连接

Java spring数据jpa中的交叉连接,java,spring-data,spring-data-jpa,Java,Spring Data,Spring Data Jpa,有两个实体 @Entity public class Event{ ... @ManyToMany(fetch = FetchType.LAZY) private Set<EventGroup> eventGroups; } @Entity public class EventGroup { ... @ManyToMany(fetch = FetchType.LAZY) private Set<Event> events; } 这就是我

有两个实体

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

@Entity
public class EventGroup {
...
    @ManyToMany(fetch = FetchType.LAZY)
    private Set<Event> events;
}
这就是我构建规范的方式:

    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;
    }
这种交叉连接破坏了一切

我该怎么办?可能还有别的办法吗?

解决了

    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;
    }
专用规范构建规范(最终事件过滤器){
最终规范=新规范(){
@凌驾
公共谓词toPredicate(根根、CriteriaQuery cq、CriteriaBuilder cb){
cq.distinct(真);
谓词=cb.conjunction();
if(filter.getEventGroupId()!=null){
Join-Join=root.Join(事件组);
predicate.getExpressions().add(join.get(EventGroup.id).in(filter.getEventGroupIds());
}
返回谓词;
}
};
退货规格;
}

您根本不需要执行
加入
操作-只需使用
root.get(Event.eventGroups)
检索事件组,然后使用
cb.in(…)
顺便问一句:当您拥有
存储库时,为什么要使用
crudepository
?谢谢!但通过这种方式,我应该传递eventGroups,而不是eventgroupsid。但这不是问题。你是说@Repository注释吗?我只是按照spring的说明)如果在代码中的某个集合中保留
PRIMARYKEY
s,那么您就犯了可怕的错误——这是糟糕的应用程序设计。相反,您应该保留分离的实体-如果您的实体数量很小,那么从前端获取EventGroupID也是非常有效的。所以我认为这没关系。你实际上是在互联网上传输主键??那是。。。。这是我所听过的最糟糕的应用程序设计,它一上线就会遭到黑客攻击。
    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)
    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;
    }