📄 defaultflushentityeventlistener.java
字号:
session.getActionQueue().addAction(
new EntityUpdateAction(
entry.getId(),
values,
dirtyProperties,
event.hasDirtyCollection(),
entry.getLoadedState(),
entry.getVersion(),
nextVersion,
entity,
entry.getRowId(),
persister,
session
)
);
return substitute;
}
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
) {
final boolean intercepted = session.getInterceptor().onFlushDirty(
entity,
entry.getId(),
values,
entry.getLoadedState(),
persister.getPropertyNames(),
persister.getPropertyTypes()
);
return intercepted;
}
/**
* 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 + -