📄 defaultflushentityeventlistener.java
字号:
} // check nullability but do not perform command execute // we'll use scheduled updates for that. new Nullability(session).checkNullability( values, persister, true ); // schedule the update // note that we intentionally do _not_ pass in currentPersistentState! session.getActionQueue().addAction( new EntityUpdateAction( entry.getId(), values, dirtyProperties, event.hasDirtyCollection(), entry.getLoadedState(), entry.getVersion(), nextVersion, entity, entry.getRowId(), persister, session ) ); return intercepted; } protected void validate(Object entity, EntityPersister persister, Status status, EntityMode entityMode) { // validate() instances of Validatable if ( status == Status.MANAGED && persister.implementsValidatable( entityMode ) ) { ( (Validatable) entity ).validate(); } } protected boolean handleInterception(FlushEntityEvent event) { SessionImplementor session = event.getSession(); EntityEntry entry = event.getEntityEntry(); EntityPersister persister = entry.getPersister(); Object entity = event.getEntity(); //give the Interceptor a chance to modify property values final Object[] values = event.getPropertyValues(); final boolean intercepted = invokeInterceptor( session, entity, entry, values, persister ); //now we might need to recalculate the dirtyProperties array if ( intercepted && event.isDirtyCheckPossible() && !event.isDirtyCheckHandledByInterceptor() ) { int[] dirtyProperties; if ( event.hasDatabaseSnapshot() ) { dirtyProperties = persister.findModified( event.getDatabaseSnapshot(), values, entity, session ); } else { dirtyProperties = persister.findDirty( values, entry.getLoadedState(), entity, session ); } event.setDirtyProperties(dirtyProperties); } return intercepted; } protected boolean invokeInterceptor( SessionImplementor session, Object entity, EntityEntry entry, final Object[] values, EntityPersister persister) { return session.getInterceptor().onFlushDirty( entity, entry.getId(), values, entry.getLoadedState(), persister.getPropertyNames(), persister.getPropertyTypes() ); } /** * Convience method to retreive an entities next version value */ private Object getNextVersion(FlushEntityEvent event) throws HibernateException { EntityEntry entry = event.getEntityEntry(); EntityPersister persister = entry.getPersister(); if ( persister.isVersioned() ) { Object[] values = event.getPropertyValues(); if ( entry.isBeingReplicated() ) { return Versioning.getVersion(values, persister); } else { int[] dirtyProperties = event.getDirtyProperties(); final boolean isVersionIncrementRequired = isVersionIncrementRequired( event, entry, persister, dirtyProperties ); final Object nextVersion = isVersionIncrementRequired ? Versioning.increment( entry.getVersion(), persister.getVersionType(), event.getSession() ) : entry.getVersion(); //use the current version Versioning.setVersion(values, nextVersion, persister); return nextVersion; } } else { return null; } } private boolean isVersionIncrementRequired( FlushEntityEvent event, EntityEntry entry, EntityPersister persister, int[] dirtyProperties ) { final boolean isVersionIncrementRequired = entry.getStatus()!=Status.DELETED && ( dirtyProperties==null || Versioning.isVersionIncrementRequired( dirtyProperties, event.hasDirtyCollection(), persister.getPropertyVersionability() ) ); return isVersionIncrementRequired; } /** * Performs all necessary checking to determine if an entity needs an SQL update * to synchronize its state to the database. Modifies the event by side-effect! * Note: this method is quite slow, avoid calling if possible! */ protected final boolean isUpdateNecessary(FlushEntityEvent event) throws HibernateException { EntityPersister persister = event.getEntityEntry().getPersister(); Status status = event.getEntityEntry().getStatus(); if ( !event.isDirtyCheckPossible() ) { return true; } else { int[] dirtyProperties = event.getDirtyProperties(); if ( dirtyProperties!=null && dirtyProperties.length!=0 ) { return true; //TODO: suck into event class } else { return hasDirtyCollections( event, persister, status ); } } } private boolean hasDirtyCollections(FlushEntityEvent event, EntityPersister persister, Status status) { if ( isCollectionDirtyCheckNecessary(persister, status) ) { DirtyCollectionSearchVisitor visitor = new DirtyCollectionSearchVisitor( event.getSession(), persister.getPropertyVersionability() ); visitor.processEntityPropertyValues( event.getPropertyValues(), persister.getPropertyTypes() ); boolean hasDirtyCollections = visitor.wasDirtyCollectionFound(); event.setHasDirtyCollection(hasDirtyCollections); return hasDirtyCollections; } else { return false; } } private boolean isCollectionDirtyCheckNecessary(EntityPersister persister, Status status) { return status==Status.MANAGED && persister.isVersioned() && persister.hasCollections(); } /** * Perform a dirty check, and attach the results to the event */ protected void dirtyCheck(FlushEntityEvent event) throws HibernateException { final Object entity = event.getEntity(); final Object[] values = event.getPropertyValues(); final SessionImplementor session = event.getSession(); final EntityEntry entry = event.getEntityEntry(); final EntityPersister persister = entry.getPersister(); final Serializable id = entry.getId(); final Object[] loadedState = entry.getLoadedState(); int[] dirtyProperties = session.getInterceptor().findDirty( entity, id, values, loadedState, persister.getPropertyNames(), persister.getPropertyTypes() ); event.setDatabaseSnapshot(null); final boolean interceptorHandledDirtyCheck; boolean cannotDirtyCheck; if ( dirtyProperties==null ) { // Interceptor returned null, so do the dirtycheck ourself, if possible interceptorHandledDirtyCheck = false; cannotDirtyCheck = loadedState==null; // object loaded by update() if ( !cannotDirtyCheck ) { // dirty check against the usual snapshot of the entity dirtyProperties = persister.findDirty( values, loadedState, entity, session ); } else { // dirty check against the database snapshot, if possible/necessary final Object[] databaseSnapshot = getDatabaseSnapshot(session, persister, id); if ( databaseSnapshot != null ) { dirtyProperties = persister.findModified(databaseSnapshot, values, entity, session); cannotDirtyCheck = false; event.setDatabaseSnapshot(databaseSnapshot); } } } else { // the Interceptor handled the dirty checking cannotDirtyCheck = false; interceptorHandledDirtyCheck = true; } event.setDirtyProperties(dirtyProperties); event.setDirtyCheckHandledByInterceptor(interceptorHandledDirtyCheck); event.setDirtyCheckPossible(!cannotDirtyCheck); } private Object[] getDatabaseSnapshot(SessionImplementor session, EntityPersister persister, Serializable id) { if ( persister.isSelectBeforeUpdateRequired() ) { Object[] snapshot = session.getPersistenceContext() .getDatabaseSnapshot(id, persister); if (snapshot==null) { //do we even really need this? the update will fail anyway.... if ( session.getFactory().getStatistics().isStatisticsEnabled() ) { session.getFactory().getStatisticsImplementor() .optimisticFailure( persister.getEntityName() ); } throw new StaleObjectStateException( persister.getEntityName(), id ); } else { return snapshot; } } else { //TODO: optimize away this lookup for entities w/o unsaved-value="undefined" EntityKey entityKey = new EntityKey( id, persister, session.getEntityMode() ); return session.getPersistenceContext() .getCachedDatabaseSnapshot( entityKey ); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -