Hibernate 专题研究系列(一) save/update/saveOrUpdate等方法学习(续三)

 

7、Delete
1) 返回值
   void
 
2)事件监听处理类及重要代码
    DefaultDeleteEventListener
  public   void   onDelete(DeleteEvent event, Set transientEntities)   throws   HibernateException {
     EntityEntry entityEntry = persistenceContext.getEntry( entity );
      if   ( entityEntry ==   null   ) {
            persister = source .getEntityPersister( event.getEntityName(), entity );
 
              if   ( ForeignKeys.isTransient( persister.getEntityName(), entity,   null , source ) ) {
                deleteTransientEntity( source, entity , event.isCascadeDeleteEnabled(), persister, transientEntities );
                   // EARLY EXIT!!!
                   return ;
           }
            performDetachedEntityDeletionCheck( event );
 
           entityEntry = persistenceContext.addEntity(
                      entity,
                     ( persister.isMutable() ? Status.MANAGED : Status.READ_ONLY),
                      persister.getPropertyValues( entity ),
                      key,
                      version,
                     LockMode.NONE,
                        true ,
                      persister,
                        false ,
                        false
           );
     }
      else   {
              if   ( entityEntry.getStatus() == Status.DELETED || entityEntry.getStatus() == Status.GONE ) {
                   return ;
           }
            persister = entityEntry.getPersister();
            id = entityEntry.getId();
            version = entityEntry.getVersion();
     }
 
     deleteEntity(
                 source,
                 entity,
                entityEntry,
                event.isCascadeDeleteEnabled(),
                event.isOrphanRemovalBeforeUpdates(),
                 persister,
                transientEntities
     );
   }   
 
3)事务范围外的处理方式
   如果在事务范围外,delete不会得到执行;delete操作,只是把EntityDeleteAction加入到ActionQueue中的deletions队列中,detetions实际上是一个ArrayList;直到flush时才会执行。
   当然当实体是持久态/游离态时,才会将 EntityDeleteAction加入到ActionQueue队列中。
 
4)瞬时态
   可以删除一个瞬时态的实体,处理过程是将瞬时对象加入瞬时对象列表中,然后执行相关级联操作。处理程序不会对瞬时对象在StatefulPersistenceContext中做任何处理。完成删除操作时,
   实体状态仍旧 是瞬时态。
 
5) 游离态
   如果在 StatefulPersistenceContext找不到实体对应的EntityEntry,且实体的关键列值为null或与unsaved-value相等,则认为该实体为游离态,则作为游离态对象进行处理。
   创建对象EntityEntry加入StatefulPersistenceContext中,并将 EntityDeleteAction加入到ActionQueue队列中。将实体状态标识为DELETED状态。直到commit前,实体一直是DELETED状态,
   事务提交后,将会变成DETACHED (游离) 状态。
 
6) 持久态
    如果在 StatefulPersistenceContext找得到实体对应的EntityEntry,且实体的状态不为DELETED或GONE状态,则认为是持久态,进行持久态对象处理过程。
   将 EntityDeleteAction加入到ActionQueue队列中。将实体状态标识为DELETED状态。直到commit前,实体一直是DELETED状态, 事务提交后,将会变成DETACHED (游离) 状态。
 
7)总结
 
8、Flush
1) 返回值
   void
 
2)事件监听处理类及重要代码
    DefaultFlushEventListener
public   void   onFlush(FlushEvent event)   throws   HibernateException {
      final   EventSource source = event.getSession();
      final   PersistenceContext persistenceContext = source.getPersistenceContext();
 
      if   ( persistenceContext.getNumberOfManagedEntities() > 0 ||
                persistenceContext.getCollectionEntries().size() > 0 ) {
 
              try   {
                source.getEventListenerManager().flushStart();
 
                 flushEverythingToExecutions( event ); // 将entities和collections的相应动作加入ActionQueue中
                 performExecutions( source ); // 然后执行ActionQueue所有的Actions
                 postFlush( source );
           }
              finally   {
                source.getEventListenerManager().flushEnd(
                           event.getNumberOfEntitiesProcessed(),
                          event.getNumberOfCollectionsProcessed()
                );
           }
 
            postPostFlush( source );
 
              if   ( source.getFactory().getStatistics().isStatisticsEnabled() ) {
                source.getFactory().getStatisticsImplementor().flush();
           }
     }
}
 
