Я пытаюсь выполнить динамический поиск в нескольких таблицах.
Когда я присоединяюсь ТОЛЬКО к одной таблице, я получаю ожидаемый результат.
Когда Объединяю все таблицы и получаю только половину результата или вообще ни одного. Даже если я не включу Predicates в criteriaBuilder.or(); простое объявление JOINS нарушит код.
Объект:
Код: Выделить всё
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
//Other fields...
@ToString.Exclude
@JsonIgnore
@OneToMany(mappedBy = "imageInfo", fetch = FetchType.LAZY)
private List genres;
@ToString.Exclude
@JsonIgnore
@OneToMany(mappedBy = "imageInfo", fetch = FetchType.LAZY)
private List keywords;
@ToString.Exclude
@JsonIgnore
@OneToMany(mappedBy = "imageInfo", fetch = FetchType.LAZY)
private List locations;
@ToString.Exclude
@JsonIgnore
@OneToMany(mappedBy = "imageInfo", fetch = FetchType.LAZY)
private List persons;
Код: Выделить всё
@Getter
@Setter
@Entity
@Table(name = "genre_image_info_mapping",schema = "public")
public class GenreImageInfoMEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
Long id;
@ManyToOne(cascade = CascadeType.DETACH)
@JoinColumn(name = "fk_genre_id")
GenreEntity genre;
@ManyToOne(cascade = CascadeType.DETACH)
@JoinColumn(name = "fk_image_info_id")
ImageInfoEntity imageInfo;
}
Код: Выделить всё
@Entity
@Getter
@Setter
@Table(name = "genre",schema = "public")
public class GenreEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
@Column(name = "name")
String name;
}
Specification
This way work correctly:
Код: Выделить всё
private Specification fullSearch(String search) {
return (root, query, criteriaBuilder) -> {
Join joinG = root.join(ImageInfoEntity_.GENRES);
String searchFinal = "%" + Utility.unaccent(search.toLowerCase()) + "%";
Predicate genrePredicate = criteriaBuilder.like(criteriaBuilder.function("unaccent", String.class, criteriaBuilder.lower(joinG.get(GenreImageInfoMEntity_.GENRE).get(GenreEntity_.NAME))),searchFinal);
return criteriaBuilder.or(genrePredicate);
};
}
Код: Выделить всё
private Specification fullSearch(String search) {
return (root, query, criteriaBuilder) -> {
Join joinG = root.join(ImageInfoEntity_.GENRES);
Join joinL = root.join(ImageInfoEntity_.LOCATIONS);
Join joinP = root.join(ImageInfoEntity_.PERSONS);
Join joinK = root.join(ImageInfoEntity_.KEYWORDS);
String searchFinal = "%" + Utility.unaccent(search.toLowerCase()) + "%";
Предикат жанрPredicate = критерииBuilder.like(criteriaBuilder.function("unaccent", String.class, критерииBuilder.lower(joinG.get (GenreImageInfoMEntity_.GENRE).get(GenreEntity_.NAME))),searchFinal);
Предикат personPredicate = критерииBuilder.like(criteriaBuilder.function("unaccent", String.class, критерииBuilder.lower(joinP.get(PersonImageInfoMEntity_) .PERSON).get(PersonEntity_.SEARCH_NAME))),searchFinal);
Predicate ключевое словоPredicate = критерииBuilder.like(criteriaBuilder.function("unaccent", String.class, критерииBuilder.lower(joinK.get(KeywordImageInfoMEntity_.KEYWORD) ).get(KeywordEntity_.KEYWORD))),searchFinal);
Предикат locationPredicate = критерииBuilder.like(criteriaBuilder.function("unaccent", String.class, критерииBuilder.lower(joinL.get(LocationImageInfoMEntity_.LOCATION). get(LocationEntity_.NAME))),searchFinal);
Предикат locationHUNPredicate = критерииBuilder.like(criteriaBuilder.function("unaccent", String.class, критерииBuilder.lower(joinL.get(LocationImageInfoMEntity_.LOCATION).get( LocationEntity_.HUN_NAME))),searchFinal);
Предикат locationENGPredicate = критерииBuilder.like(criteriaBuilder.function("unaccent", String.class, критерииBuilder.lower(joinL.get(LocationImageInfoMEntity_.LOCATION).get(LocationEntity_. ENG_NAME))),searchFinal);
Предикат фотографPredicate = критерииBuilder.like(criteriaBuilder.function("unaccent", String.class, критерииBuilder.lower(root.get(ImageInfoEntity_.PHOTOGRAPHER).get(PersonEntity_.ABC_NAME) )),searchFinal);
Предикат OwnerPredicate = критерииBuilder.like(criteriaBuilder.function("unaccent", String.class, критерииBuilder.lower(root.get(ImageInfoEntity_.OWNER))),searchFinal);
критерии возвратаBuilder.or(genrePredicate,personPredicate,keywordPredicate,locationPredicate,locationENGPredicate,locationHUNPredicate,ownerPredicate,photographerPredicate);
};
}
Другие характеристики:
Код: Выделить всё
public Specification build(FilterImageInfoDto filterImageInfoDto) {
List specifications = new ArrayList();
if(filterImageInfoDto.getSearch()!= null){
specifications.add(fullSearch(filterImageInfoDto.getSearch()));
}
if(filterImageInfoDto.getSizeX()!= null){
specifications.add(isSizeXEq(filterImageInfoDto.getSizeX()));
}
if(filterImageInfoDto.getSizeY()!= null){
specifications.add(isSizeYEq(filterImageInfoDto.getSizeY()));
}
if(filterImageInfoDto.getCategory()!= null){
specifications.add(isCategoryEq(filterImageInfoDto.getCategory().getId()));
}
if(filterImageInfoDto.getUploadDate()!= null){
specifications.add(isUploadDateEq(filterImageInfoDto.getUploadDate()));
}
if(filterImageInfoDto.getCaptureYear()!= null){
specifications.add(isCaptureYearEq(filterImageInfoDto.getCaptureYear()));
}
if(filterImageInfoDto.getTechnics()!= null && !filterImageInfoDto.getTechnics().isEmpty() ){
specifications.add(isTechnicsEq(filterImageInfoDto.getTechnics()));
}
if(filterImageInfoDto.getMaterials()!= null && !filterImageInfoDto.getMaterials().isEmpty()){
specifications.add(isMaterialsEq(filterImageInfoDto.getMaterials()));
}
if(filterImageInfoDto.getGenres()!= null&& !filterImageInfoDto.getGenres().isEmpty()) {
specifications.add(isGenreEq(filterImageInfoDto.getGenres()));
}
if(filterImageInfoDto.getPersons()!= null && !filterImageInfoDto.getPersons().isEmpty()){
specifications.add(isPersonEq(filterImageInfoDto.getPersons()));
}
if(filterImageInfoDto.getPhotographers()!= null && !filterImageInfoDto.getPhotographers().isEmpty()){
specifications.add(isPhotographerEq(filterImageInfoDto.getPhotographers()));
}
if(filterImageInfoDto.getLocations()!= null && !filterImageInfoDto.getLocations().isEmpty()){
specifications.add(isLocationEq(filterImageInfoDto.getLocations()));
}
if(filterImageInfoDto.getKeywords()!= null && !filterImageInfoDto.getKeywords().isEmpty()){
specifications.add(isKeywordLike(filterImageInfoDto.getKeywords()));
}
if(filterImageInfoDto.getHolders()!= null && !filterImageInfoDto.getHolders().isEmpty()){
спецификации.add(isHolderEq(filterImageInfoDto.getHolders()));
}
return спецификации.stream()< br /> .reduce(Specification::and)
.orElse(null);
}
Я пробовал разбить его на разные функции, но ничего не помогает.
Источник: https://stackoverflow.com/questions/781 ... ted-output
Мобильная версия