#StackBounty: #java #hibernate In Hibernate why does saveOrUpdate give an exception when object already exists in database

Bounty: 50

Previously, when I was adding a entity to database with Hibernate I used to check that it hadn’t already been added. But in an effort to improve performance I forgot this check and just tried to add without checking, as I was using saveOrUpdate() it was my understanding that if Hibernate found it was already added it would just update with and changes made by my save.

But instead it fails with

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;
        }

Used to check first before call to addToDatabase

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


Get this bounty!!!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.