Как мне проверить, существует ли запись уже в таблице в springboot JPA?

#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. Это сработало после изменения возвращаемого типа. Спасибо за ваше время. Очень признателен.