Java 类org.hibernate.engine.spi.Status 实例源码

项目:lams    文件:TwoPhaseLoad.java   
/**
 * Add an uninitialized instance of an entity class, as a placeholder to ensure object
 * identity. Must be called before <tt>postHydrate()</tt>.
 *
 * Create a "temporary" entry for a newly instantiated entity. The entity is uninitialized,
 * but we need the mapping from id to instance in order to guarantee uniqueness.
 *
 * @param key The entity key
 * @param object The entity instance
 * @param persister The entity persister
 * @param lockMode The lock mode
 * @param lazyPropertiesAreUnFetched Are lazy properties still un-fetched?
 * @param session The Session
 */
public static void addUninitializedEntity(
        final EntityKey key,
        final Object object,
        final EntityPersister persister,
        final LockMode lockMode,
        final boolean lazyPropertiesAreUnFetched,
        final SessionImplementor session) {
    session.getPersistenceContext().addEntity(
            object,
            Status.LOADING,
            null,
            key,
            null,
            lockMode,
            true,
            persister,
            false,
            lazyPropertiesAreUnFetched
    );
}
项目:lams    文件:TwoPhaseLoad.java   
/**
 * Same as {@link #addUninitializedEntity}, but here for an entity from the second level cache
 *
 * @param key The entity key
 * @param object The entity instance
 * @param persister The entity persister
 * @param lockMode The lock mode
 * @param lazyPropertiesAreUnFetched Are lazy properties still un-fetched?
 * @param version The version
 * @param session The Session
 */
public static void addUninitializedCachedEntity(
        final EntityKey key,
        final Object object,
        final EntityPersister persister,
        final LockMode lockMode,
        final boolean lazyPropertiesAreUnFetched,
        final Object version,
        final SessionImplementor session) {
    session.getPersistenceContext().addEntity(
            object,
            Status.LOADING,
            null,
            key,
            version,
            lockMode,
            true,
            persister,
            false,
            lazyPropertiesAreUnFetched
        );
}
项目:lams    文件:SessionImpl.java   
@Override
public LockMode getCurrentLockMode(Object object) throws HibernateException {
    errorIfClosed();
    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.getPersister().getEntityName()
            );
    }
    return e.getLockMode();
}
项目:lams    文件:DefaultUpdateEventListener.java   
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() );
    if ( entry!=null ) {
        if ( entry.getStatus()== Status.DELETED ) {
            throw new ObjectDeletedException( "deleted instance passed to update()", null, event.getEntityName() );
        }
        else {
            return entityIsPersistent(event);
        }
    }
    else {
        entityIsDetached(event);
        return null;
    }
}
项目:lams    文件:DefaultFlushEntityEventListener.java   
private Object[] getValues(Object entity, EntityEntry entry, boolean mightBeDirty, SessionImplementor session) {
    final Object[] loadedState = entry.getLoadedState();
    final Status status = entry.getStatus();
    final EntityPersister persister = entry.getPersister();

    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, persister, entry.getId(), session );

        // grab its current state
        values = persister.getPropertyValues( entity );

        checkNaturalId( persister, entry, values, loadedState, session );
    }
    return values;
}
项目:lams    文件:DefaultFlushEntityEventListener.java   
/**
 * 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 );
        }

    }
}
项目:lams    文件:DefaultSaveOrUpdateEventListener.java   
/**
 * The given save-update event named a transient entity.
 * <p/>
 * Here, we will perform the save processing.
 *
 * @param event The save event to be handled.
 *
 * @return The entity's identifier after saving.
 */
protected Serializable entityIsTransient(SaveOrUpdateEvent event) {

    LOG.trace( "Saving transient instance" );

    final EventSource source = event.getSession();

    EntityEntry entityEntry = event.getEntry();
    if ( entityEntry != null ) {
        if ( entityEntry.getStatus() == Status.DELETED ) {
            source.forceFlush( entityEntry );
        }
        else {
            throw new AssertionFailure( "entity was persistent" );
        }
    }

    Serializable id = saveWithGeneratedOrRequestedId( event );

    source.getPersistenceContext().reassociateProxy( event.getObject(), id );

    return id;
}
项目:lams    文件:AbstractFlushingEventListener.java   
/**
     * 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.getPersister(), me.getKey(), anything );
            }
        }
    }
项目:lams    文件:AbstractEntityInsertAction.java   
/**
 * Make the entity "managed" by the persistence context.
 */
public final void makeEntityManaged() {
    nullifyTransientReferencesIfNotAlready();
    final Object version = Versioning.getVersion( getState(), getPersister() );
    getSession().getPersistenceContext().addEntity(
            getInstance(),
            ( getPersister().isMutable() ? Status.MANAGED : Status.READ_ONLY ),
            getState(),
            getEntityKey(),
            version,
            LockMode.WRITE,
            isExecuted,
            getPersister(),
            isVersionIncrementDisabled,
            false
    );
}
项目:gorm-hibernate5    文件:GrailsHibernateUtil.java   
/**
 * Sets the target object to read-write, allowing Hibernate to dirty check it and auto-flush changes.
 *
 * @see #setObjectToReadyOnly(Object, org.hibernate.SessionFactory)
 *
 * @param target The target object
 * @param sessionFactory The SessionFactory instance
 */
