知识准备 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)。