ActionQueue
private   <E   extends   Executable & Comparable<?> & Serializable>   void   executeActions(ExecutableList<E> list)   throws   HibernateException {
      // todo : consider ways to improve the double iteration of Executables here:
      //         1) we explicitly iterate list here to perform Executable#execute()
      //         2) ExecutableList#getQuerySpaces also iterates the Executables to collect query spaces.
      try   {
              for   ( E e : list ) {
                   try   {
                     e.execute();
                }
                   finally   {
                      beforeTransactionProcesses.register( e.getBeforeTransactionCompletionProcess() );
                      afterTransactionProcesses.register( e.getAfterTransactionCompletionProcess() );
                }
           }
     }
      finally   {
              if   ( session.getFactory().getSettings().isQueryCacheEnabled() ) {
                   // Strictly speaking, only a subset of the list may have been processed if a RuntimeException occurs.
                   // We still invalidate all spaces. I don't see this as a big deal - after all, RuntimeExceptions are
                   // unexpected.
                Set<Serializable> propertySpaces = list.getQuerySpaces();
                 invalidateSpaces( propertySpaces.toArray(   new   Serializable[propertySpaces.size()] ) );
           }
     }
 
     list.clear();
     session.getTransactionCoordinator().getJdbcCoordinator().executeBatch();
}
 
3)事务范围外的处理方式
3.1) 设置connection为自动提交
假如,没有显式地创建一个事务并开启,然后对一个游离态对象进行delete操作,即该操作不在事务范围内,如果不执行flush操作,delete动作不会得到执行; 如果执行flush操作,
由于事务为自动提交,delete操作的delete sql将执行并提交至数据库。没有显式事务同样可以提交 数据 更新 ,不只是save,还有delete、update、persist、merge操作。
3.2)设置connection为非自动提交
假如, 没有显式地创建一个事务并开启,然后对一个游离态对象进行delete操作,即该操作不在事务范围内,如果不执行flush操作,delete动作不会得到执行; 如果执行flush操作,
由于事务为手动提交,delete操作的delete sql将执行但事务得不到提交。
3.3)flush的作用
除了DefaultSaveOrUpdateEventListener中个别的情况外,其他的操作如update、persist、merge、delete等,只是将相应的Action加入到ActionQueue各自的队列中,并不会立即执行
相应的 数据库操作。这里说的 DefaultSaveOrUpdateEventListener中个别情况是指,save 操作在有些情况下不是将Action加入到ActionQueue中,而是直接执行Insert sql 操作并更新至
据库中。所以,一般情况下,只有等到flush时, Actions 才会得到执行。flush的作用就是执行ActionQueue中的各种Action。
3.4)flush与commit的区别
3.4.1)commit包含flush操作,但处理的东西比flush多;commit还要执行关闭当前事务,开启新事务的工作。一旦当前事务提交,该事务就结束了,就不可再用了。
3.4.2)flush操作只是执行ActionQueue中的Action,执行完Action之后,将对ActionQueue进行清空避免同一操作多次被执行。
3.4.3)flush操作在显式地事务范围内时,可以执行多次,对事务本身没有影响,当前事务不会关闭,还处于活跃中;只是执行并清空的ActionQueue队列中的Action。
3.4.4)就算没有显式的事务,flush操作同样可以更新数据库,只要Connection. setAutoCommit (true);
3.4.5)没有Transaction,就没有commit方法;但没有Transaction,可以执行flush方法。
 
4)瞬时态
 
5)持久态
 
6)游离态

 

你可能感兴趣的:(Hibernate 专题研究系列(一) save/update/saveOrUpdate等方法学习(续三))