public static void setObjectToReadWrite(final Object target, SessionFactory sessionFactory) {
    Session session = sessionFactory.getCurrentSession();
    if (!canModifyReadWriteState(session, target)) {
        return;
    }

    SessionImplementor sessionImpl = (SessionImplementor) session;
    EntityEntry ee = sessionImpl.getPersistenceContext().getEntry(target);

    if (ee == null || ee.getStatus() != Status.READ_ONLY) {
        return;
    }

    Object actualTarget = target;
    if (target instanceof HibernateProxy) {
        actualTarget = ((HibernateProxy)target).getHibernateLazyInitializer().getImplementation();
    }

    session.setReadOnly(actualTarget, false);
    session.setFlushMode(FlushMode.AUTO);
    incrementVersion(target);
}
项目:lams    文件:StatefulPersistenceContext.java   
@Override
public EntityEntry addEntity(
        final Object entity,
        final Status status,
        final Object[] loadedState,
        final EntityKey entityKey,
        final Object version,
        final LockMode lockMode,
        final boolean existsInDatabase,
        final EntityPersister persister,
        final boolean disableVersionIncrement,
        boolean lazyPropertiesAreUnfetched) {
    addEntity( entityKey, entity );
    return addEntry(
            entity,
            status,
            loadedState,
            null,
            entityKey.getIdentifier(),
            version,
            lockMode,
            existsInDatabase,
            persister,
            disableVersionIncrement,
            lazyPropertiesAreUnfetched
    );
}
项目:lams    文件:StatefulPersistenceContext.java   
@Override
    public EntityEntry addEntry(
            final Object entity,
            final Status status,
            final Object[] loadedState,
            final Object rowId,
            final Serializable id,
            final Object version,
            final LockMode lockMode,
            final boolean existsInDatabase,
            final EntityPersister persister,
            final boolean disableVersionIncrement,
            boolean lazyPropertiesAreUnfetched) {

        final EntityEntry e = new EntityEntry(
                status,
                loadedState,
                rowId,
                id,
                version,
                lockMode,
                existsInDatabase,
                persister,
                disableVersionIncrement,
                lazyPropertiesAreUnfetched,
                this
        );

        entityEntryContext.addEntityEntry( entity, e );
//      entityEntries.put(entity, e);

        setHasNonReadOnlyEnties( status );
        return e;
    }
项目:lams    文件:TwoPhaseLoad.java   
/**
 * Register the "hydrated" state of an entity instance, after the first step of 2-phase loading.
 *
 * Add the "hydrated state" (an array) of an uninitialized entity to the session. We don't try
 * to resolve any associations yet, because there might be other entities waiting to be
 * read from the JDBC result set we are currently processing
 *
 * @param persister The persister for the hydrated entity
 * @param id The entity identifier
 * @param values The entity values
 * @param rowId The rowId for the entity
 * @param object An optional instance for the entity being loaded
 * @param lockMode The lock mode
 * @param lazyPropertiesAreUnFetched Whether properties defined as lazy are yet un-fetched
 * @param session The Session
 */
public static void postHydrate(
        final EntityPersister persister,
        final Serializable id,
        final Object[] values,
        final Object rowId,
        final Object object,
        final LockMode lockMode,
        final boolean lazyPropertiesAreUnFetched,
        final SessionImplementor session) {
    final Object version = Versioning.getVersion( values, persister );
    session.getPersistenceContext().addEntry(
            object,
            Status.LOADING,
            values,
            rowId,
            id,
            version,
            lockMode,
            true,
            persister,
            false,
            lazyPropertiesAreUnFetched
        );

    if ( version != null && LOG.isTraceEnabled() ) {
        final String versionStr = persister.isVersioned()
                ? persister.getVersionType().toLoggableString( version, session.getFactory() )
                : "null";
        LOG.tracef( "Version: %s", versionStr );
    }
}
项目:lams    文件:SessionImpl.java   
@Override
public boolean contains(Object object) {
    errorIfClosed();
    checkTransactionSynchStatus();
    if ( object instanceof HibernateProxy ) {
        //do not use proxiesByKey, since not all
        //proxies that point to this session's
        //instances are in that collection!
        LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
        if ( li.isUninitialized() ) {
            //if it is an uninitialized proxy, pointing
            //with this session, then when it is accessed,
            //the underlying instance will be "contained"
            return li.getSession()==this;
        }
        else {
            //if it is initialized, see if the underlying
            //instance is contained, since we need to
            //account for the fact that it might have been
            //evicted
            object = li.getImplementation();
        }
    }
    // A session is considered to contain an entity only if the entity has
    // an entry in the session's persistence context and the entry reports
    // that the entity has not been removed
    EntityEntry entry = persistenceContext.getEntry( object );
    delayedAfterCompletion();
    return entry != null && entry.getStatus() != Status.DELETED && entry.getStatus() != Status.GONE;
}
项目:lams    文件:DefaultSaveEventListener.java   
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() );
    if ( entry!=null && entry.getStatus() != Status.DELETED ) {
        return entityIsPersistent(event);
    }
    else {
        return entityIsTransient(event);
    }
}
项目:lams    文件:DefaultFlushEntityEventListener.java   
/**
 * Flushes a single entity's state to the database, by scheduling
 * an update action, if necessary
 */
