Spring + Hibernate : a different object with the same identifier value was already associated with the session

75,081

Solution 1

Use merge(). The exception means that the current session is already aware of the entity you are passing. If not, check how you have overridden hashCode() and equals() - it should return different values for different entities.

Solution 2

You can also encounter this problem if you are doing a delete() or update(). The problem is likely to occur if you build the hibernate-mapped pojo yourself, perhaps from a DTO. This pojo now has the same identifier as one that is already in the Session, and that causes the problem.

You now have two options. Either do what @Bozho said and first merge() the object. That takes care of updating. For deleting, take the object returned by merge() and delete it.

The other option is to first query the Session using the id of the object and then delete or update it.

Solution 3

I have seen this when an Entity does not have a GeneratedValue annotation for its ID column:

@GeneratedValue(strategy = GenerationType.AUTO)

Solution 4

I resolved so: On delete method:

    this.getHibernateTemplate().clear();

    this.getHibernateTemplate().delete(obj);

    // Esta línea realiza el "commit" del comando
    this.getHibernateTemplate().flush();

On update method:

    this.getHibernateTemplate().merge(obj);

    // Esta línea realiza el "commit" del comando
    this.getHibernateTemplate().flush();
Share:
75,081
Ashika Umanga Umagiliya
Author by

Ashika Umanga Umagiliya

Updated on February 12, 2020

