文章不断更新中
每次的修改将以颜色标识,有疑问的地方以此色标识
第一次注释
1.SessionImpl.saveOrUpdate
public void saveOrUpdate(Object obj) throws HibernateException {
if (obj==null) throw new NullPointerException("attempted to update null");//如果对象为空,则抛出异常
if ( reassociateIfUninitializedProxy(obj) ) return;
Object object = unproxyAndReassociate(obj); //a proxy is always "update", never "save"
EntityEntry e = getEntry(object);//从session中拿出obj相关的entityentry,这个对象持有po当前的状态
if (e!=null && e.status!=DELETED) {
// do nothing for persistent instances
log.trace("saveOrUpdate() persistent instance");
}
else if (e!=null) { //ie. e.status==DELETED
log.trace("saveOrUpdate() deleted instance");
save(obj);
}
else {
// the object is transient
Boolean isUnsaved = interceptor.isUnsaved(object);//interceptor是可配置的,默认是Configratiron,返回null
ClassPersister persister = getPersister(object);//得到obj的Persister Class mapping信息
if (isUnsaved==null) {
// use unsaved-value
if ( persister.isUnsaved(object) ) //参考AbstractEntityPersister.isUnsaved,如果obj的identifier为空,则返回true,否则继续判断如果version property为空,则返回true,否则返回false
{
log.trace("saveOrUpdate() unsaved instance");
save(obj);
}
else {
Serializable id = persister.getIdentifier(object);
if ( log.isTraceEnabled() ) log.trace("saveOrUpdate() previously saved instance with id: " + id);
doUpdate(object, id, persister);
}
}
else {
if ( isUnsaved.booleanValue() ) {
log.trace("saveOrUpdate() unsaved instance");
save(obj);
}
else {
log.trace("saveOrUpdate() previously saved instance");
doUpdate( object, persister.getIdentifier(object), persister );
}
}
2.SessionImpl.save
public Serializable save(Object obj) throws HibernateException {
if (obj==null) throw new NullPointerException("attempted to save null");
Object object = unproxy(obj); //throws exception if uninitialized
EntityEntry e = getEntry(object);
if ( e!=null )//如果在session中已经存在po
{
if ( e.status==DELETED ) {//如果po的状态是DELETED,立刻对session进行flush
forceFlush(e);
}
else {
log.trace( "object already associated with session" );//返回po的id,什么事都不干
return e.id;
}
}
Serializable id = saveWithGeneratedIdentifier(object, Cascades.ACTION_SAVE_UPDATE, null); //id might be generated by SQL insert
reassociateProxy(obj, id); //TODO: move into saveWithGeneratedIdentifier()?
return id;
}
3.SessionImpl.saveWithGeneratedIdentifier
private Serializable saveWithGeneratedIdentifier(Object object, Cascades.CascadingAction action, Object anything)
throws HibernateException {
ClassPersister persister = getPersister(object);
try {
Serializable id = persister.getIdentifierGenerator()
.generate(this, object);//产生obj的identity,如果id是assigned,则直接返回obj的identity,如果是native,则根据底层数据库的特性产生id
if (id==null) {
throw new IdentifierGenerationException("null id generated for: " + object.getClass());
}
else if (id==IdentifierGeneratorFactory.SHORT_CIRCUIT_INDICATOR) {
return getIdentifier(object); //yick!
}
else if (id==IdentifierGeneratorFactory.IDENTITY_COLUMN_INDICATOR) {
return doSave(object, null, persister, true, action, anything);
}
else {
if ( log.isDebugEnabled() ) log.debug("generated identifier: " + id);
return doSave(object, id, persister, false, action, anything);
}
}
catch (SQLException sqle) {
throw new JDBCException("Could not save object", sqle);
}
}
4.SessionImpl.doSave
//hibernate在执行insert的时候,一般不会立刻执行insert sql,除非你用identity机制来产生id,否则insert sql将会在推迟到session.flush的时候才会执行,会先产生需要返回的id(利用sequence等机制,只要不是identity机制),然后将执行insert sql的计划放在insertions这个队列中,等flush的时候再执行insert sql,不过需要注意的是,在insert用indentity机制产生id的obj的时候,在插入obj之前,hibernate会把insertions队列中的insert sql全部执行,为什么需要这样做,未知。
private Serializable doSave(
final Object object,
Key key,
final ClassPersister persister,
final boolean replicate,
final boolean useIdentityColumn,
final Cascades.CascadingAction cascadeAction,
final Object anything)
throws HibernateException {
if ( persister.implementsValidatable() ) ( (Validatable) object ).validate();//验证obj的合法性
Serializable id;
if (useIdentityColumn) {//如果是用identity机制产生的id,那么将session insert队列的现有的insert sql全部执行,有什么必要吗?
id = null;
executeInserts();
}
else {
id = key.getIdentifier();
}
// Put a placeholder in entries, so we don't recurse back and try to save() the
// same object again. QUESTION: should this be done before onSave() is called?
// likewise, should it be done before onUpdate()?
addEntry(object, SAVING, null, id, null, LockMode.WRITE, useIdentityColumn, persister, false); //okay if id is null here
// cascade-save to many-to-one BEFORE the parent is saved //在处理儿子(从表数据)前,先把父亲(主表数据)处理一下
cascading++;
try {
Cascades.cascade(this, persister, object, cascadeAction, Cascades.CASCADE_BEFORE_INSERT_AFTER_DELETE, anything);
}
finally {
cascading--;
}
Object[] values = persister.getPropertyValues(object);
Type[] types = persister.getPropertyTypes();
boolean substitute = false;
if (!replicate) {
substitute = interceptor.onSave( object, id, values, persister.getPropertyNames(), types );
//keep the existing version number in the case of replicate!
if ( persister.isVersioned() ) {
substitute = Versioning.seedVersion(
values, persister.getVersionProperty(), persister.getVersionType()
) || substitute;
}
}
if ( persister.hasCollections() ) {
//TODO: make OnReplicateVisitor extend WrapVisitor
if (replicate) {
OnReplicateVisitor visitor = new OnReplicateVisitor(this, id);
visitor.processValues(values, types);
}
WrapVisitor visitor = new WrapVisitor(this);
// substitutes into values by side-effect
visitor.processValues(values, types);
substitute = substitute || visitor.isSubstitutionRequired();
}
if (substitute) persister.setPropertyValues(object, values);
TypeFactory.deepCopy(values, types, persister.getPropertyUpdateability(), values);
nullifyTransientReferences(values, types, useIdentityColumn, object);
checkNullability(values, persister, false);
if (useIdentityColumn) {//如果是用identity机制产生的id,那么不会等到flush,就会插入数据,因为要返回id,这个用identity机制产生的id只有执行insert才能生成。
ScheduledIdentityInsertion insert = new ScheduledIdentityInsertion(values, object, persister, this);
insert.execute();
executions.add(insert);
id = insert.getGeneratedId();
persister.setIdentifier(object, id);
key = new Key(id, persister);
checkUniqueness(key, object);
}
Object version = Versioning.getVersion(values, persister);
addEntity(key, object);
addEntry(object, LOADED, values, id, version, LockMode.WRITE, useIdentityColumn, persister, replicate);
nonExists.remove(key);
if (!useIdentityColumn) {
insertions.add( new ScheduledInsertion( id, values, object, persister, this ) );
}
// cascade-save to collections AFTER the collection owner was saved//父亲已经处理,这里将处理儿子
cascading++;
try {
Cascades.cascade(this, persister, object, cascadeAction, Cascades.CASCADE_AFTER_INSERT_BEFORE_DELETE, anything);
}
finally {
cascading--;
}
return id;
}