public void onFlushEntity(FlushEntityEvent event) throws HibernateException {
    final Object entity = event.getEntity();
    final EntityEntry entry = event.getEntityEntry();
    final EventSource session = event.getSession();
    final EntityPersister persister = entry.getPersister();
    final Status status = entry.getStatus();
    final Type[] types = persister.getPropertyTypes();

    final boolean mightBeDirty = entry.requiresDirtyCheck( entity );

    final Object[] values = getValues( entity, entry, mightBeDirty, session );

    event.setPropertyValues( values );

    //TODO: avoid this for non-new instances where mightBeDirty==false
    boolean substitute = wrapCollections( session, persister, types, values );

    if ( isUpdateNecessary( event, mightBeDirty ) ) {
        substitute = scheduleUpdate( event ) || substitute;
    }

    if ( status != Status.DELETED ) {
        // now update the object .. has to be outside the main if block above (because of collections)
        if ( substitute ) {
            persister.setPropertyValues( entity, values );
        }

        // Search for collections by reachability, updating their role.
        // We don't want to touch collections reachable from a deleted object
        if ( persister.hasCollections() ) {
            new FlushVisitor( session, entity ).processEntityPropertyValues( values, types );
        }
    }

}
项目:lams    文件:DefaultFlushEntityEventListener.java   
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 ( event.getEntityEntry().getPersister().getInstrumentationMetadata().isInstrumented() ) {
                event.getEntityEntry()
                        .getPersister()
                        .getInstrumentationMetadata()
                        .extractInterceptor( event.getEntity() )
                        .clearDirty();
            }
            event.getSession()
                    .getFactory()
                    .getCustomEntityDirtinessStrategy()
                    .resetDirty( event.getEntity(), event.getEntityEntry().getPersister(), event.getSession() );
            return false;
        }
    }
    else {
        return hasDirtyCollections( event, event.getEntityEntry().getPersister(), status );
    }
}
项目:lams    文件:DefaultReplicateEventListener.java   
private void performReplication(
        Object entity,
        Serializable id,
        Object version,
        EntityPersister persister,
        ReplicationMode replicationMode,
        EventSource source) throws HibernateException {

    if ( LOG.isTraceEnabled() ) {
        LOG.tracev( "Replicating changes to {0}", MessageHelper.infoString( persister, id, source.getFactory() ) );
    }

    new OnReplicateVisitor( source, id, entity, true ).process( entity, persister );

    source.getPersistenceContext().addEntity(
            entity,
            ( persister.isMutable() ? Status.MANAGED : Status.READ_ONLY ),
            null,
            source.generateEntityKey( id, persister ),
            version,
            LockMode.NONE,
            true,
            persister,
            true,
            false
    );

    cascadeAfterReplicate( entity, persister, replicationMode, source );
}
项目:lams    文件:DefaultLoadEventListener.java   
/**
 * If there is already a corresponding proxy associated with the
 * persistence context, return it; otherwise create a proxy, associate it
 * with the persistence context, and return the just-created proxy.
 *
 * @param event The initiating load request event
 * @param persister The persister corresponding to the entity to be loaded
 * @param keyToLoad The key of the entity to be loaded
 * @param options The defined load options
 * @param persistenceContext The originating session
 *
 * @return The created/existing proxy
 */
private Object createProxyIfNecessary(
        final LoadEvent event,
        final EntityPersister persister,
        final EntityKey keyToLoad,
        final LoadEventListener.LoadType options,
        final PersistenceContext persistenceContext) {
    Object existing = persistenceContext.getEntity( keyToLoad );
    if ( existing != null ) {
        // return existing object or initialized proxy (unless deleted)
        LOG.trace( "Entity found in session cache" );
        if ( options.isCheckDeleted() ) {
            EntityEntry entry = persistenceContext.getEntry( existing );
            Status status = entry.getStatus();
            if ( status == Status.DELETED || status == Status.GONE ) {
                return null;
            }
        }
        return existing;
    }
    LOG.trace( "Creating new proxy for entity" );
    // return new uninitialized proxy
    Object proxy = persister.createProxy( event.getEntityId(), event.getSession() );
    persistenceContext.getBatchFetchQueue().addBatchLoadableEntityKey( keyToLoad );
    persistenceContext.addProxy( keyToLoad, proxy );
    return proxy;
}
项目:lams    文件:DefaultLoadEventListener.java   
/**
 * Attempts to locate the entity in the session-level cache.
 * <p/>
 * If allowed to return nulls, then if the entity happens to be found in
 * the session cache, we check the entity type for proper handling
 * of entity hierarchies.
 * <p/>
 * If checkDeleted was set to true, then if the entity is found in the
 * session-level cache, it's current status within the session cache
 * is checked to see if it has previously been scheduled for deletion.
 *
 * @param event The load event
 * @param keyToLoad The EntityKey representing the entity to be loaded.
 * @param options The load options.
 *
 * @return The entity from the session-level cache, or null.
 *
 * @throws HibernateException Generally indicates problems applying a lock-mode.
 */
protected Object loadFromSessionCache(
        final LoadEvent event,
        final EntityKey keyToLoad,
        final LoadEventListener.LoadType options) throws HibernateException {

    SessionImplementor session = event.getSession();
    Object old = session.getEntityUsingInterceptor( keyToLoad );

    if ( old != null ) {
        // this object was already loaded
        EntityEntry oldEntry = session.getPersistenceContext().getEntry( old );
        if ( options.isCheckDeleted() ) {
            Status status = oldEntry.getStatus();
            if ( status == Status.DELETED || status == Status.GONE ) {
                return REMOVED_ENTITY_MARKER;
            }
        }
        if ( options.isAllowNulls() ) {
            final EntityPersister persister = event.getSession()
                    .getFactory()
                    .getEntityPersister( keyToLoad.getEntityName() );
            if ( !persister.isInstance( old ) ) {
                return INCONSISTENT_RTN_CLASS_MARKER;
            }
        }
        upgradeLock( old, oldEntry, event.getLockOptions(), event.getSession() );
    }

    return old;
}
项目:lams    文件:AbstractFlushingEventListener.java   
/**
 * 1. detect any dirty entities
 * 2. schedule any entity updates
 * 3. search out any reachable collections
 */
private int flushEntities(final FlushEvent event, final PersistenceContext persistenceContext) throws HibernateException {

    LOG.trace( "Flushing entities and processing referenced collections" );

    final EventSource source = event.getSession();
    final Iterable<FlushEntityEventListener> flushListeners = source.getFactory().getServiceRegistry()
            .getService( EventListenerRegistry.class )
            .getEventListenerGroup( EventType.FLUSH_ENTITY )
            .listeners();

    // Among other things, updateReachables() will recursively load all
    // collections that are moving roles. This might cause entities to
    // be loaded.

    // So this needs to be safe from concurrent modification problems.

    final Map.Entry<Object,EntityEntry>[] entityEntries = persistenceContext.reentrantSafeEntityEntries();
    final int count = entityEntries.length;

    for ( Map.Entry<Object,EntityEntry> me : entityEntries ) {

        // Update the status of the object and if necessary, schedule an update

        EntityEntry entry = me.getValue();
        Status status = entry.getStatus();

        if ( status != Status.LOADING && status != Status.GONE ) {
            final FlushEntityEvent entityEvent = new FlushEntityEvent( source, me.getKey(), entry );
            for ( FlushEntityEventListener listener : flushListeners ) {
                listener.onFlushEntity( entityEvent );
            }
        }
    }

    source.getActionQueue().sortActions();

    return count;
}
项目:lams    文件:AbstractSaveEventListener.java   
/**
 * Determine whether the entity is persistent, detached, or transient
 *
 * @param entity The entity to check
 * @param entityName The name of the entity
 * @param entry The entity's entry in the persistence context
 * @param source The originating session.
 *
 * @return The state.
 */
