Spring + Hibernate:具有相同标识符值的不同对象已与会话相关联 [英] Spring + Hibernate : a different object with the same identifier value was already associated with the session
问题描述
在我的使用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屋!