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

 

知识准备 1
所有Entity实体在其hbm.xml配置文件中都必须设置Id元素或composite-id元素,不然hbm.xml文件会报错
因此,任何情况下Entity都拥有 IdentifierGenerator对象,即关键列生成策略。
< id  name = "id"   type = "string" >
     < column  name = "id" ></ column >
     < generator  class  = "guid" ></ generator >
</ id >
 
知识准备 2
protected  Serializable saveWithGeneratedId(
           Object entity,
           String entityName,
           Object anything,
           EventSource source,
             boolean  requiresImmediateIdAccess) {
     EntityPersister persister = source.getEntityPersister( entityName, entity );
     Serializable generatedId = persister.getIdentifierGenerator().generate( source, entity );
      if  ( generatedId ==  null  ) {
             throw  new  IdentifierGenerationException(  "null id generated for:"  + entity.getClass() );
     }
      else  if  ( generatedId == IdentifierGeneratorHelper.SHORT_CIRCUIT_INDICATOR ) { 
             return  source.getIdentifier( entity );
     }
      else  if  ( generatedId == IdentifierGeneratorHelper.POST_INSERT_INDICATOR ) {
             return  performSave( entity,  null , persister,  true , anything, source, requiresImmediateIdAccess );
     }
      else  {
             //  TODO : define toString()s for generators
             if  LOG.isDebugEnabled() ) {
                 LOG.debugf(
                             "Generated identifier: %s, using strategy: %s" ,
                          persister.getIdentifierType().toLoggableString( generatedId, source.getFactory() ),
                          persister.getIdentifierGenerator().getClass().getName()
                );
           }
 
             return  performSave( entity, generatedId, persister,  false , anything, source,  true  );
     }
}
 
generatedId 为null:说明hbm.xml没有配置id/composite-id列,直接抛出异常。
generatedId 为  SHORT_CIRCUIT_INDICATOR: 目前只有 ForeignGenerator使用该类型。
generatedId 为  POST_INSERT_INDICATOR : 拥有 SequenceGenerator、 IdentityGenerator、 SelectGenerator等三个, POST_INSERT_INDICATOR useIdentityColumn为true,
                                      即会选择 EntityIdentityInsertAction。
generatedId 为其他的:如Assigned、 GUIDGenerator 等,将 useIdentityColumn为true,即会选择 EntityInsertAction。
 
知识准备 3
org.hibernate.event.internal. AbstractSaveEventListener 
  //所有子类都不会覆盖该方法、所以判断是否延迟执行数据库的逻辑封装在这里
protected   Serializable performSaveOrReplicate
       Object entity,
       EntityKey key,
       EntityPersister persister,
        boolean   useIdentityColumn,
       Object anything,
       EventSource source,
        boolean   requiresImmediateIdAccess) {
     boolean   inTxn = source.getTransactionCoordinator().isTransactionInProgress();
     boolean   shouldDelayIdentityInserts = !inTxn && !requiresImmediateIdAccess;
 
   AbstractEntityInsertAction insert = addInsertAction(
       values, id, entity, persister, useIdentityColumn, source, shouldDelayIdentityInserts
   );
}
 
AbstractSaveEventListener 是  DefaultSaveOrUpdateEventListener、 DefaultSaveEventListener、
DefaultUpdateEventListener、 DefaultPersistEventListener、
DefaultMergeEventListener、 DefaultReplicateEventListener 的直接或间接父类。
所有子类都不会覆盖该方法、所以判断是否延迟执行数据库的逻辑封装在这里。
 
useIdentityColumn:关系到这两者 EntityIdentityInsertAction和 EntityInsertAction之间的 选择。 EntityIdentityInsertAction的isEarlyInsert()方法
                   根据 inTxn和 requiresImmediateIdAccess决定取值; EntityInsertAction的 isEarlyInsert()方法永远返回false。返回false表示不立即
                   到数据库执行Insert Sql操作。
 
shouldDelayIdentityInserts:是否延迟进行操作数据库,只会影响 EntityIdentityInsertAction的isEarlyInsert方法,不会 影响到 EntityInsertAction,
                            因为 isEarlyInsert方法永远返回false。
 
 
知识准备 4
 
EntityIdentityInsertAction:对应由数据库生成关键字值id的insert操作。有可能立即执行,不需要等到flush或commit时。
EntityInsertAction:对应由程序生成关键字的Insert操作,没机会立即执行。需等到flush或commit时,才执行。
EntityUpdateAction:对应update操作。
EntityDeleteAction:对应delete操作。
 
知识准备 5
/**
 * Represents the status of an entity with respect to  this session. These statuses are for internal
 * book  - keeping only and are not intended to represent  any notion that is visible to the _application_.
 */
public   enum   Status {
       MANAGED ,
       READ_ONLY ,
       DELETED ,
       GONE ,
       LOADING ,
       SAVING
}
 
MANAGED和 READ_ONLY: update时,将游离态对象转换为持久态时,需要将该Entity创建一个EntityEntry对象,并将其放入StatefulPersistenceContext中。
                    这时,将EntityEntry的Status标识为 MANAGED和 READ_ONLY。如果hbm中class的 属性 mutable设置true(默认为true,可变),则为
                     MANAGED,否则为 READ_ONLY。
DELETED: delete时,首先把 EntityDeleteAction放入ActionQueue队列,但未执行,并 将该Entity对应的EntityEntry的Status标识为DELETED。
         表示已标示为删除,但未真正执行操作。
GONE:当flush和commit时,EntityDeleteAction真正得到执行,当执行完之后,将 EntityEntry的Status标识为GONE。
SAVING:执行保存操作时,需要为Entity在 StatefulPersistenceContext中创建一个EntityEntry,并将其Status标识为 SAVING。
LOADING: 数据Load时的标识。
 
知识准备 6
瞬时态、游离态、持久态、删除态的判断逻辑:
1)如果Entity在 StatefulPersistenceContext中存在相应的EntityEntry对象,且EntityEntry的Status为DELETED,那么判断为删除态(DELETED);
2)如果Entity在 StatefulPersistenceContext中存在相应的EntityEntry对象,且EntityEntry的Status不为DELETED,那么判断为持久态(PERSISTENT);
3)如果Entity在 StatefulPersistenceContext中不存在相应的EntityEntry对象,如果Entity关键字值为null或与hbm文件中id元素配置的unsaved-value
   相等,那么判断为 瞬时 (TRANSIANT);
4)如果Entity在 StatefulPersistenceContext中 不存在 相应的EntityEntry对象,除3)外,否则判断为 游离态 (DETACHED)。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值