protected EntityState getEntityState(
        Object entity,
        String entityName,
        EntityEntry entry, //pass this as an argument only to avoid double looking
        SessionImplementor source) {

    final boolean traceEnabled = LOG.isTraceEnabled();
    if ( entry != null ) { // the object is persistent

        //the entity is associated with the session, so check its status
        if ( entry.getStatus() != Status.DELETED ) {
            // do nothing for persistent instances
            if ( traceEnabled ) {
                LOG.tracev( "Persistent instance of: {0}", getLoggableName( entityName, entity ) );
            }
            return EntityState.PERSISTENT;
        }
        // ie. e.status==DELETED
        if ( traceEnabled ) {
            LOG.tracev( "Deleted instance of: {0}", getLoggableName( entityName, entity ) );
        }
        return EntityState.DELETED;
    }
    // the object is transient or detached

    // the entity is not associated with the session, so
    // try interceptor and unsaved-value

    if ( ForeignKeys.isTransient( entityName, entity, getAssumedUnsaved(), source ) ) {
        if ( traceEnabled ) {
            LOG.tracev( "Transient instance of: {0}", getLoggableName( entityName, entity ) );
        }
        return EntityState.TRANSIENT;
    }
    if ( traceEnabled ) {
        LOG.tracev( "Detached instance of: {0}", getLoggableName( entityName, entity ) );
    }
    return EntityState.DETACHED;
}
项目:lams    文件:Collections.java   
private static void processDereferencedCollection(PersistentCollection coll, SessionImplementor session) {
    final PersistenceContext persistenceContext = session.getPersistenceContext();
    final CollectionEntry entry = persistenceContext.getCollectionEntry( coll );
    final CollectionPersister loadedPersister = entry.getLoadedPersister();

    if ( loadedPersister != null && LOG.isDebugEnabled() ) {
        LOG.debugf(
                "Collection dereferenced: %s",
                MessageHelper.collectionInfoString( loadedPersister, 
                        coll, entry.getLoadedKey(), session
                )
        );
    }

    // do a check
    final boolean hasOrphanDelete = loadedPersister != null && loadedPersister.hasOrphanDelete();
    if ( hasOrphanDelete ) {
        Serializable ownerId = loadedPersister.getOwnerEntityPersister().getIdentifier( coll.getOwner(), session );
        if ( ownerId == null ) {
            // the owning entity may have been deleted and its identifier unset due to
            // identifier-rollback; in which case, try to look up its identifier from
            // the persistence context
            if ( session.getFactory().getSettings().isIdentifierRollbackEnabled() ) {
                final EntityEntry ownerEntry = persistenceContext.getEntry( coll.getOwner() );
                if ( ownerEntry != null ) {
                    ownerId = ownerEntry.getId();
                }
            }
            if ( ownerId == null ) {
                throw new AssertionFailure( "Unable to determine collection owner identifier for orphan-delete processing" );
            }
        }
        final EntityKey key = session.generateEntityKey( ownerId, loadedPersister.getOwnerEntityPersister() );
        final Object owner = persistenceContext.getEntity( key );
        if ( owner == null ) {
            throw new AssertionFailure(
                    "collection owner not associated with session: " +
                    loadedPersister.getRole()
            );
        }
        final EntityEntry e = persistenceContext.getEntry( owner );
        //only collections belonging to deleted entities are allowed to be dereferenced in the case of orphan delete
        if ( e != null && e.getStatus() != Status.DELETED && e.getStatus() != Status.GONE ) {
            throw new HibernateException(
                    "A collection with cascade=\"all-delete-orphan\" was no longer referenced by the owning entity instance: " +
                    loadedPersister.getRole()
            );
        }
    }

    // do the work
    entry.setCurrentPersister( null );
    entry.setCurrentKey( null );
    prepareCollectionForUpdate( coll, entry, session.getFactory() );

}
项目:lams    文件:StatefulPersistenceContext.java   
@Override
public void setEntryStatus(EntityEntry entry, Status status) {
    entry.setStatus( status );
    setHasNonReadOnlyEnties( status );
}
项目:lams    文件:StatefulPersistenceContext.java   
private void setHasNonReadOnlyEnties(Status status) {
    if ( status==Status.DELETED || status==Status.MANAGED || status==Status.SAVING ) {
        hasNonReadOnlyEntities = true;
    }
}
项目:lams    文件:CollectionLoadContext.java   
/**
 * Retrieve the collection that is being loaded as part of processing this
 * result set.
 * <p/>
 * Basically, there are two valid return values from this method:<ul>
 * <li>an instance of {@link org.hibernate.collection.spi.PersistentCollection} which indicates to
 * continue loading the result set row data into that returned collection
 * instance; this may be either an instance already associated and in the
 * midst of being loaded, or a newly instantiated instance as a matching
 * associated collection was not found.</li>
 * <li><i>null</i> indicates to ignore the corresponding result set row
 * data relating to the requested collection; this indicates that either
 * the collection was found to already be associated with the persistence
 * context in a fully loaded state, or it was found in a loading state
 * associated with another result set processing context.</li>
 * </ul>
 *
 * @param persister The persister for the collection being requested.
 * @param key The key of the collection being requested.
 *
 * @return The loading collection (see discussion above).
 */
