Spring + Hibernate:具有相同标识符值的不同对象已与会话相关联 [英] Spring + Hibernate : a different object with the same identifier value was already associated with the session

查看:94
本文介绍了Spring + Hibernate:具有相同标识符值的不同对象已与会话相关联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的使用Spring和Hibernate的应用程序中,每次从CSV文件读取记录时,我都通过调用 handleRow()来解析CSV文件并填充数据库。

我的域名模式:


'家族'有许多'SubFamily' 'b'b
'SubFamily'有很多'Locus'



一个'Locus'属于一个'Species' p>

系列< - > SubFamily< - >轨迹都是双向映射。



代码:

  public void handleRow(Family dummyFamily,SubFamily dummySubFamily ,Locus dummyLocus){
//访问DAO层的服务方法
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);
}

//使用保存引用,从GFF处理程序
更新Locus locus = dummyLocus;

subFamily.addLocus(locus);

assignSpecies(serv,locus);
//坚持对象
if(newFamily){
serv.createFamily(family);
} else {
serv.updateFamily(family);




$ b一个物种被分配到一个轨迹使用以下方法,它只访问DAO层:

  private void assignSpecies(CommonService serv,Locus locus){
String locusId = locus .getLocusId();
String speciesId = CommonUtils.getLocusSpecies(locusId,ctx.getSpeciesList())。getSpeciesId();
//只需从DAO获取Species对象
Species sp = serv.getSpeciesBySpeciesId(speciesId);
locus.setSpecies(sp);

Hibernate提供以下错误:

  [INFO]以周期[5000ms]开始计划刷新缓存
Hibernate:插入物种(species_id,name)值(?,?)
Hibernate :插入物种(species_id,name)值(?,?)
Hibernate:插入物种(species_id,name)值(?,?)
########### ################# ROW ##################### 1
SubFamiyID ##### ## RIF0005913
休眠:选择this_.id为id1_0_,this_.family_id为family2_1_0_,this_.rif_iD为rif3_1_0_,this_.family_name为family4_1_0_,this_.family_ipr_id为family5_1_0_,this_.family_pattern作为family6_1_0_从家人那里THIS_ THIS_ .family_id =?
创建新的SubFamiyID ####### RIF0005913
Hibernate:选择this_.id作为id3_0_,this_.species_id作为species2_3_0_,this_.name作为name3_0_ from species this_ where this_.species_id =?
休眠:插入到家庭(family_id,rif_iD,FAMILY_NAME,family_ipr_id,family_pattern)值
休眠(,,,,?????):插入亚科(sub_family_id,rif_iD,sub_family_name,sub_family_ipr_id, (?,?,?,?,?,?)
Hibernate:插入locus(locus_id,refTrans_id,function,species_id,sub_family_id,sub_family_index)值(?,?,? ?,?,?,?)
Hibernate:更新物种集species_id = ?, name =?其中id =?
Hibernate:更新子系列集合family_id =?,sub_family_index =?其中id =?
Hibernate:更新轨迹集sub_family_id =?,sub_family_index =?其中id =?
############################ ROW ################# #### 2
SubFamiyID ####### RIF0005913
休眠:选择this_.id如id1_0_,this_.family_id如family2_1_0_,this_.rif_iD如rif3_1_0_,this_.family_name如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 =?
休眠:选择subfamilie0_.family_id为family7_1_,subfamilie0_.id为id1_,subfamilie0_.sub_family_index为sub8_1_,subfamilie0_.id为id0_0_,subfamilie0_.sub_family_id为sub2_0_0_,subfamilie0_.rif_iD为rif3_0_0_,subfamilie0_.sub_family_name为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:选择species0_.id作为id3_0_,species0_.species_id作为species2_3_0_,species0_.name作为name3_0_来自物种species0_,其中species0_.id =?
休眠:选择this_.id为id1_0_,this_.family_id为family2_1_0_,this_.rif_iD为rif3_1_0_,this_.family_name为family4_1_0_,this_.family_ipr_id为family5_1_0_,this_.family_pattern从家庭family6_1_0_ THIS_其中this_.family_id = ?
Hibernate:选择this_.id作为id3_0_,this_.species_id作为species2_3_0_,this_.name作为name3_0_ from species this_ where this_.species_id =?
线程main中的异常[INFO] Closing Compass [compass]
org.springframework.orm.hibernate3.HibernateSystemException:具有相同标识符值的不同对象已与会话相关联:[com。 bigg.nihonbare.common.domain.Species#1];嵌套异常是org.hibernate.NonUniqueObjectException:具有相同标识符值的不同对象已与会话相关联:[com.bigg.nihonbare.common.domain.Species#1]
由org.hibernate引起。 NonUniqueObjectException:一个不同的对象使用相同的标识符值已经与会话相关联:[com.bigg.nihonbare.common.domain.Species#1]
。在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)$在org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:89)上的b
在org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:507)
在org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:499)
在org.hibernate.engine .CascadingAction $ 5.cascade(CascadingAction.java:218)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:268)

任何提示?使用 merge() 。异常意味着当前会话已经知道你正在传递的实体。如果不是,请检查如何覆盖 hashCode() equals() - 它应该为不同的实体返回不同的值。


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?

解决方案

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.

这篇关于Spring + Hibernate:具有相同标识符值的不同对象已与会话相关联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