gpt4 book ai didi

java - 在 Hibernate 中,当对象已存在于数据库中时,为什么 saveOrUpdate 会抛出异常

转载 作者:行者123 更新时间:2023-11-29 07:26:24 25 4
gpt4 key购买 nike

以前,当我使用 Hibernate 将一个实体添加到数据库时,我常常检查它是否已经被添加。但是为了提高性能,我忘记了这个检查,只是尝试在不检查的情况下添加,因为我正在使用 saveOrUpdate() 据我了解,如果 Hibernate 发现它已经被添加,它只会更新以及我的保存所做的更改。

但是它失败了

18/08/2018 21.58.34:BST:Errors:addError:SEVERE: Adding Error:Database Error:Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [com.jthink.songlayer.MusicBrainzReleaseWrapper#95f6f584-407f-4b26-9572-bb8c6e9c580a]
java.lang.Exception
at com.jthink.songkong.analyse.general.Errors.addError(Errors.java:28)
at com.jthink.songkong.exception.ExceptionHandling.handleHibernateException(ExceptionHandling.java:209)
at com.jthink.songkong.db.ReleaseCache.addToDatabase(ReleaseCache.java:394)
at com.jthink.songkong.db.ReleaseCache.add(ReleaseCache.java:65)




@Entity
public class MusicBrainzReleaseWrapper
{
@Id
private String guid;

@Version
private int version;

@org.hibernate.annotations.Index(name = "IDX__MUSICBRAINZ_RELEASE_WRAPPER_NAME")
@Column(length = 1000)
private String name;

@Lob
@Column(length = 512000)
private String xmldata;

public String getGuid()
{
return guid;
}

public void setGuid(String guid)
{
this.guid = guid;
}

public String getName()
{
return name;
}

public void setName(String name)
{
this.name = name;
}

public String getXmldata()
{
return xmldata;
}

public void setXmldata(String xmldata)
{
this.xmldata = xmldata;
}
}

private static boolean addToDatabase(Release release)
{
Session session = null;
try
{
session = HibernateUtil.beginTransaction();
//Marshall to String
StringWriter sw = new StringWriter();
Marshaller m = jc.createMarshaller();
m.marshal(release, sw);
sw.flush();

MusicBrainzReleaseWrapper wrapper = new MusicBrainzReleaseWrapper();
wrapper.setGuid(release.getId());
wrapper.setName(release.getTitle().toLowerCase(Locale.UK));
wrapper.setXmldata(sw.toString());
session.saveOrUpdate(wrapper);
session.getTransaction().commit();
MainWindow.logger.info("Added to db release:" + release.getId() + ":" + release.getTitle());
return true;
}
catch (ConstraintViolationException ce)
{
MainWindow.logger.warning("Release already exists in db:"+release.getId()+":"+release.getTitle());
return true;
}
catch(GenericJDBCException jde)
{
MainWindow.logger.log(Level.SEVERE, "Failed:" +jde.getMessage());
ExceptionHandling.handleDatabaseException(jde);
}
catch(HibernateException he)
{
MainWindow.logger.log(Level.SEVERE, "Failed:" +he.getMessage());
ExceptionHandling.handleHibernateException(he);
}
catch(Exception e)
{
MainWindow.logger.log(Level.WARNING,"Failed AddReleaseToDatabase:"+release.getId()+ ':' +e.getMessage(),e);
throw new RuntimeException(e);
}
finally
{
HibernateUtil.closeSession(session);
}
return false;
}

用于在调用 addToDatabase 之前首先检查

        if(ReleaseCache.get(release.getId())==null)
{
addToDatabase(release)
}

最佳答案

Hiberante 对象对于一个实体有 3 种状态。他们是: - 短暂的或新的 - 分离(对象从数据库中获取并且 hibernate session 关闭) - 持久性(对象从数据库中获取并且 hibernate session 打开)在 saveOrUpdate 方法中,它要么保存临时对象,要么更新分离/持久对象。在您的代码中,您正在尝试创建 Transient/New 对象并在其中设置旧 ID。这就是您遇到上述错误的原因。正确的方法是先使用 id 获取对象,然后更新它。

关于java - 在 Hibernate 中,当对象已存在于数据库中时,为什么 saveOrUpdate 会抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51918466/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com