public PersistentCollection getLoadingCollection(final CollectionPersister persister, final Serializable key) {
    final EntityMode em = persister.getOwnerEntityPersister().getEntityMetamodel().getEntityMode();
    final CollectionKey collectionKey = new CollectionKey( persister, key, em );
    if ( LOG.isTraceEnabled() ) {
        LOG.tracev( "Starting attempt to find loading collection [{0}]",
                MessageHelper.collectionInfoString( persister.getRole(), key ) );
    }
    final LoadingCollectionEntry loadingCollectionEntry = loadContexts.locateLoadingCollectionEntry( collectionKey );
    if ( loadingCollectionEntry == null ) {
        // look for existing collection as part of the persistence context
        PersistentCollection collection = loadContexts.getPersistenceContext().getCollection( collectionKey );
        if ( collection != null ) {
            if ( collection.wasInitialized() ) {
                LOG.trace( "Collection already initialized; ignoring" );
                // ignore this row of results! Note the early exit
                return null;
            }
            LOG.trace( "Collection not yet initialized; initializing" );
        }
        else {
            final Object owner = loadContexts.getPersistenceContext().getCollectionOwner( key, persister );
            final boolean newlySavedEntity = owner != null
                    && loadContexts.getPersistenceContext().getEntry( owner ).getStatus() != Status.LOADING;
            if ( newlySavedEntity ) {
                // important, to account for newly saved entities in query
                // todo : some kind of check for new status...
                LOG.trace( "Owning entity already loaded; ignoring" );
                return null;
            }
            // create one
            LOG.tracev( "Instantiating new collection [key={0}, rs={1}]", key, resultSet );
            collection = persister.getCollectionType().instantiate(
                    loadContexts.getPersistenceContext().getSession(), persister, key );
        }
        collection.beforeInitialize( persister, -1 );
        collection.beginRead();
        localLoadingCollectionKeys.add( collectionKey );
        loadContexts.registerLoadingCollectionXRef( collectionKey, new LoadingCollectionEntry( resultSet, persister, key, collection ) );
        return collection;
    }
    if ( loadingCollectionEntry.getResultSet() == resultSet ) {
        LOG.trace( "Found loading collection bound to current result set processing; reading row" );
        return loadingCollectionEntry.getCollection();
    }
    // ignore this row, the collection is in process of
    // being loaded somewhere further "up" the stack
    LOG.trace( "Collection is already being initialized; ignoring row" );
    return null;
}
项目:lams    文件:SessionImpl.java   
protected void performAnyNeededCrossReferenceSynchronizations() {
    if ( ! synchronizationEnabled ) {
        // synchronization (this process) was disabled
        return;
    }
    if ( entityPersister.getEntityMetamodel().hasImmutableNaturalId() ) {
        // only mutable natural-ids need this processing
        return;
    }
    if ( ! isTransactionInProgress() ) {
        // not in a transaction so skip synchronization
        return;
    }

    final boolean debugEnabled = LOG.isDebugEnabled();
    for ( Serializable pk : getPersistenceContext().getNaturalIdHelper().getCachedPkResolutions( entityPersister ) ) {
        final EntityKey entityKey = generateEntityKey( pk, entityPersister );
        final Object entity = getPersistenceContext().getEntity( entityKey );
        final EntityEntry entry = getPersistenceContext().getEntry( entity );

        if ( entry == null ) {
            if ( debugEnabled ) {
                LOG.debug(
                        "Cached natural-id/pk resolution linked to null EntityEntry in persistence context : "
                                + MessageHelper.infoString( entityPersister, pk, getFactory() )
                );
            }
            continue;
        }

        if ( !entry.requiresDirtyCheck( entity ) ) {
            continue;
        }

        // MANAGED is the only status we care about here...
        if ( entry.getStatus() != Status.MANAGED ) {
            continue;
        }

        getPersistenceContext().getNaturalIdHelper().handleSynchronization(
                entityPersister,
                pk,
                entity
        );
    }
}
项目:lams    文件:AbstractLockUpgradeEventListener.java   
/**
 * Performs a pessimistic lock upgrade on a given entity, if needed.
 *
 * @param object The entity for which to upgrade the lock.
 * @param entry The entity's EntityEntry instance.
 * @param lockOptions contains the requested lock mode.
 * @param source The session which is the source of the event being processed.
 */
