#spring-boot #spring-boot-jpa
#весенняя загрузка #spring-boot-jpa
Вопрос:
У меня есть таблица с 4 полями. И если я вставил запись, которая уже существует, т.е. Все значения полей совпадают с предыдущей записью в таблице. Как мне вернуть только запись, но не вставить в базу данных?
Моя модель выглядит так:
@Entity
public class QuestionDetails {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String department;
private String year;
private String academic_year;
private String semester;
private String type;
private String subject;
private int points;
private int unit;
// getter, setter
И контроллер выглядит так:
@Autowired
public QuestionDetailsRepository qdRepository;
@PostMapping("/api/questionDetails")
public QuestionDetails addQuestion(@Valid @RequestBody QuestionDetails qDetails) {
// here i want to first check if qDetails object is already present in table .
If present i want to return that existed record instead of inserting into table.
QuestionDetails qd = qdRepository.save(qDetails); // save only new record
return qd;
}
Используя postman, я отправляю данные следующим образом:
{
"department" : "IT",
"year" : "2020",
"academic_year" : "1st year",
"semester" : "first semester",
"type" : "objective",
"subject" : "JAVA",
"points" : 10,
"unit" : 5
}
Здесь я отправляю данные, которые уже присутствуют в таблице. Итак, я хочу проверить, существует ли эта запись уже? Если не существует, вставьте в таблицу, иначе верните эту существующую запись.
Как мне добиться этого, используя springboot Jpa hibernate?
Комментарии:
1. Можете ли вы поделиться моделью данных? JPA / Hibernate выполняет выбор перед вставкой или обновлением. Вы уверены, что он вставляет данные? Поделитесь некоторым кодом, чтобы лучше понять его.
2. @Tushar да, он вставляет те же данные, но я хочу вернуть эти данные вместо вставки в таблицу для повторяющихся данных.
Ответ №1:
Реализуйте метод выбора QuestionDetailsRepository
, как показано ниже. Добавьте все критерии, которые делают запись уникальной. Я использую отдел и год, но вы можете использовать все параметры QuestionDetails
объекта.
@Query("select qd from QuestionDetails qd where qd.department = :#{#req. department} and qd.year = :#{#req.year}")
Optional<QuestionDetails> findQuestionDetails(@Param("req") QuestionDetails req);
Убедитесь, что вы внедрили equals()
и hashCode()
в QuestionDetails
классе в соответствии с уникальными критериями.
Ваш псевдокод будет выглядеть следующим образом:
Optinal<QuestionDetails> optRecord = qdRepository.findQuestionDetails(qDetails);
if(opt.isPresent()){
return opt.get();
}else{
qdRepository.save(qDetails);
}
Комментарии:
1. Я сгенерировал equals() и hashcode() для отдела и года, но я получаю сообщение об ошибке «запрос не вернул уникальный результат: 2 «.
2. У вас есть более одной записи для критериев. Каковы уникальные критерии для таблицы? Вы добавили все параметры из запроса, кроме отдела и года?
3. Уникальным критерием в таблице является то, имеет ли какой-либо столбец значение, отличное от других записей. Да, я добавил все параметры из запроса, но получаю ту же ошибку. Итак, в следующий раз я добавлю только отдел и только год, но все равно получаю ту же ошибку.
4. Можете ли вы выполнить запрос вручную и поделиться результатами? Возможно, вам потребуется изменить возвращаемый тип на list или удалить повторяющиеся записи. Кажется, уникальное ограничение отсутствует на уровне БД. Другой вариант — изменить возвращаемый тип на List.
5. Это сработало после изменения возвращаемого типа. Спасибо за ваше время. Очень признателен.