分享
 
 
 

Hibernate2.1.6 源码分析

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

文章不断更新中

每次的修改将以颜色标识,有疑问的地方以此色标识

第一次注释

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;

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有