protected void upgradeLock(Object object, EntityEntry entry, LockOptions lockOptions, EventSource source) {

    LockMode requestedLockMode = lockOptions.getLockMode();
    if ( requestedLockMode.greaterThan( entry.getLockMode() ) ) {
        // The user requested a "greater" (i.e. more restrictive) form of
        // pessimistic lock

        if ( entry.getStatus() != Status.MANAGED ) {
            throw new ObjectDeletedException(
                    "attempted to lock a deleted instance",
                    entry.getId(),
                    entry.getPersister().getEntityName()
            );
        }

        final EntityPersister persister = entry.getPersister();

        if ( log.isTraceEnabled() ) {
            log.tracev(
                    "Locking {0} in mode: {1}",
                    MessageHelper.infoString( persister, entry.getId(), source.getFactory() ),
                    requestedLockMode
            );
        }

        final SoftLock lock;
        final CacheKey ck;
        if ( persister.hasCache() ) {
            ck = source.generateCacheKey( entry.getId(), persister.getIdentifierType(), persister.getRootEntityName() );
            lock = persister.getCacheAccessStrategy().lockItem( ck, entry.getVersion() );
        }
        else {
            ck = null;
            lock = null;
        }

        try {
            if ( persister.isVersioned() && requestedLockMode == LockMode.FORCE  ) {
                // todo : should we check the current isolation mode explicitly?
                Object nextVersion = persister.forceVersionIncrement(
                        entry.getId(), entry.getVersion(), source
                );
                entry.forceLocked( object, nextVersion );
            }
            else {
                persister.lock( entry.getId(), entry.getVersion(), object, lockOptions, source );
            }
            entry.setLockMode(requestedLockMode);
        }
        finally {
            // the database now holds a lock + the object is flushed from the cache,
            // so release the soft lock
            if ( persister.hasCache() ) {
                persister.getCacheAccessStrategy().unlockItem( ck, lock );
            }
        }

    }
}
项目:lams    文件:DefaultFlushEntityEventListener.java   
private void checkNaturalId(
        EntityPersister persister,
        EntityEntry entry,
        Object[] current,
        Object[] loaded,
        SessionImplementor session) {
    if ( persister.hasNaturalIdentifier() && entry.getStatus() != Status.READ_ONLY ) {
        if ( !persister.getEntityMetamodel().hasImmutableNaturalId() ) {
            // SHORT-CUT: if the natural id is mutable (!immutable), no need to do the below checks
            // EARLY EXIT!!!
            return;
        }

        final int[] naturalIdentifierPropertiesIndexes = persister.getNaturalIdentifierProperties();
        final Type[] propertyTypes = persister.getPropertyTypes();
        final boolean[] propertyUpdateability = persister.getPropertyUpdateability();

        final Object[] snapshot = loaded == null
                ? session.getPersistenceContext().getNaturalIdSnapshot( entry.getId(), persister )
                : session.getPersistenceContext().getNaturalIdHelper().extractNaturalIdValues( loaded, persister );

        for ( int i = 0; i < naturalIdentifierPropertiesIndexes.length; i++ ) {
            final int naturalIdentifierPropertyIndex = naturalIdentifierPropertiesIndexes[i];
            if ( propertyUpdateability[naturalIdentifierPropertyIndex] ) {
                // if the given natural id property is updatable (mutable), there is nothing to check
                continue;
            }

            final Type propertyType = propertyTypes[naturalIdentifierPropertyIndex];
            if ( !propertyType.isEqual( current[naturalIdentifierPropertyIndex], snapshot[i] ) ) {
                throw new HibernateException(
                        String.format(
                                "An immutable natural identifier of entity %s was altered from %s to %s",
                                persister.getEntityName(),
                                propertyTypes[naturalIdentifierPropertyIndex].toLoggableString(
                                        snapshot[i],
                                        session.getFactory()
                                ),
                                propertyTypes[naturalIdentifierPropertyIndex].toLoggableString(
                                        current[naturalIdentifierPropertyIndex],
                                        session.getFactory()
                                )
                        )
                );
            }
        }
    }
}
项目:lams    文件:DefaultFlushEntityEventListener.java   
private boolean scheduleUpdate(final FlushEntityEvent event) {
    final EntityEntry entry = event.getEntityEntry();
    final EventSource session = event.getSession();
    final Object entity = event.getEntity();
    final Status status = entry.getStatus();
    final EntityPersister persister = entry.getPersister();
    final Object[] values = event.getPropertyValues();

    if ( LOG.isTraceEnabled() ) {
        if ( status == Status.DELETED ) {
            if ( !persister.isMutable() ) {
                LOG.tracev(
                        "Updating immutable, deleted entity: {0}",
                        MessageHelper.infoString( persister, entry.getId(), session.getFactory() )
                );
            }
            else if ( !entry.isModifiableEntity() ) {
                LOG.tracev(
                        "Updating non-modifiable, deleted entity: {0}",
                        MessageHelper.infoString( persister, entry.getId(), session.getFactory() )
                );
            }
            else {
                LOG.tracev(
                        "Updating deleted entity: ",
                        MessageHelper.infoString( persister, entry.getId(), session.getFactory() )
                );
            }
        }
        else {
            LOG.tracev(
                    "Updating entity: {0}",
                    MessageHelper.infoString( persister, entry.getId(), session.getFactory() )
            );
        }
    }

    final boolean intercepted = !entry.isBeingReplicated() && handleInterception( event );

    // increment the version number (if necessary)
    final Object nextVersion = getNextVersion( event );

    // if it was dirtied by a collection only
    int[] dirtyProperties = event.getDirtyProperties();
    if ( event.isDirtyCheckPossible() && dirtyProperties == null ) {
        if ( !intercepted && !event.hasDirtyCollection() ) {
            throw new AssertionFailure( "dirty, but no dirty properties" );
        }
        dirtyProperties = ArrayHelper.EMPTY_INT_ARRAY;
    }

    // check nullability but do not doAfterTransactionCompletion 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(),
                    ( status == Status.DELETED && !entry.isModifiableEntity() ?
                            persister.getPropertyValues( entity ) :
                            entry.getLoadedState() ),
                    entry.getVersion(),
                    nextVersion,
                    entity,
                    entry.getRowId(),
                    persister,
                    session
            )
    );

    return intercepted;
}
项目:lams    文件:DefaultFlushEntityEventListener.java   
private boolean isCollectionDirtyCheckNecessary(EntityPersister persister, Status status) {
    return ( status == Status.MANAGED || status == Status.READ_ONLY ) &&
            persister.isVersioned() &&
            persister.hasCollections();
}
项目:lams    文件:DefaultSaveOrUpdateEventListener.java   
protected Serializable entityIsPersistent(SaveOrUpdateEvent event) throws HibernateException {
    final boolean traceEnabled = LOG.isTraceEnabled();
    if ( traceEnabled ) {
        LOG.trace( "Ignoring persistent instance" );
    }
    EntityEntry entityEntry = event.getEntry();
    if ( entityEntry == null ) {
        throw new AssertionFailure( "entity was transient or detached" );
    }
    else {

        if ( entityEntry.getStatus() == Status.DELETED ) {
            throw new AssertionFailure( "entity was deleted" );
        }

        final SessionFactoryImplementor factory = event.getSession().getFactory();

        Serializable requestedId = event.getRequestedId();

        Serializable savedId;
        if ( requestedId == null ) {
            savedId = entityEntry.getId();
        }
        else {

            final boolean isEqual = !entityEntry.getPersister().getIdentifierType()
                    .isEqual( requestedId, entityEntry.getId(), factory );

            if ( isEqual ) {
                throw new PersistentObjectException(
                        "object passed to save() was already persistent: " +
                                MessageHelper.infoString( entityEntry.getPersister(), requestedId, factory )
                );
            }

            savedId = requestedId;

        }

        if ( traceEnabled ) {
            LOG.tracev(
                    "Object already associated with session: {0}",
                    MessageHelper.infoString( entityEntry.getPersister(), savedId, factory )
            );
        }

        return savedId;

    }
}
项目:lams    文件:DefaultSaveOrUpdateEventListener.java   
protected void performUpdate(
        SaveOrUpdateEvent event,
        Object entity,
        EntityPersister persister) throws HibernateException {

    final boolean traceEnabled = LOG.isTraceEnabled();
    if ( traceEnabled && !persister.isMutable() ) {
        LOG.trace( "Immutable instance passed to performUpdate()" );
    }

    if ( traceEnabled ) {
        LOG.tracev(
                "Updating {0}",
                MessageHelper.infoString( persister, event.getRequestedId(), event.getSession().getFactory() )
        );
    }

    final EventSource source = event.getSession();
    final EntityKey key = source.generateEntityKey( event.getRequestedId(), persister );

    source.getPersistenceContext().checkUniqueness( key, entity );

    if ( invokeUpdateLifecycle( entity, persister, source ) ) {
        reassociate( event, event.getObject(), event.getRequestedId(), persister );
        return;
    }

    // this is a transient object with existing persistent state not loaded by the session

    new OnUpdateVisitor( source, event.getRequestedId(), entity ).process( entity, persister );

    // TODO: put this stuff back in to read snapshot from
    // the second-level cache (needs some extra work)
    /*Object[] cachedState = null;

       if ( persister.hasCache() ) {
        CacheEntry entry = (CacheEntry) persister.getCache()
                .get( event.getRequestedId(), source.getTimestamp() );
           cachedState = entry==null ?
                null :
                entry.getState(); //TODO: half-assemble this stuff
       }*/

    source.getPersistenceContext().addEntity(
            entity,
            ( persister.isMutable() ? Status.MANAGED : Status.READ_ONLY ),
            null, // cachedState,
            key,
            persister.getVersion( entity ),
            LockMode.NONE,
            true,
            persister,
            false,
            true // assume true, since we don't really know, and it doesn't matter
    );

    persister.afterReassociate( entity, source );

    if ( traceEnabled ) {
        LOG.tracev(
                "Updating {0}", MessageHelper.infoString(
                persister,
                event.getRequestedId(),
                source.getFactory()
        )
        );
    }

    cascadeOnUpdate( event, persister, entity );
}
项目:lams    文件:AbstractReassociateEventListener.java   
/**
 * Associates a given entity (either transient or associated with another session) to
 * the given session.
 *
 * @param event The event triggering the re-association
 * @param object The entity to be associated
 * @param id The id of the entity.
 * @param persister The entity's persister instance.
 *
 * @return An EntityEntry representing the entity within this session.
 */
