本人自学开发一个图书管理系统,持久层尝试用hibernate,但是进行删除操作一老抛出异常(描述比較長,請耐心觀看)一般来说 根据 底层数据库 主外键设置的主从表,可以映射为实体关系的 一对多的双向连接。
我用MyEclipse自动生成DAO文件,在hbm.xml映射文件中
我把所有的one-to-many的设置如下:
<set cascade="all,delete-orphan" inverse="true" name="bookstores" sort="unsorted">
   <key>
    <column name="BOOKRID" not-null="true" precision="22" scale="0"/>
   </key>
   <one-to-many class="bookDAO.Bookstore"/>
  </set>
所有的many 端设置如下:
<many-to-one class="bookInfoDAO.Bookinfo" fetch="select" name="bookinfo">
   <column name="BOOKRID" not-null="true" precision="22" scale="0" />
  </many-to-one>整个数据库表的关系如下(箭头方向为主表,非箭头的为从表):Role<--UserInfo<---BookBorrowInfo-->BookStore--->BookInfo--->CateInfo
角色<--用户信息<---库存借阅信息---->图书库存--->图书信息--->分类在java代码中进行删除BookInfo的代码如下:1) Transaction tx=this.getSession().beginTransaction(); 2)          this.getSession().delete(bookinfoRef);3) tx.commit(); 在第三步
a)如果该BookInfo有子项BookStore,该子项BookStore还有子项BookBorrowInfo,则删除bookinfo抛出
org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [bookBorrowRecordDAO.Bookborrowinfo#1540]
org.hibernate.impl.SessionImpl.forceFlush(SessionImpl.java:1014)
org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:165)
org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:94)
org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
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)
org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:268)
org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:216)
org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:296)
org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:242)
org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:219)
org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
org.hibernate.engine.Cascade.cascade(Cascade.java:130)
org.hibernate.event.def.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:131)
org.hibernate.event.def.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:122)
org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:65)
org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
bookInfoDAO.BookinfoDAO.deleteSelectBookinfo(BookinfoDAO.java:247)
b)如果子项BookStore没有子项BookBorrowInfo,则删除bookinfo正常。c)如果把和BookInfo所有子项BookStore和所有子项BookStore的子项BookBorrowInfo去除关联
setParent(null),parent.getChilds().clear();就不会抛出异常,到底是为什么呢?d)其他的对象,采用上面三步走的方式删除则不会抛出异常,比如刪除Userinfo,BookStore,Borrowinfo,偏偏就Bookinfo出問題我想:設置cascade="all,delete-orphan" ,刪除主表記錄,字表應該會被Hibernate自動刪除,不應該有什麽問題啊
小弟苦闷了好久,請大家帮帮我吧,先謝謝了

解决方案 »

  1.   

    是不是之前加载了UserInfo
    1) Transaction tx=this.getSession().beginTransaction();2)          this.getSession().delete(bookinfoRef);3) tx.commit(); 你的这个session的生命周期是什么样的,从打开到关闭还做了哪些操作
      

  2.   


    因为bookstore有子项,所以删除bookstore时,会报异常,你将这两个的级联更新也设置为cascade="all,delete-orphan" 估计就行了。
      

  3.   

    Transaction tx=this.getSession().beginTransaction(); 2)          this.getSession().delete(bookinfoRef); 3) tx.commit();
    这里的删除是没问题的,deleted object would be re-saved by cascade 
    系统提示你的删除对象并没有持久化,看看你是怎么获得bookinfoRef的
      

  4.   

    可能是你级联的层次太多 所以你要删除的话 就的把所以有关联的set 都加上级联删除 不然 是会报错的 
      

  5.   

    因为使用MyEclipse的自动生成的DAO对象
    我所有的数据表的DAO类都是继承相同的BaseHibernateDAO类,BaseHibernateDAO调用了HibernateSessionFactory 的getSession()静态方法返回的Session,在HibernateSessionFactory类中,我做了手脚,设置了一个静态属性Session,把返回的Session都设置为这个Session的引用,类似 singtlon工厂模式这样不同DAO生成的实体对象可以在各个DAO的Session中使用了,就不用getSession().merge(arg)了,也不必关闭session了。这样做肯定不对,但是我Spring还不会呢 -_-!  。。
      

  6.   


    根据MyEclipse自动生成DAO类获取的集合,如:通过BookinfoDAO.findAll()方法返回非泛型集合List,然后我手工转为List<Bookinfo>集合,删除的 bookinfoRef就是从这个List<Bookinfo>集合选取的
      

  7.   


    由于设置了cascade="all"并且List<Bookinfo>集合和bookinfoRef在同一个持久上下文里,如果不事先把这个bookinfoRef从集合里删除,就去删除它的话。就会出现org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade 
      

  8.   

    lz,<set cascade="all,delete-orphan" cascade="all"里面的都包含了
    其中删除的是不能用的!这功能在HIBERNATE中没什么作用