Лучший способ предотвратить дублирование строк в базе данных

Я использую hibernate , ища передовой опыт, чтобы избежать той же самой вставки в базу данных. Я написал программу, которая сохраняет результаты поиска из API в зависимости от ввода пользователя, когда ввод один и тот же, у меня есть дублированные строки без идентификатора в базе данных. Это проблематично для меня, потому что в будущем использует. Каждая вставка должна быть УНИКАЛЬНОЙ.

Часть модели сущности:

@Entity
@Component
public class Flight {

    private Long id;

    private String departure;

    private String currency;

    private String destination;

    private BigDecimal price;
... etc //

Сохранить код:

        @RequestMapping(value = "/save", method = RequestMethod.GET)
        public String save(
                @ModelAttribute("FlightDTO") FlightDTO flightDTO,
                @ModelAttribute("FlightOutput") Map<String, Map<String, FlightDeserialization>> flightOutputMap,
                @ModelAttribute("HotelOutput") ArrayList<Comparison> hotelOutputList,
                @ModelAttribute("HotelGooglePlaceList") Map<Integer, List<PlacesResults>> hotelGooglePlaceList,
                @ModelAttribute("HotelGoogleImageList") Map<Integer, List<Imageresults>> hotelGoogleImageList) {


            boolean isHotelGoogleListEqualToHotelOutputList = hotelGooglePlaceList.keySet().size() == hotelOutputList.size() & hotelGooglePlaceList.keySet().size() == hotelGoogleImageList.size();


            Flight flight;
            for (String keyOut : flightOutputMap.keySet()) {

                for (String keyIn : flightOutputMap.get(keyOut).keySet()) {
                    flight = new Flight();
                    flight.setCurrency(flightDTO.getCurrency());
                    flight.setAirline(csvParser.airlineParser(flightOutputMap.get(keyOut).get(keyIn).getAirline()));
                    flight.setAirlineIata(flightOutputMap.get(keyOut).get(keyIn).getAirline());
                    flight.setDepartureTime(flightOutputMap.get(keyOut).get(keyIn).getDepartureTime());
                    flight.setReturnTime(flightOutputMap.get(keyOut).get(keyIn).getReturnTime());
                    flight.setFlightNumber(flightOutputMap.get(keyOut).get(keyIn).getFlightNumber());
                    flight.setPrice(flightOutputMap.get(keyOut).get(keyIn).getPrice());
                    flight.setExpiresAt(flightOutputMap.get(keyOut).get(keyIn).getExpiresAt());
                    flight.setDestination(flightDTO.getDestination());
                    flight.setDeparture(flightDTO.getDeparture());
                    flight.setUserName(CurrentUserName().getUsername());

                    if (isHotelGoogleListEqualToHotelOutputList) {
                        Hotel hotel;
                        BigDecimal exchangeRate = currencyRepository.findByName(flightDTO.getCurrency()).getExchangeRate();
                        for (int i = 0; i < hotelOutputList.size(); i++) {
                            Comparison array = hotelOutputList.get(i);
                            hotel = new Hotel();


                            hotel.setImage(hotelGoogleImageList.get(i).get(1).getImage());
                                            hotel.setHotelLink(hotelGoogleImageList.get(i).get(0).getLink());



                            hotel.setLatitude(hotelGooglePlaceList.get(i).get(0).getGps_coordinates().getLatitude());
                            hotel.setLongitude(hotelGooglePlaceList.get(i).get(0).getGps_coordinates().getLongitude());


hotel.setCurrency(flightDTO.getCurrency());
hotel.setName(array.getHotel());
hotel.setSite(array.getVendor1());
hotel.setSite(array.getVendor2());
                            hotel.setPrice(hotelCurrencyService.amountCalculator(array.getVendor1Price(), exchangeRate));
                            hotel.setPrice(hotelCurrencyService.amountCalculator(array.getVendor2Price(), exchangeRate));
                            hotel.setPrice(hotelCurrencyService.amountCalculator(array.getVendor3Price(), exchangeRate));


flight.setHotel(hotel);
flightRepository.save(flight);

Я пробовал использовать @UniqueConstraint и @Unique, но, думаю, он предназначался для чего-то другого.

Пожалуйста, помогите мне !

Создайте уникальное ограничение в базе данных.

fiveelements 28.07.2019 08:27
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
1
2 804
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Добавление @UniqueConstraint в ORM не помогает, так как спящий режим не проверяет уникальность. Есть два способа — добавить уникальное ограничение в таблицу базы данных и/или реализовать проверку дублирующихся записей самостоятельно в коде.

Если вы добавите уникальное ограничение в таблицу базы данных, обработайте исключение нарушения ограничений.

Почему нет? @UniqueConstraint должен создавать уникальный индекс для объявленных полей, не так ли?

Bor Laze 28.07.2019 08:33

@BorLaze Если DDL не сгенерирован, уникальный индекс не будет создан. Почему бы не сделать это в первую очередь в определении таблицы, если OP не генерирует DDL из ORM?

fiveelements 28.07.2019 08:40

Я не знаю, но когда я добавил его в свойства приложения, Intellij кричит, что это неиспользуемое свойство.

Grafik Krystian 28.07.2019 08:41

@GrafikKrystian, ты пробовал spring.jpa.hibernate.ddl-auto=update?

Bor Laze 28.07.2019 08:46
Ответ принят как подходящий

Во-первых, вам не нужно @Component на вашей сущности.

Во-вторых, добавьте эту аннотацию

@Table(name = "table_name", uniqueConstraints = {@UniqueConstraint(columnNames  = {"id", "departure", ...})})

с полями, которые не должны дублироваться.

NB: вам нужно добавить spring.jpa.hibernate.ddl-auto=update в application.properties

spring.jpa.hibernate.ddl-auto=update после добавления РАБОТАЕТ! Спасибо!

Grafik Krystian 28.07.2019 08:59

Бор уже дал ответ, но я просто хочу кое-что добавить, вы также можете указать @Column(unique = true) private int id; на уровне поля, у вас также будет больше контроля, например, обнуляемый, обновляемый и т. д.

Romil Patel 28.07.2019 10:13

Другие вопросы по теме