gpt4 book ai didi

java - JPA谓词标准构建器多对多麻烦

转载 作者:行者123 更新时间:2023-12-02 02:22:08 25 4
gpt4 key购买 nike

我有 3 个表,例如 alarmalarmTagalarm_alarmTagalarmalarmTag 表具有多对多关系。 alarm_alarmTag 表映射 alarmalarmTag 表。

每个警报可以有多个警报标签。例如alarm1tag1tag2。因此,我想创建一个搜索过滤器,当我在该过滤器上选择 tag1 时,我想显示具有 tag1 的警报。

我已经通过 join 完成了此操作,但问题是当我过滤 tag1 时,它在标签列上仅显示 tag1,但该列上还有其他标签。

过滤器之前:

+------------------+
| alarm table |
+------------------+
| id | tag |
+------------------+
| 1 | tag1, tag2 |
| 2 | tag3, tag4 |
+------------------+

使用tag1过滤后:

+------------------+
| alarm table |
+------------------+
| id | tag |
+------------------+
| 1 | tag1 |(this column must also have `tag2`)
+------------------+

型号:

public class ActiveAlarm {

@Id
private Long id;

@ManyToMany(cascade = CascadeType.PERSIST)
private Set<AlarmTag> alarmTag;

}

Controller :

@GetMapping("/active")
public List<ActiveAlarmView> findAll(@RequestParam(required = false, defaultValue = "") List<Long> alarmTag) {

var data = repository.findAll(ActiveAlarmSpecification.filter(alarmTag));

return data.stream().map(record -> ActiveAlarmView.builder()
.id(record.getId())
.alarmTag(record.getAlarmTag()))
.build()).collect(Collectors.toList());
}

过滤器规范:

public class ActiveAlarmSpecification {

/**
* Filter Specification.
*/
public static Specification<ActiveAlarm> filter(List<Long> alarmTag) {
return (root, query, cb) -> {
query.distinct(true);

ArrayList<Predicate> predicates = new ArrayList<>();

if (!alarmTag.isEmpty()) {
//***problem is in this line***
predicates.add(root.join("alarmTag").get("id").in(alarmTag));
}

return cb.and(predicates.toArray(new Predicate[0]));
};
}
}

警报标签模型:

public class AlarmTag {

@Id
private Long id;

private String label;
}

这是我的请求链接:http://localhost:8080/api/test/v1/alarm/active?alarmTag=1

最佳答案

您必须单独获取这些内容或使用 group by 来聚合标签名称/ID(不幸的是,使用 DTO 进行投影)。

这背后的原因是这正​​是 SQL 将产生的结果。查询将像 +- 一样:

SELECT * FROM alarm a JOIN alarm_tag at ON ... JOIN tag t ON ... WHERE t.id IN (your,tags)

当您只有单个标签时,此查询结果将不包含任何其他具有与 IN 子句中不同 id 的标签

您将获得您想要的所有警报,但标签会从结果中过滤掉 - 这正是您在此处看到的内容

您可以尝试将 root.join 替换为 root.fetch 或尝试额外的 root.fetch,但我不确定是否可以两者都可以。

关于java - JPA谓词标准构建器多对多麻烦,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57272108/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com