Comments

  • Ashika Umanga Umagiliya
    Ashika Umanga Umagiliya about 4 years

    In my application, which uses Spring and Hibernate, I parse a CSV file and populate the db by calling handleRow() every time a record is read from the CSV file.

    My domain model:

    'Family' has many 'SubFamily'

    'SubFamily' has many 'Locus'

    a 'Locus' belongs to a 'Species'

    Family <-> SubFamily <-> Locus are all bi-directional mappings.

    Code:

    public void handleRow(Family dummyFamily, SubFamily dummySubFamily, Locus dummyLocus) {
      //Service method which access DAO layers
      CommonService serv = ctx.getCommonService();
    
      boolean newFamily=false;
      Family family=serv.getFamilyByFamilyId(dummyFamily.getFamilyId());
      if(family==null){
        newFamily=true;
        family=new Family();
        family.setFamilyId(dummyFamily.getFamilyId());
        family.setFamilyIPRId(dummyFamily.getFamilyIPRId());
        family.setFamilyName(dummyFamily.getFamilyName());
        family.setFamilyPattern(dummyFamily.getFamilyPattern());
        family.setRifID(dummyFamily.getRifID());
      }
    
      SubFamily subFamily = family.getSubFamilyBySubFamilyId( dummySubFamily.getSubFamilyId() );
      if(subFamily==null){   
        subFamily=new SubFamily();
        subFamily.setRifID(dummySubFamily.getRifID());   
        subFamily.setSubFamilyId(dummySubFamily.getSubFamilyId());
        subFamily.setSubFamilyIPRId(dummySubFamily.getSubFamilyIPRId());
        subFamily.setSubFamilyName(dummySubFamily.getSubFamilyName());
        subFamily.setSubFamilyPattern(dummySubFamily.getSubFamilyPattern());
    
        family.addSubFamily(subFamily);
      }
    
      //use the save reference, to update from GFF handler
      Locus locus = dummyLocus;
    
      subFamily.addLocus(locus);
    
      assignSpecies(serv,locus);
      //Persist object
      if(newFamily){
        serv.createFamily(family);
      } else {
        serv.updateFamily(family);
      }
    }
    

    a Species is assigned to a Locus using following method, which simply accesses the DAO layer:

    private void assignSpecies (CommonService serv, Locus locus) {
      String locusId = locus.getLocusId();
      String speciesId = CommonUtils.getLocusSpecies(locusId, ctx.getSpeciesList()).getSpeciesId();
      //Simply get Species object from DAO
      Species sp = serv.getSpeciesBySpeciesId(speciesId);
      locus.setSpecies(sp);  
    }
    

    Hibernate gives following error:

    [INFO] Starting scheduled refresh cache with period [5000ms]
    Hibernate: insert into species (species_id, name) values (?, ?)
    Hibernate: insert into species (species_id, name) values (?, ?)
    Hibernate: insert into species (species_id, name) values (?, ?)
    ############################ROW#####################1
    SubFamiyID#######RIF0005913
    Hibernate: select this_.id as id1_0_, this_.family_id as family2_1_0_, this_.rif_iD as rif3_1_0_, this_.family_name as family4_1_0_, this_.family_ipr_id as family5_1_0_, this_.family_pattern as family6_1_0_ from family this_ where this_.family_id=?
    Creating NEW SubFamiyID#######RIF0005913
    Hibernate: select this_.id as id3_0_, this_.species_id as species2_3_0_, this_.name as name3_0_ from species this_ where this_.species_id=?
    Hibernate: insert into family (family_id, rif_iD, family_name, family_ipr_id, family_pattern) values (?, ?, ?, ?, ?)
    Hibernate: insert into subfamily (sub_family_id, rif_iD, sub_family_name, sub_family_ipr_id, sub_family_pattern, family_id, sub_family_index) values (?, ?, ?, ?, ?, ?, ?)
    Hibernate: insert into locus (locus_id, refTrans_id, function, species_id, sub_family_id, sub_family_index) values (?, ?, ?, ?, ?, ?)
    Hibernate: update species set species_id=?, name=? where id=?
    Hibernate: update subfamily set family_id=?, sub_family_index=? where id=?
    Hibernate: update locus set sub_family_id=?, sub_family_index=? where id=?
    ############################ROW#####################2
    SubFamiyID#######RIF0005913
    Hibernate: select this_.id as id1_0_, this_.family_id as family2_1_0_, this_.rif_iD as rif3_1_0_, this_.family_name as family4_1_0_, this_.family_ipr_id as family5_1_0_, this_.family_pattern as family6_1_0_ from family this_ where this_.family_id=?
    Hibernate: select subfamilie0_.family_id as family7_1_, subfamilie0_.id as id1_, subfamilie0_.sub_family_index as sub8_1_, subfamilie0_.id as id0_0_, subfamilie0_.sub_family_id as sub2_0_0_, subfamilie0_.rif_iD as rif3_0_0_, subfamilie0_.sub_family_name as sub4_0_0_, subfamilie0_.sub_family_ipr_id as sub5_0_0_, subfamilie0_.sub_family_pattern as sub6_0_0_, subfamilie0_.family_id as family7_0_0_ from subfamily subfamilie0_ where subfamilie0_.family_id=?
    Hibernate: select locuslist0_.sub_family_id as sub5_1_, locuslist0_.id as id1_, locuslist0_.sub_family_index as sub7_1_, locuslist0_.id as id2_0_, locuslist0_.locus_id as locus2_2_0_, locuslist0_.refTrans_id as refTrans3_2_0_, locuslist0_.function as function2_0_, locuslist0_.sub_family_id as sub5_2_0_, locuslist0_.species_id as species6_2_0_ from locus locuslist0_ where locuslist0_.sub_family_id=?
    Hibernate: select species0_.id as id3_0_, species0_.species_id as species2_3_0_, species0_.name as name3_0_ from species species0_ where species0_.id=?
    Hibernate: select this_.id as id1_0_, this_.family_id as family2_1_0_, this_.rif_iD as rif3_1_0_, this_.family_name as family4_1_0_, this_.family_ipr_id as family5_1_0_, this_.family_pattern as family6_1_0_ from family this_ where this_.family_id=?
    Hibernate: select this_.id as id3_0_, this_.species_id as species2_3_0_, this_.name as name3_0_ from species this_ where this_.species_id=?
    Exception in thread "main" [INFO] Closing Compass [compass]
    org.springframework.orm.hibernate3.HibernateSystemException: a different object with the same identifier value was already associated with the session: [com.bigg.nihonbare.common.domain.Species#1]; nested exception is org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.bigg.nihonbare.common.domain.Species#1]
    Caused by: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.bigg.nihonbare.common.domain.Species#1]
     at org.hibernate.engine.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:590)
     at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:284)
     at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:223)
     at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:89)
     at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
     at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:507)
     at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:499)
     at org.hibernate.engine.CascadingAction$5.cascade(CascadingAction.java:218)
     at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:268)
    

    Any tips?

  • Ravi Parekh
    Ravi Parekh almost 13 years
    is there a way to do update child entity persistance with session.saveOrUpdate. i have used get() and i need to update child entity with given ID. merge is working but just for information
  • Alex
    Alex over 11 years
    It would be usefull read also this article: stevideter.com/2008/12/07/…
  • Green Fireman
    Green Fireman about 8 years
    Thanks! I had problems with deleting an entity.
  • Bruno Franco
    Bruno Franco over 6 years
    Worked perfectly for me. Thanks!