Как я могу изменить эту Спецификацию JPA Spring Data или обновить эти сущности JPA, чтобы получить желаемые результаты? - PullRequest
0 голосов
/ 17 февраля 2020

Я создаю веб-приложение. Я недавно добавил фильтр страны на стороне интерфейса. Теперь я хочу использовать параметр запроса для вызова соответствующего CrudRepository в бэкэнде. В вызов я хочу включить спецификацию, которая включает в себя текст, извлеченный из параметра запроса.

Пример:

Пользователь устанавливает для фильтра страны значение «ether».

Ожидание: я хочу, чтобы в ответ было включено объявление, в котором есть место с адресом, на котором указана страна = "Нидерланды".

Ситуация: я вижу, что в журнал записывается следующий запрос Hibernate:

2020-02-17 20: 01: 10.720 DEBUG 4088 --- [nio-8080-exe c -5] org.hibernate. SQL: выберите файл классифицированного_0 в качестве id1_0_, классифицированного__. описание как descript2_0_, классифицировано как 0_3__ценка, классифицировано как цена____, классифицировано как итоговое значение_0_, классифицировано как идентификатора_0_, классифицировано как класс_ классификатора_0_ из классифицированного классифицированного места перекрестного соединения0_1, где классифицировано0_.id = place1_.id и (например, place1_.country?)

... и не получить результатов.

Мне кажется, проблема в том, что мы ищем записи, где классифицированные.id == место. id . Я на самом деле хочу искать записи, где классифицированный.ид == место. секретный_ид . Я также не уверен насчет перекрестного соединения ...

Скриншоты (некоторые столбцы для краткости опущены во втором):

enter image description here enter image description here enter image description here enter image description here

Сущности:

@Entity
public class Classified {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    private String summary;
    private String description;
    private double price;

    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "classified_id")
    private List<ImageMetadata> imageMetadata = new ArrayList<>();

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "classified_id")
    private ThumbnailMetadata thumbnailMetadata;

    public Place getPlace() {
        return place;
    }

    @OneToOne
    @JoinColumn(name = "id")
    private Place place;

    public Classified() { }

    public Classified(String summary, String description, double price, String currency) {
        this.summary = summary;
        this.description = description;
        this.price = price;
    }

    public ThumbnailMetadata getThumbnailMetadata() {
        return thumbnailMetadata;
    }

    public void setThumbnailMetadata(ThumbnailMetadata thumbnailMetadata) {
        this.thumbnailMetadata = thumbnailMetadata;
    }

    public List<ImageMetadata> getImageMetadata() {
        return imageMetadata;
    }

    public void setImageMetadata(List<ImageMetadata> imageMetadata) {
        this.imageMetadata = imageMetadata;
    }

    public void setId(long id) {
        this.id = id;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public long getId() {
        return id;
    }

    public String getSummary() {
        return summary;
    }

    public void setSummary(String summary) {
        this.summary = summary;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public double getPrice() {
        return price;
    }
}
@Entity
public class Place {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @Embedded
    private Address address;

    @OneToOne
    @JoinColumn(name = "classified_id")
    private Classified classified;

    private double latitude;
    private double longitude;
    private String label;

    public Place(Address address, Classified classified, double latitude, double longitude, String label) {
        this.address = address;
        this.classified = classified;
        this.latitude = latitude;
        this.longitude = longitude;
        this.label = label;
    }

    public Place(Classified classified, Address address) {
        this.classified = classified;
        this.address = address;
    }

    public Place() {
    }

    public long getId() {
        return id;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public double getLatitude() {
        return latitude;
    }

    public void setLatitude(double latitude) {
        this.latitude = latitude;
    }

    public double getLongitude() {
        return longitude;
    }

    public void setLongitude(double longitude) {
        this.longitude = longitude;
    }

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }
}

@Embeddable
public class Address {
    private String country;
    private String countryCode;
    private String state;
    private String city;
    private String suburb;
    private String town;
    private String county;
    private String postcode;
    private String hamlet;
    private String village;
    private String stateDistrict;

    public Address() {
    }

    public Address(String country, String countryCode, String state, String city, String suburb, String town,
                   String county, String postcode, String hamlet, String village, String stateDistrict) {
        this.country = country;
        this.countryCode = countryCode;
        this.state = state;
        this.city = city;
        this.suburb = suburb;
        this.town = town;
        this.county = county;
        this.postcode = postcode;
        this.hamlet = hamlet;
        this.village = village;
        this.stateDistrict = stateDistrict;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getCountryCode() {
        return countryCode;
    }

    public void setCountryCode(String countryCode) {
        this.countryCode = countryCode;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getSuburb() {
        return suburb;
    }

    public void setSuburb(String suburb) {
        this.suburb = suburb;
    }

    public String getTown() {
        return town;
    }

    public void setTown(String town) {
        this.town = town;
    }

    public String getCounty() {
        return county;
    }

    public void setCounty(String county) {
        this.county = county;
    }

    public String getPostcode() {
        return postcode;
    }

    public void setPostcode(String postcode) {
        this.postcode = postcode;
    }

    public String getHamlet() {
        return hamlet;
    }

    public void setHamlet(String hamlet) {
        this.hamlet = hamlet;
    }

    public String getVillage() {
        return village;
    }

    public void setVillage(String village) {
        this.village = village;
    }

    public String getStateDistrict() {
        return stateDistrict;
    }

    public void setStateDistrict(String stateDistrict) {
        this.stateDistrict = stateDistrict;
    }
}
@Entity
public class ImageMetadata {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    private String path;
    private String filename;

    @ManyToOne
    @JoinColumn(name="classified_id")
    private Classified classified;

    public Classified getClassified() {
        return classified;
    }

    public void setClassified(Classified classified) {
        this.classified = classified;
    }

    public ImageMetadata() {
    }

    public ImageMetadata(String path) {
        this.path = path;
    }

    public ImageMetadata(FileMetadata fileMetadata) {
        this.path = fileMetadata.getPath();
        this.filename = fileMetadata.getFilename();
    }

    public String getFilename() {
        return filename;
    }

    public void setFilename(String filename) {
        this.filename = filename;
    }

    public long getId() {
        return id;
    }

    public String getPath() {
        return path;
    }
}
@Entity
public class ThumbnailMetadata {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    private String path;
    private String filename;

    @ManyToOne
    @JoinColumn(name="classified_id")
    private Classified classified;

    public Classified getClassified() {
        return classified;
    }

    public void setClassified(Classified classified) {
        this.classified = classified;
    }

    public ThumbnailMetadata() {
    }

    public ThumbnailMetadata(String path) {
        this.path = path;
    }

    public ThumbnailMetadata(FileMetadata fileMetadata) {
        this.path = fileMetadata.getPath();
        this.filename = fileMetadata.getFilename();
    }

    public void setPath(String path) {
        this.path = path;
    }

    public String getFilename() {
        return filename;
    }

    public void setFilename(String filename) {
        this.filename = filename;
    }

    public long getId() {
        return id;
    }

    public String getPath() {
        return path;
    }
}

Репозиторий:

@Repository
public interface ClassifiedRepository extends CrudRepository<Classified, Long>, JpaSpecificationExecutor<Classified> {}

Спецификация:

public class ClassifiedCountrySpecification implements Specification<Classified> {
    private final String countryString;

    public ClassifiedCountrySpecification(String countryString) {
        this.countryString = countryString;
    }

    @Override
    public Predicate toPredicate(Root<Classified> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
        return criteriaBuilder.like(root.get("place").get("address").get("country"), "%" + countryString + "%");
    }
}
...