Hibernate 数据库中唯一密钥的重复项

Hibernate 数据库中唯一密钥的重复项,hibernate,spring-boot,Hibernate,Spring Boot,我不熟悉Hibernate,因为遇到了一个问题,我放弃了尝试更新/合并mysql数据库表中的一个条目。我在表中的一列上有一个唯一的约束,我想在使用hibernate更改数据库中的某些值后对其进行更新,但它永远不起作用: 这是我的java类: 我正在使用session.mergeweatherToUpdate;在更改某些值后将其合并回数据库。但是合并失败,甚至saveOrUpdate也失败了 我的数据库中已经有一个citylondon条目,我想从表中提取它,合并一些更改并将其上传回数据库 以下是我

我不熟悉Hibernate,因为遇到了一个问题,我放弃了尝试更新/合并mysql数据库表中的一个条目。我在表中的一列上有一个唯一的约束,我想在使用hibernate更改数据库中的某些值后对其进行更新,但它永远不起作用:

这是我的java类:

我正在使用session.mergeweatherToUpdate;在更改某些值后将其合并回数据库。但是合并失败,甚至saveOrUpdate也失败了

我的数据库中已经有一个citylondon条目,我想从表中提取它,合并一些更改并将其上传回数据库

以下是我得到的错误:

我尝试使用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();
}

首先,您必须了解在Hibernate中管理实体实例的工作方式。你可以从阅读指南开始

在您的示例中,从weatherToUpdate实体复制属性后,需要将retrievedWeatherData.get0对象作为参数传递给merge函数

复制可以手动完成,也可以使用ApacheCommons库中的helper实用程序函数完成。请参阅

因此,您的代码变成:

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或Spring boot,我建议您使用来管理hibernate实体。这一点都不难,您可以不再担心管理数据库事务启动、提交、回滚,而且您还可以获得一些功能。

您是否尝试过保存?相同错误java.sql.SQLIntegrityConstraintViolationException:Duplicate entry。。我没有得到的是,我只想更新字段并将其设置回。。但它不允许我。陷入这样的问题是非常令人沮丧的。我现在损失了2-3个小时。你能告诉我你是怎么做到的吗?是的,我已经更新了我的代码。请检查一下你的方法是否有效。我试过了,现在没有错误了。我现在就知道了,所以您需要先从数据库中获取数据,然后执行保存、更新操作。您可以检索一个hibernate管理的实体,您可以将其视为数据库中的记录,在其中执行操作。。不过,我建议你花点时间阅读。好的。是的,我正在读一些书,也在看一些视频来理解。非常感谢!
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();
}
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);
}