以前以为hibernate是通过id来却分对象的状态的,分析源码才发现是通过状态标识的,hibernate会自动为你的对象添加一个状态标识,具体如下:
不管是save,update还是saveOrUpdate,hibernate都会调用
DefaultSaveOrUpdateEventListener类的onSaveOrUpdate(......)方法,代码如下:
- protected static final int PERSISTENT = 0;
- protected static final int TRANSIENT = 1;
- protected static final int DETACHED = 2;
- protected static final int DELETED = 3;
- switch ( entityState ) {
- case DETACHED:
- entityIsDetached( event );
- return null;
- case PERSISTENT:
- return entityIsPersistent( event );
- default: //TRANSIENT or DELETED
- return entityIsTransient( event );
- }
- SaveOrUpdateEventListener是个接口,实现类为DefaultSaveOrUpdateEventListener
- public void onSaveOrUpdate(SaveOrUpdateEvent event) {
- final SessionImplementor source = event.getSession();
- final Object object = event.getObject();//在这里object已经携带有信息了,只不过id还是为0
- final Serializable requestedId = event.getRequestedId();//这里都为null.这个只有调用save(Obj,id)才有值.
- if ( requestedId != null ) {
- //assign the requested id to the proxy, *before*
- //reassociating the proxy
- if ( object instanceof HibernateProxy ) {
- ( ( HibernateProxy ) object ).getHibernateLazyInitializer().setIdentifier( requestedId );
- }
- }
- if ( reassociateIfUninitializedProxy( object, source ) ) {//执行2次,这里都为false
- log.trace( "reassociated uninitialized proxy" );
- // an uninitialized proxy, noop, don't even need to
- // return an id, since it is never a save()
- }
- else {
- //initialize properties of the event:初始化属性,把
- final Object entity = source.getPersistenceContext().unproxyAndReassociate( object );
- event.setEntity( entity );
- event.setEntry( source.getPersistenceContext().getEntry( entity ) );//从session中拿出obj相关的entityentry,这个对象持有po当前的状态
- //return the id in the event object
- event.setResultId( performSaveOrUpdate( event ) );//执行完这句后,还会再次执行onSaveOrUpdate()方法,这时,event.getObject返回的Object 的id已经有值了
- }
- }
以下代码中hibernate会从session中读取对象的快照,如果没有,对象的状态就是
TRANSIENT
- DefaultSaveEventListener类,继承自DefaultSaveOrUpdateEventListener
- protected Serializable performSaveOrUpdate(SaveOrUpdateEvent event) {
- // this implementation is supposed to tolerate incorrect unsaved-value
- // mappings, for the purpose of backward-compatibility
- EntityEntry entry = event.getSession().getPersistenceContext().getEntry( event.getEntity() );
- //第一次执行到这里entry为null,第二次这里还是null
- if ( entry!=null && entry.getStatus() != Status.DELETED ) {
- //如果在obj在session已经有对应的entityentry,即obj已经是po,且状态是DELETED,那么执行delete操作
- return entityIsPersistent(event);
- }
- else {
- return entityIsTransient(event);
- }
- }