当删除一个被引用的实体时,hibernate会抛出org.hibernate.exception.ConstraintViolationException,现在问题来了。我能捕获到这个异常,然后做一些反馈给用户,说明还有其他资源在引用本资源,不能删除。功能倒是能实现,但是日志文件里有很多ERROR信息,关于org.hibernate.exception.ConstraintViolationException的。
大致如下:
2009-03-18 16:15:09,160 ERROR [org.hibernate.util.JDBCExceptionReporter] - DELETE statement conflicted with COLUMN REFERENCE constraint 'FK4AFD4ACEFA4C24EA'. The conflict occurred in database 'FddsSampleDB', table 'Employee', column 'vfsImage_fileID'.
2009-03-18 16:15:09,176 ERROR [org.hibernate.event.def.AbstractFlushingEventListener] - Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: could not delete: [com.versata.fdds.model.vfs.VFSImage#1485]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2476)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2632)
at org.hibernate.action.EntityDeleteAction.execute(EntityDeleteAction.java:73)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:144)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:297)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:558)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:540)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:510)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:310)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:117)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:652)
at com.versata.fdds.model.managers.VFSImageManager$$EnhancerByCGLIB$$dd5dd6ea.delete(<generated>)多的我就不写了,如何避免这种情况呢?我阅读了org.hibernate.event.def.AbstractFlushingEventListener的源代码,发现有如下方法定义
      /**
      * Execute all SQL and second-level cache updates, in a
      * special order so that foreign-key constraints cannot
      * be violated:
      * <ol>
      * <li> Inserts, in the order they were performed
      * <li> Updates
      * <li> Deletion of collection elements
      * <li> Insertion of collection elements
      * <li> Deletes, in the order they were performed
      * </ol>
      */
     protected void performExecutions(EventSource session) throws HibernateException {
 
         log.trace("executing flush");
 
         try {
             // we need to lock the collection caches before
 // executing entity inserts/updates in order to
 // account for bidi associations
 session.getActionQueue().prepareActions();
             session.getActionQueue().executeActions();
         }
         catch (HibernateException he) {
             log.error("Could not synchronize database state with session", he);
             throw he;         }
     }
  大家请注意加粗的部分,也就是说在hibernate里面,这个日志等级就被定义为ERROR并且强行记录了,那怎么办呢?
难道非要修改log4j.properties设置一个子日志对这个hibernate包的日志级别设置为FATAL?这样的确不会记录了,但是我认为是无法被老大认可的。或者是所有delete之前先判断有没有被其他资源引用?这样开销太大了吧不知道大家有没有什么好的思路

解决方案 »

  1.   

    难道非要修改log4j.properties设置一个子日志对这个hibernate包的日志级别设置为FATAL?这样的确不会记录了,但是我认为是无法被老大认可的。 修改log4j将这个类的日志专门输出到一个文件中可不可以?
    要不直接修改源码重新打包也是一种办法。这是第三方类库的问题,你们老大不认可又能怎么样?
    把你的调查结果整理成一份报告交给老大,提出你的建议,从你的角度来讲已经仁至义尽,决策让老大来拿。