예제 #1
0
  @Override
  public void execute() throws HibernateException {
    final Serializable id = getId();
    final EntityPersister persister = getPersister();
    final SessionImplementor session = getSession();
    final Object instance = getInstance();

    final boolean veto = preUpdate();

    final SessionFactoryImplementor factory = session.getFactory();
    Object previousVersion = this.previousVersion;
    if (persister.isVersionPropertyGenerated()) {
      // we need to grab the version value from the entity, otherwise
      // we have issues with generated-version entities that may have
      // multiple actions queued during the same flush
      previousVersion = persister.getVersion(instance);
    }

    final Object ck;
    if (persister.hasCache()) {
      final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy();
      ck = cache.generateCacheKey(id, persister, factory, session.getTenantIdentifier());
      lock = cache.lockItem(session, ck, previousVersion);
    } else {
      ck = null;
    }

    if (!veto) {
      persister.update(
          id,
          state,
          dirtyFields,
          hasDirtyCollection,
          previousState,
          previousVersion,
          instance,
          rowId,
          session);
    }

    final EntityEntry entry = session.getPersistenceContext().getEntry(instance);
    if (entry == null) {
      throw new AssertionFailure("possible nonthreadsafe access to session");
    }

    if (entry.getStatus() == Status.MANAGED || persister.isVersionPropertyGenerated()) {
      // get the updated snapshot of the entity state by cloning current state;
      // it is safe to copy in place, since by this time no-one else (should have)
      // has a reference  to the array
      TypeHelper.deepCopy(
          state, persister.getPropertyTypes(), persister.getPropertyCheckability(), state, session);
      if (persister.hasUpdateGeneratedProperties()) {
        // this entity defines proeprty generation, so process those generated
        // values...
        persister.processUpdateGeneratedProperties(id, instance, state, session);
        if (persister.isVersionPropertyGenerated()) {
          nextVersion = Versioning.getVersion(state, persister);
        }
      }
      // have the entity entry doAfterTransactionCompletion post-update processing, passing it the
      // update state and the new version (if one).
      entry.postUpdate(instance, state, nextVersion);
    }

    if (persister.hasCache()) {
      if (persister.isCacheInvalidationRequired() || entry.getStatus() != Status.MANAGED) {
        persister.getCacheAccessStrategy().remove(session, ck);
      } else {
        // TODO: inefficient if that cache is just going to ignore the updated state!
        final CacheEntry ce = persister.buildCacheEntry(instance, state, nextVersion, getSession());
        cacheEntry = persister.getCacheEntryStructure().structure(ce);

        final boolean put = cacheUpdate(persister, previousVersion, ck);
        if (put && factory.getStatistics().isStatisticsEnabled()) {
          factory
              .getStatisticsImplementor()
              .secondLevelCachePut(getPersister().getCacheAccessStrategy().getRegion().getName());
        }
      }
    }

    session
        .getPersistenceContext()
        .getNaturalIdHelper()
        .manageSharedNaturalIdCrossReference(
            persister, id, state, previousNaturalIdValues, CachedNaturalIdValueSource.UPDATE);

    postUpdate();

    if (factory.getStatistics().isStatisticsEnabled() && !veto) {
      factory.getStatisticsImplementor().updateEntity(getPersister().getEntityName());
    }
  }
예제 #2
0
  @Override
  public void execute() throws HibernateException {
    nullifyTransientReferencesIfNotAlready();

    final EntityPersister persister = getPersister();
    final SessionImplementor session = getSession();
    final Object instance = getInstance();
    final Serializable id = getId();

    final boolean veto = preInsert();

    // Don't need to lock the cache here, since if someone
    // else inserted the same pk first, the insert would fail

    if (!veto) {

      persister.insert(id, getState(), instance, session);

      final EntityEntry entry = session.getPersistenceContext().getEntry(instance);
      if (entry == null) {
        throw new AssertionFailure("possible non-threadsafe access to session");
      }

      entry.postInsert(getState());

      if (persister.hasInsertGeneratedProperties()) {
        persister.processInsertGeneratedProperties(id, instance, getState(), session);
        if (persister.isVersionPropertyGenerated()) {
          version = Versioning.getVersion(getState(), persister);
        }
        entry.postUpdate(instance, getState(), version);
      }

      getSession().getPersistenceContext().registerInsertedKey(getPersister(), getId());
    }

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

    if (isCachePutEnabled(persister, session)) {
      final CacheEntry ce = persister.buildCacheEntry(instance, getState(), version, session);
      cacheEntry = persister.getCacheEntryStructure().structure(ce);
      final CacheKey ck =
          session.generateCacheKey(
              id, persister.getIdentifierType(), persister.getRootEntityName());
      final boolean put = persister.getCacheAccessStrategy().insert(ck, cacheEntry, version);

      if (put && factory.getStatistics().isStatisticsEnabled()) {
        factory
            .getStatisticsImplementor()
            .secondLevelCachePut(getPersister().getCacheAccessStrategy().getRegion().getName());
      }
    }

    handleNaturalIdPostSaveNotifications(id);

    postInsert();

    if (factory.getStatistics().isStatisticsEnabled() && !veto) {
      factory.getStatisticsImplementor().insertEntity(getPersister().getEntityName());
    }

    markExecuted();
  }