Hibernate @ManyToOne как не создавать запись, если она уже создана?

Есть три сущности
Город и Источник погоды ( они идентичны ):
public class City {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(unique = true, nullable = false)
    private String cityName;

    public City(String cityName) {
        this.cityName = cityName;
    }
}

Погода:
public class Weather {

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

    private LocalDateTime date;
    private double temp;
    private double humidity;
    private int pressure;
    private String weatherDescription;

    @ManyToOne
    @JoinColumn(name="weather_source_id")
    private WeatherSource weatherSource;

    @ManyToOne
    @JoinColumn(name="city_id")
    private City city;
}


При добавлении погоды с городом, который уже есть в городе получаем ошибку:
//выше получена погода
        w.setCity(new City("Rostov-on-Don"));
        w.setWeatherSource(new WeatherSource("openWeather"));
        weatherService.add(w);

ОШИБКА: повторяющееся значение ключа нарушает ограничение уникальности "uk_djnk44fptegbsu6drhc9xvlfj"

Подробности: Ключ "(city_name)=(Rostov-on-Don)" уже существует.
Как сделать, чтобы hibernate не пытался добавить запись в таблицу городов, если там уже есть нужный город?
Пробовал использовать в equals и hasCode только значение name. Неужели перед тем как добавить нужно просто из сервиса вытянуть город по имени и его уже добавлять к погоде? нельзя ли это сделать автоматически?
  • Вопрос задан
  • 308 просмотров
Решения вопроса 1
azerphoenix
@azerphoenix Куратор тега Java
Java Software Engineer
Здравствуйте!
1) В репозиторий для City (предположительно CityRepository или CityDao) добавьте метод, который вернет вам объект City по его названию.
Optional<City> findCityByCityName(String cityName);

примерно так
2) Далее
Как сделать, чтобы hibernate не пытался добавить запись в таблицу городов, если там уже есть нужный город?

Теперь, в сервисном уровне вы вытягиваете город по его названию и если такого нет, то добавляете, а если такой город есть, то можете в методе orElseThrow() выбросить RuntimeException исключение о том, что такой город есть. Можно создать свое исключение типа: CityExistsException

Если не хотите использовать Optional, то можно создать метод в репозитории boolean existsByCityName(String cityName); А дальше также если true, то выбрасываете исключение
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы