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