private DirtyCheckAttributeInfoImpl(FlushEntityEvent event) { this.event = event; this.descriptor = event.getEntityEntry().getDescriptor(); this.numberOfAttributes = descriptor.getPropertyNames().length; }
@Override public Object proxyFor(Object impl) throws HibernateException { final EntityEntry e = getEntry( impl ); if ( e == null ) { return impl; } return proxyFor( e.getDescriptor(), e.getEntityKey(), impl ); }
/** * process cascade save/update at the start of a flush to discover * any newly referenced entity that must be passed to saveOrUpdate(), * and also apply orphan delete */ private void prepareEntityFlushes(EventSource session, PersistenceContext persistenceContext) throws HibernateException { LOG.debug( "Processing flush-time cascades" ); final Object anything = getAnything(); //safe from concurrent modification because of how concurrentEntries() is implemented on IdentityMap for ( Map.Entry<Object,EntityEntry> me : persistenceContext.reentrantSafeEntityEntries() ) { // for ( Map.Entry me : IdentityMap.concurrentEntries( persistenceContext.getEntityEntries() ) ) { EntityEntry entry = (EntityEntry) me.getValue(); Status status = entry.getStatus(); if ( status == Status.MANAGED || status == Status.SAVING || status == Status.READ_ONLY ) { cascadeOnFlush( session, entry.getDescriptor(), me.getKey(), anything ); } } }
/** * Perform whatever processing is encapsulated here before completion of the transaction. * * @param session The session on which the transaction is preparing to complete. */ @Override public void doBeforeTransactionCompletion(SessionImplementor session) { final EntityTypeDescriptor entityDescriptor = entry.getDescriptor(); final Object nextVersion = entityDescriptor.forceVersionIncrement( entry.getId(), entry.getVersion(), session ); entry.forceLocked( object, nextVersion ); } }
private boolean canClearEntityEntryReference(){ if( managedEntity.$$_hibernate_getEntityEntry() == null ) { return true; } if( !(managedEntity.$$_hibernate_getEntityEntry() instanceof ImmutableEntityEntry) ) { return true; } else if( managedEntity.$$_hibernate_getEntityEntry().getDescriptor().canUseReferenceCacheEntries() ) { return false; } return true; } }
@Override public void replaceDelayedEntityIdentityInsertKeys(EntityKey oldKey, Object generatedId) { final Object entity = entitiesByKey.remove( oldKey ); final EntityEntry oldEntry = entityEntryContext.removeEntityEntry( entity ); parentsByChild.clear(); final EntityKey newKey = session.generateEntityKey( generatedId, oldEntry.getDescriptor() ); addEntity( newKey, entity ); addEntry( entity, oldEntry.getStatus(), oldEntry.getLoadedState(), oldEntry.getRowId(), generatedId, oldEntry.getVersion(), oldEntry.getLockMode(), oldEntry.isExistsInDatabase(), oldEntry.getDescriptor(), oldEntry.isBeingReplicated() ); }
@Override public void forceFlush(EntityEntry entityEntry) throws HibernateException { if ( log.isDebugEnabled() ) { log.debugf( "Flushing to force deletion of re-saved object: %s", MessageHelper.infoString( entityEntry.getDescriptor(), entityEntry.getId(), getFactory() ) ); } if ( persistenceContext.getCascadeLevel() > 0 ) { throw new ObjectDeletedException( "deleted object would be re-saved by cascade (remove deleted object from associations)", entityEntry.getId(), entityEntry.getDescriptor().getEntityName() ); } checkOpenOrWaitingForAutoClose(); doFlush(); }
@Override public void doBeforeTransactionCompletion(SessionImplementor session) { final EntityTypeDescriptor entityDescriptor = entry.getDescriptor(); if ( !entry.isExistsInDatabase() ) { // HHH-9419: We cannot check for a version of an entry we ourselves deleted return; } final Object latestVersion = entityDescriptor.getCurrentVersion( entry.getId(), session ); if ( !entry.getVersion().equals( latestVersion ) ) { throw new OptimisticLockException( object, "Newer version [" + latestVersion + "] of entity [" + MessageHelper.infoString( entry.getEntityName(), entry.getId() ) + "] found in database" ); } } }
protected boolean handleInterception(FlushEntityEvent event) { SessionImplementor session = event.getSession(); EntityEntry entry = event.getEntityEntry(); EntityTypeDescriptor entityDescriptor = entry.getDescriptor(); 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, entityDescriptor ); //now we might need to recalculate the dirtyProperties array if ( intercepted && event.isDirtyCheckPossible() ) { dirtyCheck( event ); } return intercepted; }
/** * 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 { EntityTypeDescriptor entityDescriptor = event.getEntityEntry().getDescriptor(); 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, entityDescriptor, status ); } } }
private Object[] getValues(Object entity, EntityEntry entry, boolean mightBeDirty, SessionImplementor session) { final Object[] loadedState = entry.getLoadedState(); final Status status = entry.getStatus(); final EntityTypeDescriptor descriptor = entry.getDescriptor(); final Object[] values; if ( status == Status.DELETED ) { //grab its state saved at deletion values = entry.getDeletedState(); } else if ( !mightBeDirty && loadedState != null ) { values = loadedState; } else { checkId( entity, descriptor, entry.getId(), session ); // grab its current state values = descriptor.getPropertyValues( entity ); checkNaturalId( descriptor, entry, values, loadedState, session ); } return values; }
@Override public String bestGuessEntityName(Object object) { if ( object instanceof HibernateProxy ) { LazyInitializer initializer = ( (HibernateProxy) object ).getHibernateLazyInitializer(); // it is possible for this method to be called during flush processing, // so make certain that we do not accidentally initialize an uninitialized proxy if ( initializer.isUninitialized() ) { return initializer.getEntityName(); } object = initializer.getImplementation(); } EntityEntry entry = persistenceContext.getEntry( object ); if ( entry == null ) { return guessEntityName( object ); } else { return entry.getDescriptor().getEntityName(); } }
private boolean isUpdateNecessary(final FlushEntityEvent event, final boolean mightBeDirty) { final Status status = event.getEntityEntry().getStatus(); if ( mightBeDirty || status == Status.DELETED ) { // compare to cached state (ignoring collections unless versioned) dirtyCheck( event ); if ( isUpdateNecessary( event ) ) { return true; } else { if ( SelfDirtinessTracker.class.isInstance( event.getEntity() ) ) { ( (SelfDirtinessTracker) event.getEntity() ).$$_hibernate_clearDirtyAttributes(); } event.getSession() .getFactory() .getCustomEntityDirtinessStrategy() .resetDirty( event.getEntity(), event.getEntityEntry().getDescriptor(), event.getSession() ); return false; } } else { return hasDirtyCollections( event, event.getEntityEntry().getDescriptor(), status ); } }
@Override public String getEntityName(Object object) { checkOpen(); // checkTransactionSynchStatus(); if ( object instanceof HibernateProxy ) { if ( !persistenceContext.containsProxy( object ) ) { throw new TransientObjectException( "proxy was not associated with the session" ); } object = ( (HibernateProxy) object ).getHibernateLazyInitializer().getImplementation(); } EntityEntry entry = persistenceContext.getEntry( object ); if ( entry == null ) { throwTransientObjectException( object ); } return entry.getDescriptor().getEntityName(); }
@Override public void lock(Serializable id, Object version, Object object, int timeout, SharedSessionContractImplementor session) { if ( StringHelper.isEmpty( lockable.getVersionColumnName() ) ) { throw new HibernateException( "[" + lockMode + "] not supported for non-versioned entities [" + lockable.getEntityName() + "]" ); } final EntityEntry entry = session.getPersistenceContext().getEntry( object ); final Object nextVersion = entry.getDescriptor().forceVersionIncrement( entry.getId(), entry.getVersion(), session ); entry.forceLocked( object, nextVersion ); }
@Override public LockMode getCurrentLockMode(Object object) throws HibernateException { checkOpen(); checkTransactionSynchStatus(); if ( object == null ) { throw new NullPointerException( "null object passed to getCurrentLockMode()" ); } if ( object instanceof HibernateProxy ) { object = ( (HibernateProxy) object ).getHibernateLazyInitializer().getImplementation( this ); if ( object == null ) { return LockMode.NONE; } } EntityEntry e = persistenceContext.getEntry( object ); if ( e == null ) { throw new TransientObjectException( "Given object not associated with the session" ); } if ( e.getStatus() != Status.MANAGED ) { throw new ObjectDeletedException( "The given object was deleted", e.getId(), e.getDescriptor().getEntityName() ); } return e.getLockMode(); }
/** * PostLoad cannot occur during initializeEntity, as that call occurs *before* * the Set collections are added to the persistence context by Loader. * Without the split, LazyInitializationExceptions can occur in the Entity's * postLoad if it acts upon the collection. * * HHH-6043 * * @param entity The entity * @param session The Session * @param postLoadEvent The (re-used) post-load event */ public static void postLoad( final Object entity, final SharedSessionContractImplementor session, final PostLoadEvent postLoadEvent) { if ( session.isEventSource() ) { final PersistenceContext persistenceContext = session.getPersistenceContext(); final EntityEntry entityEntry = persistenceContext.getEntry( entity ); postLoadEvent.setEntity( entity ).setId( entityEntry.getId() ).setDescriptor( entityEntry.getDescriptor() ); final EventListenerGroup<PostLoadEventListener> listenerGroup = session.getFactory() .getServiceRegistry() .getService( EventListenerRegistry.class ) .getEventListenerGroup( EventType.POST_LOAD ); for ( PostLoadEventListener listener : listenerGroup.listeners() ) { listener.onPostLoad( postLoadEvent ); } } }
final EntityEntry entry = event.getEntityEntry(); final EventSource session = event.getSession(); final EntityTypeDescriptor entityDescriptor = entry.getDescriptor(); final Status status = entry.getStatus(); final List persistentAttributes = entityDescriptor.getPersistentAttributes();
final EntityTypeDescriptor entityDescriptor = entry.getDescriptor(); final VersionDescriptor versionDescriptor = entityDescriptor.getHierarchy().getVersionDescriptor();
final EntityTypeDescriptor descriptor = entry.getDescriptor(); final Object nextVersion = descriptor.forceVersionIncrement( entry.getId(),