protected final EntityEntry reassociate(AbstractEvent event, Object object, Serializable id, EntityPersister persister) {

    if ( log.isTraceEnabled() ) {
        log.tracev(
                "Reassociating transient instance: {0}",
                MessageHelper.infoString( persister, id, event.getSession().getFactory() )
        );
    }

    final EventSource source = event.getSession();
    final EntityKey key = source.generateEntityKey( id, persister );

    source.getPersistenceContext().checkUniqueness( key, object );

    //get a snapshot
    Object[] values = persister.getPropertyValues( object );
    TypeHelper.deepCopy(
            values,
            persister.getPropertyTypes(),
            persister.getPropertyUpdateability(),
            values,
            source
    );
    Object version = Versioning.getVersion( values, persister );

    EntityEntry newEntry = source.getPersistenceContext().addEntity(
            object,
            ( persister.isMutable() ? Status.MANAGED : Status.READ_ONLY ),
            values,
            key,
            version,
            LockMode.NONE,
            true,
            persister,
            false,
            true //will be ignored, using the existing Entry instead
    );

    new OnLockVisitor( source, id, object ).process( object, persister );

    persister.afterReassociate( object, source );

    return newEntry;

}
项目:lams    文件:AbstractSaveEventListener.java   
/**
 * Prepares the save call by checking the session caches for a pre-existing
 * entity and performing any lifecycle callbacks.
 *
 * @param entity The entity to be saved.
 * @param id The id by which to save the entity.
 * @param persister The entity's persister instance.
 * @param useIdentityColumn Is an identity column being used?
 * @param anything Generally cascade-specific information.
 * @param source The session from which the event originated.
 * @param requiresImmediateIdAccess does the event context require
 * access to the identifier immediately after execution of this method (if
 * not, post-insert style id generators may be postponed if we are outside
 * a transaction).
 *
 * @return The id used to save the entity; may be null depending on the
 *         type of id generator used and the requiresImmediateIdAccess value
 */
protected Serializable performSave(
        Object entity,
        Serializable id,
        EntityPersister persister,
        boolean useIdentityColumn,
        Object anything,
        EventSource source,
        boolean requiresImmediateIdAccess) {

    if ( LOG.isTraceEnabled() ) {
        LOG.tracev( "Saving {0}", MessageHelper.infoString( persister, id, source.getFactory() ) );
    }

    final EntityKey key;
    if ( !useIdentityColumn ) {
        key = source.generateEntityKey( id, persister );
        Object old = source.getPersistenceContext().getEntity( key );
        if ( old != null ) {
            if ( source.getPersistenceContext().getEntry( old ).getStatus() == Status.DELETED ) {
                source.forceFlush( source.getPersistenceContext().getEntry( old ) );
            }
            else {
                throw new NonUniqueObjectException( id, persister.getEntityName() );
            }
        }
        persister.setIdentifier( entity, id, source );
    }
    else {
        key = null;
    }

    if ( invokeSaveLifecycle( entity, persister, source ) ) {
        return id; //EARLY EXIT
    }

    return performSaveOrReplicate(
            entity,
            key,
            persister,
            useIdentityColumn,
            anything,
            source,
            requiresImmediateIdAccess
    );
}
项目:lams    文件:AbstractPersistentCollection.java   
/**
 * Given a collection of entity instances that used to
 * belong to the collection, and a collection of instances
 * that currently belong, return a collection of orphans
 */
