文章不断更新中 每次的修改将以颜色标识,有疑问的地方以此色标识 第一次注释
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;
}

|