Повторяющаяся запись для уникального ключа в базе данных - PullRequest
0 голосов
/ 30 марта 2019

Я новичок в Hibernate и прекратил попытки обновить / объединить запись в таблице базы данных mysql из-за проблемы, с которой я столкнулся.У меня есть уникальное ограничение для столбца в таблице, и я хочу обновить его после изменения некоторых значений в базе данных с помощью hibernate, но он никогда не работает:

Это мой класс Java:

package com.weatherapi.test.weather_api.model;

import lombok.Data;

import javax.persistence.*;

@Entity
@Table(name="weather", uniqueConstraints = @UniqueConstraint(columnNames = {"city"}))
@Data
public class Weather {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    @Column(name = "city")
    private String city;

    private String headline;

    @Column(name = "descriptions")
    private String description;

    @Transient
    private String wind;

    @Transient
    private String icon;

    private String currentTemp;
    private String minTemp;
    private String maxTemp;
    private String sunrise;
    private String sunset;

    @Transient
    private String unit;
}

и я использую session.merge(weatherToUpdate);, чтобы объединить его с базой данных после изменения некоторых значений.но слияние не удается и даже saveOrUpdate не удается.

В моей базе данных уже есть запись города Лондон, которую я хочу извлечь из таблицы, объединить некоторые изменения и загрузить ее обратно в базу данных.

Вот ошибка, которую яget:

java.sql.SQLIntegrityConstraintViolationException: Duplicate entry 'London' for key 'UK_835v8un5oinaj7vdsvc9ym7ub'
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:117) ~[mysql-connector-java-8.0.15.jar:8.0.15]
    at 

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

РЕДАКТИРОВАТЬ:

Вот как я пытаюсь сохранить:

public void updateCityFromDatabase(Weather weatherToUpdate,String city){
    // Create Session
    Session session = factory.getCurrentSession();
    // Begin Transaction
    session.getTransaction().begin();
    try{
    LOGGER.info("reading the weather data...");
    Query query = session.createQuery("from Weather wt where wt.city = :city");
    query.setParameter("city",weatherToUpdate.getCity());
    List<Weather> retrievedWeatherData = query.list();
    if(retrievedWeatherData.get(0).getCity().equals(weatherToUpdate.getCity())){
        LOGGER.info("City already exists and parameters are same");
        session.save(weatherToUpdate);
    }else{
        session.clear();
    }
    session.getTransaction().commit();
    LOGGER.info("City parameters Updated!");
    factory.close();
}

1 Ответ

1 голос
/ 30 марта 2019

Прежде всего, вы должны понять, как работают экземпляры сущностей в Hibernate. Вы можете начать с чтения руководства здесь .

В вашем примере вам нужно передать объект retrievedWeatherData.get(0) в качестве аргумента функции merge() после копирования свойств из weatherToUpdate объекта.

Копирование может быть выполнено либо вручную, либо с помощью вспомогательной служебной функции, например BeanUtils.copyProperties () из библиотеки Apache Commons (см. Пример ).

Итак, ваш код становится:

List<Weather> retrievedWeatherData = query.list();
Weather firstRetrievedWeatherData = retrievedWeatherData.get(0);

if (firstRetrievedWeatherData.getCity().equals(weatherToUpdate.getCity())) {

    // Manually Copy properties values from weatherToUpdate to retrieved object
    // Property value for id is excluded
    firstRetrievedWeatherData.setCity(weatherToUpdate.getCity());
    firstRetrievedWeatherData.setHeadline(weatherToUpdate.getHeadline());
    // Copy more other properties

    // Generate an update sql statement instead of insert
    session.merge(firstRetrievedWeatherData);
}

Наконец, я бы рекомендовал использовать Spring Data для управления спящими объектами, если вы используете Spring или Spring boot. Это совсем не сложно, вы можете перестать беспокоиться об управлении транзакциями с БД (запуск, принятие, откат), а также вам предоставляется несколько функций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...