@SuppressWarnings({"JavaDoc", "unchecked"})
protected static Collection getOrphans(
        Collection oldElements,
        Collection currentElements,
        String entityName,
        SessionImplementor session) throws HibernateException {

    // short-circuit(s)
    if ( currentElements.size() == 0 ) {
        // no new elements, the old list contains only Orphans
        return oldElements;
    }
    if ( oldElements.size() == 0 ) {
        // no old elements, so no Orphans neither
        return oldElements;
    }

    final EntityPersister entityPersister = session.getFactory().getEntityPersister( entityName );
    final Type idType = entityPersister.getIdentifierType();

    // create the collection holding the Orphans
    final Collection res = new ArrayList();

    // collect EntityIdentifier(s) of the *current* elements - add them into a HashSet for fast access
    final java.util.Set currentIds = new HashSet();
    final java.util.Set currentSaving = new IdentitySet();
    for ( Object current : currentElements ) {
        if ( current != null && ForeignKeys.isNotTransient( entityName, current, null, session ) ) {
            final EntityEntry ee = session.getPersistenceContext().getEntry( current );
            if ( ee != null && ee.getStatus() == Status.SAVING ) {
                currentSaving.add( current );
            }
            else {
                final Serializable currentId = ForeignKeys.getEntityIdentifierIfNotUnsaved(
                        entityName,
                        current,
                        session
                );
                currentIds.add( new TypedValue( idType, currentId ) );
            }
        }
    }

    // iterate over the *old* list
    for ( Object old : oldElements ) {
        if ( !currentSaving.contains( old ) ) {
            final Serializable oldId = ForeignKeys.getEntityIdentifierIfNotUnsaved( entityName, old, session );
            if ( !currentIds.contains( new TypedValue( idType, oldId ) ) ) {
                res.add( old );
            }
        }
    }

    return res;
}
项目:lams    文件:UnresolvedEntityInsertActions.java   
/**
 * Resolve any dependencies on {@code managedEntity}.
 *
 * @param managedEntity - the managed entity name
 * @param session - the session
 *
 * @return the insert actions that depended only on the specified entity.
 *
 * @throws IllegalArgumentException if {@code managedEntity} did not have managed or read-only status.
 */
@SuppressWarnings({ "unchecked" })
public Set<AbstractEntityInsertAction> resolveDependentActions(Object managedEntity, SessionImplementor session) {
    final EntityEntry entityEntry = session.getPersistenceContext().getEntry( managedEntity );
    if ( entityEntry.getStatus() != Status.MANAGED && entityEntry.getStatus() != Status.READ_ONLY ) {
        throw new IllegalArgumentException( "EntityEntry did not have status MANAGED or READ_ONLY: " + entityEntry );
    }

    final boolean traceEnabled = LOG.isTraceEnabled();
    // Find out if there are any unresolved insertions that are waiting for the
    // specified entity to be resolved.
    final Set<AbstractEntityInsertAction> dependentActions = dependentActionsByTransientEntity.remove( managedEntity );
    if ( dependentActions == null ) {
        if ( traceEnabled ) {
            LOG.tracev(
                    "No unresolved entity inserts that depended on [{0}]",
                    MessageHelper.infoString( entityEntry.getEntityName(), entityEntry.getId() )
            );
        }
        // NOTE EARLY EXIT!
        return Collections.emptySet();
    }
    final Set<AbstractEntityInsertAction> resolvedActions = new IdentitySet(  );
    if ( traceEnabled  ) {
        LOG.tracev(
                "Unresolved inserts before resolving [{0}]: [{1}]",
                MessageHelper.infoString( entityEntry.getEntityName(), entityEntry.getId() ),
                toString()
        );
    }
    for ( AbstractEntityInsertAction dependentAction : dependentActions ) {
        if ( traceEnabled ) {
            LOG.tracev(
                    "Resolving insert [{0}] dependency on [{1}]",
                    MessageHelper.infoString( dependentAction.getEntityName(), dependentAction.getId() ),
                    MessageHelper.infoString( entityEntry.getEntityName(), entityEntry.getId() )
            );
        }
        final NonNullableTransientDependencies dependencies = dependenciesByAction.get( dependentAction );
        dependencies.resolveNonNullableTransientEntity( managedEntity );
        if ( dependencies.isEmpty() ) {
            if ( traceEnabled ) {
                LOG.tracev(
                        "Resolving insert [{0}] (only depended on [{1}])",
                        dependentAction,
                        MessageHelper.infoString( entityEntry.getEntityName(), entityEntry.getId() )
                );
            }
            // dependentAction only depended on managedEntity..
            dependenciesByAction.remove( dependentAction );
            resolvedActions.add( dependentAction );
        }
    }
    if ( traceEnabled  ) {
        LOG.tracev(
                "Unresolved inserts after resolving [{0}]: [{1}]",
                MessageHelper.infoString( entityEntry.getEntityName(), entityEntry.getId() ),
                toString()
        );
    }
    return resolvedActions;
}
项目:high-performance-java-persistence    文件:OptimisticLockingChildUpdatesRootVersionTest.java   
private boolean deleted(FlushEntityEvent event) {
    return event.getEntityEntry().getStatus() == Status.DELETED;
}
项目:high-performance-java-persistence    文件:OptimisticLockingBidirectionalChildUpdatesRootVersionTest.java   
private void incrementRootVersion(FlushEntityEvent event, Object root) {
    EntityEntry entityEntry = event.getSession().getPersistenceContext().getEntry( Hibernate.unproxy( root) );
    if(entityEntry.getStatus() != Status.DELETED) {
        event.getSession().lock(root, LockMode.OPTIMISTIC_FORCE_INCREMENT);
    }
}
项目:high-performance-java-persistence    文件:OptimisticLockingBidirectionalChildUpdatesRootVersionTest.java   
private boolean deleted(FlushEntityEvent event) {
    return event.getEntityEntry().getStatus() == Status.DELETED;
}