【发布时间】:2021-11-15 03:46:57
【问题描述】:
我只想找到 by lang = "en" 和类似 "pom" 的值(pomme 是苹果的法语翻译)。
获取的值将是:
FoodEntity : {
names : [
pomme, apple
]
}
从技术上讲,它不应该被检索,因为它是 lang = "fr" 。 它没有考虑 lang 谓词。有人有什么想法吗? 它还检索所有名称。我只需要一个!
在@Query 中一切正常,但我需要 Jpa 规范
@Query(value = "select f from FoodEntity f join fetch f.names fn
where fn.value = ?1 and fn.lang = ?2")
@Entity
@Data
@Table(name = "food")
public class FoodEntity {
@Id
@SequenceGenerator(name = "food_id_seq", sequenceName = "food_id_seq", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "food_id_seq")
@Column(name = "id")
private Integer id;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "food_name_locale", joinColumns = {@JoinColumn(name = "food_id")}, inverseJoinColumns = {@JoinColumn(name = "locale_id")})
@JsonManagedReference
private Set<LocaleEntity> names = new HashSet<>();
}
public class LocaleEntity {
@Id
@SequenceGenerator(name = "locale_id_seq", sequenceName = "locale_id_seq", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "locale_id_seq")
@Column(name = "id")
private Integer id;
@Column(name = "value", columnDefinition = "TEXT")
private String value;
@Column(name = "lang")
private String lang;
@ManyToMany(mappedBy = "names")
@JsonBackReference
private Set<FoodEntity> foods;
}
JPA 规范内部:
public class FoodSpecification implements Specification<FoodEntity> {
private FoodCriteria searchCriteria;
public FoodSpecification(FoodCriteria searchCriteria) {
this.searchCriteria = searchCriteria;
}
@Override
public Specification<FoodEntity> and(Specification<FoodEntity> other) {
return Specification.super.and(other);
}
@Override
public Specification<FoodEntity> or(Specification<FoodEntity> other) {
return Specification.super.or(other);
}
@Override
public Predicate toPredicate(Root<FoodEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
List<Predicate> predicates = new ArrayList<Predicate>();
if(searchCriteria.getName() != null && !searchCriteria.getName().isEmpty()){
predicates.add(criteriaBuilder.and(criteriaBuilder.like(joinFoodName(root).get("value"), searchCriteria.getName() +"%"), criteriaBuilder.equal(joinFoodName(root).get("lang"), searchCriteria.getLang())));
}
return criteriaQuery.distinct(true).where(predicates.toArray(new Predicate[] {})).getRestriction();
}
private SetJoin<FoodEntity, LocaleEntity> joinFoodName(Root<FoodEntity> root){
return root.joinSet("names", JoinType.INNER);
}
}
【问题讨论】:
标签: spring-boot jpa spring-data-jpa criteria-api openjpa