#hibernate #jpa #criteria-api
#гибернация #jpa #критерии-api
Вопрос:
У меня есть таблица со следующими столбцами и соответствующим классом POJO
@Entity
@Table(name = "base_quote")
public class BaseQuote {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "cc_min")
private int cubicCapacityMin;
@Column(name = "cc_max")
private int cubicCapacityMax;
@Column(name = "car_age_min")
private int carAgeMin;
@Column(name = "car_age_max")
private int carAgeMax;
@Column(name = "base_amount")
public double baseAmount;
конструктор, геттеры и сеттеры
Я пытаюсь написать запрос, который вернет базовое значение для автомобиля, кубический объем которого находится между cc_min и cc_max, а возраст — между carAgeMin и carAgeMax. Я пытаюсь получить либо всю строку, чтобы позже я мог использовать базовое значение этой строки.
Я получаю cc и возраст автомобиля через DTO.
private double baseAmount (QuoteDTO quoteDTO) {
try (Session session = sessionFactory.openSession()) {
CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery<BaseQuote> cq = cb.createQuery(BaseQuote.class);
Root<BaseQuote> root = cq.from(BaseQuote.class);
cq.select(root).where(cb.gt(root.get("cc_max")), quoteDTO.getCubicCapacity());
Query<BaseQuote> query = session.createQuery(cq);
List<BaseQuote> results = query.getResultList();
}
return null;
}
Я получаю что-то не так, потому что я получаю не удается разрешить метод, потому cb.gt(root.get("cc_max")
что я пытался также использовать имя поля класса cubicCapacityMax
вместо cc_max
, но я получаю ту же ошибку. Я хочу получить строки, в которых значение cc_max
больше кубической емкости DTO, поэтому я использовал то .gt()
, что было предложено в демонстрации, которую я использовал. Он подчеркивает все в скобках .gt()
. Я знаю, что это не дает конкретного результата, который я на самом деле ищу, но это первая часть выражения. Где я ошибаюсь?
Комментарии:
1. Ваше утверждение должно быть
cb.gt(root.get("cc_max"), quoteDTO.getCubicCapacity())
?2. @samabcde Я так думаю, я думаю, что .gt() должен сравнить то, что есть в базе данных, со вторым параметром, который в моем случае является целым числом, поступающим из DTO. Я думаю, что я пытаюсь неправильно прочитать cc_max, но не знаю почему
3. Следует ли использовать сопоставленное свойство
cubicCapacityMax
вместо имени столбцаcc_max
, поскольку вы не пишете sql? Я предлагаю вам предоставить подробную информацию о вашей новой проблеме в другом вопросе, поскольку текущий вопрос возникает только из-за простой опечатки.4. Вы должны использовать имя свойства, а не имя поля базы данных:
root.get("cubicCapacityMax")
вместоroot.get("cc_max")
. Попробуйте следовать руководству «Hello World» и заставить его работать, прежде чем отправлять вопрос5. спасибо вам обоим, я соответствующим образом отредактирую свой вопрос, но, как я уже сказал, я пытался использовать как cubicCapacityMax, так и cc_max, и я получил то же самое от IntelliJ
Ответ №1:
Вы получаете ошибку, потому что using Path#get(String)
не является типобезопасным. Используйте выражения метамодели, если вы хотите, чтобы компилятор правильно интерпретировал тип, который вы хотите вернуть. Если вы используете строковый параметр, вам нужно указать такой тип:
Expression<Integer> expr = root.<Integer> get("cubicCapacityMax");
Используя Метамодель, то же самое выражение может быть получено таким образом:
Expression<Integer> expr = root.get(BaseQuote_.cubicCapacityMax);
Также обратите внимание, что строковый параметр должен соответствовать имени свойства ( cubicCapacityMax
в данном случае), а не имени поля ( cc_max
) в базе данных.
Смотрите также: