コード例 #1
0
  private void addEntityCheckCache(SessionFactoryImplementor sessionFactory) throws Exception {
    Item item = new Item("chris", "Chris's Item");
    beginTx();
    try {
      Session s = sessionFactory.openSession();
      s.getTransaction().begin();
      s.persist(item);
      s.getTransaction().commit();
      s.close();
    } catch (Exception e) {
      setRollbackOnlyTx(e);
    } finally {
      commitOrRollbackTx();
    }

    beginTx();
    try {
      Session s = sessionFactory.openSession();
      Item found = (Item) s.load(Item.class, item.getId());
      Statistics stats = sessionFactory.getStatistics();
      log.info(stats.toString());
      assertEquals(item.getDescription(), found.getDescription());
      assertEquals(0, stats.getSecondLevelCacheMissCount());
      assertEquals(1, stats.getSecondLevelCacheHitCount());
      s.delete(found);
      s.close();
    } catch (Exception e) {
      setRollbackOnlyTx(e);
    } finally {
      commitOrRollbackTx();
    }
  }
  @Override
  public void lock(
      Serializable id, Object version, Object object, int timeout, SessionImplementor session) {
    final String sql = determineSql(timeout);
    SessionFactoryImplementor factory = session.getFactory();
    try {
      try {
        PreparedStatement st =
            session
                .getTransactionCoordinator()
                .getJdbcCoordinator()
                .getStatementPreparer()
                .prepareStatement(sql);
        try {
          getLockable().getIdentifierType().nullSafeSet(st, id, 1, session);
          if (getLockable().isVersioned()) {
            getLockable()
                .getVersionType()
                .nullSafeSet(
                    st,
                    version,
                    getLockable().getIdentifierType().getColumnSpan(factory) + 1,
                    session);
          }

          ResultSet rs =
              session
                  .getTransactionCoordinator()
                  .getJdbcCoordinator()
                  .getResultSetReturn()
                  .extract(st);
          try {
            if (!rs.next()) {
              if (factory.getStatistics().isStatisticsEnabled()) {
                factory.getStatisticsImplementor().optimisticFailure(getLockable().getEntityName());
              }
              throw new StaleObjectStateException(getLockable().getEntityName(), id);
            }
          } finally {
            session.getTransactionCoordinator().getJdbcCoordinator().release(rs, st);
          }
        } finally {
          session.getTransactionCoordinator().getJdbcCoordinator().release(st);
        }
      } catch (SQLException e) {
        throw session
            .getFactory()
            .getSQLExceptionHelper()
            .convert(
                e,
                "could not lock: "
                    + MessageHelper.infoString(getLockable(), id, session.getFactory()),
                sql);
      }
    } catch (JDBCException e) {
      throw new PessimisticEntityLockException(object, "could not obtain pessimistic lock", e);
    }
  }
コード例 #3
0
 private void comparePropertyAndRaiseSOSE(
     Serializable id, Object oldField, SessionFactoryImplementor factory, boolean b) {
   // TODO support other entity modes
   if (b) {
     if (factory.getStatistics().isStatisticsEnabled()) {
       factory.getStatisticsImplementor().optimisticFailure(getEntityName());
     }
     throw new StaleObjectStateException(getEntityName(), id);
   }
 }
コード例 #4
0
 public void checkVersionAndRaiseSOSE(
     Serializable id, Object oldVersion, SessionImplementor session, Tuple resultset) {
   final Object resultSetVersion =
       gridVersionType.nullSafeGet(resultset, getVersionColumnName(), session, null);
   final SessionFactoryImplementor factory = getFactory();
   if (!gridVersionType.isEqual(oldVersion, resultSetVersion, factory)) {
     if (factory.getStatistics().isStatisticsEnabled()) {
       factory.getStatisticsImplementor().optimisticFailure(getEntityName());
     }
     throw new StaleObjectStateException(getEntityName(), id);
   }
 }
  /**
   * Performs the process of loading an entity from the configured underlying datasource.
   *
   * @param event The load event
   * @return The object loaded from the datasource, or null if not found.
   */
  protected Serializable loadFromDatasource(final ResolveNaturalIdEvent event) {
    final SessionFactoryImplementor factory = event.getSession().getFactory();
    final boolean stats = factory.getStatistics().isStatisticsEnabled();
    long startTime = 0;
    if (stats) {
      startTime = System.currentTimeMillis();
    }

    final Serializable pk =
        event
            .getEntityPersister()
            .loadEntityIdByNaturalId(
                event.getOrderedNaturalIdValues(), event.getLockOptions(), event.getSession());

    if (stats) {
      final NaturalIdRegionAccessStrategy naturalIdCacheAccessStrategy =
          event.getEntityPersister().getNaturalIdCacheAccessStrategy();
      final String regionName =
          naturalIdCacheAccessStrategy == null
              ? null
              : naturalIdCacheAccessStrategy.getRegion().getName();

      factory
          .getStatisticsImplementor()
          .naturalIdQueryExecuted(regionName, System.currentTimeMillis() - startTime);
    }

    // PK can be null if the entity doesn't exist
    if (pk != null) {
      event
          .getSession()
          .getPersistenceContext()
          .getNaturalIdHelper()
          .cacheNaturalIdCrossReferenceFromLoad(
              event.getEntityPersister(), pk, event.getOrderedNaturalIdValues());
    }

    return pk;
  }
コード例 #6
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());
    }
  }
コード例 #7
0
  @Override
  public void delete(Serializable id, Object version, Object object, SessionImplementor session)
      throws HibernateException {
    final int span = getTableSpan();
    if (span > 1) {
      throw new HibernateException(
          "Hibernate OGM does not yet support entities spanning multiple tables");
    }
    final EntityMetamodel entityMetamodel = getEntityMetamodel();
    boolean isImpliedOptimisticLocking = !entityMetamodel.isVersioned() && isAllOrDirtyOptLocking();
    Object[] loadedState = null;
    if (isImpliedOptimisticLocking) {
      // need to treat this as if it where optimistic-lock="all" (dirty does *not* make sense);
      // first we need to locate the "loaded" state
      //
      // Note, it potentially could be a proxy, so doAfterTransactionCompletion the location the
      // safe way...
      org.hibernate.engine.spi.EntityKey key = session.generateEntityKey(id, this);
      Object entity = session.getPersistenceContext().getEntity(key);
      if (entity != null) {
        EntityEntry entry = session.getPersistenceContext().getEntry(entity);
        loadedState = entry.getLoadedState();
      }
    }

    final EntityKey key = EntityKeyBuilder.fromPersister(this, id, session);
    final Tuple resultset = gridDialect.getTuple(key, this.getTupleContext());
    final SessionFactoryImplementor factory = getFactory();
    if (isImpliedOptimisticLocking && loadedState != null) {
      // we need to utilize dynamic delete statements
      for (int j = span - 1; j >= 0; j--) {
        boolean[] versionability = getPropertyVersionability();

        // TODO do a diff on the properties value from resultset
        GridType[] types = gridPropertyTypes;

        for (int i = 0; i < entityMetamodel.getPropertySpan(); i++) {
          boolean include = isPropertyOfTable(i, j) && versionability[i];
          if (include) {
            final GridType type = types[i];
            final Object snapshotValue =
                type.nullSafeGet(resultset, getPropertyColumnNames(i), session, object);
            // TODO support other entity modes
            if (!type.isEqual(loadedState[i], snapshotValue, factory)) {
              if (factory.getStatistics().isStatisticsEnabled()) {
                factory.getStatisticsImplementor().optimisticFailure(getEntityName());
              }
              throw new StaleObjectStateException(getEntityName(), id);
            }
          }
        }
      }
    } else {
      if (entityMetamodel.isVersioned()) {
        checkVersionAndRaiseSOSE(id, version, session, resultset);
      }
    }

    for (int j = span - 1; j >= 0; j--) {
      if (isInverseTable(j)) {
        return;
      }
      if (log.isTraceEnabled()) {
        log.trace("Deleting entity: " + MessageHelper.infoString(this, id, factory));
        if (j == 0 && isVersioned()) {
          log.trace("Version: " + version);
        }
      }

      // delete association information
      // needs to be executed before the tuple removal because the AtomicMap in ISPN is cleared upon
      // removal
      new EntityDehydrator()
          .gridDialect(gridDialect)
          .gridPropertyTypes(gridPropertyTypes)
          .gridIdentifierType(gridIdentifierType)
          .id(id)
          .persister(this)
          .resultset(resultset)
          .session(session)
          .tableIndex(j)
          .onlyRemovePropertyMetadata()
          .dehydrate();

      gridDialect.removeTuple(key, getTupleContext());
    }
  }
コード例 #8
0
 /*  33:    */
 /*  34:    */ public void lock(
     Serializable id, Object version, Object object, int timeout, SessionImplementor session)
       /*  35:    */ {
   /*  36: 73 */ String sql = determineSql(timeout);
   /*  37: 74 */ SessionFactoryImplementor factory = session.getFactory();
   /*  38:    */ try
   /*  39:    */ {
     /*  40:    */ try
     /*  41:    */ {
       /*  42: 77 */ PreparedStatement st =
           session
               .getTransactionCoordinator()
               .getJdbcCoordinator()
               .getStatementPreparer()
               .prepareStatement(sql);
       /*  43:    */ try
       /*  44:    */ {
         /*  45: 79 */ getLockable().getIdentifierType().nullSafeSet(st, id, 1, session);
         /*  46: 80 */ if (getLockable().isVersioned()) {
           /*  47: 81 */ getLockable()
               .getVersionType()
               .nullSafeSet(
                   st,
                   version,
                   getLockable().getIdentifierType().getColumnSpan(factory) + 1,
                   session);
           /*  48:    */ }
         /*  49: 89 */ ResultSet rs = st.executeQuery();
         /*  50:    */ try
         /*  51:    */ {
           /*  52: 91 */ if (!rs.next())
           /*  53:    */ {
             /*  54: 92 */ if (factory.getStatistics().isStatisticsEnabled()) {
               /*  55: 93 */ factory
                   .getStatisticsImplementor()
                   .optimisticFailure(getLockable().getEntityName());
               /*  56:    */ }
             /*  57: 96 */ throw new StaleObjectStateException(getLockable().getEntityName(), id);
             /*  58:    */ }
           /*  59:    */ }
         /*  60:    */ finally {
         }
         /*  61:    */ }
       /*  62:    */ finally
       /*  63:    */ {
         /*  64:104 */ st.close();
         /*  65:    */ }
       /*  66:    */ }
     /*  67:    */ catch (SQLException e)
     /*  68:    */ {
       /*  69:109 */ throw session
           .getFactory()
           .getSQLExceptionHelper()
           .convert(
               e,
               "could not lock: "
                   + MessageHelper.infoString(getLockable(), id, session.getFactory()),
               sql);
       /*  70:    */ }
     /*  71:    */ }
   /*  72:    */ catch (JDBCException e)
   /*  73:    */ {
     /*  74:117 */ throw new PessimisticEntityLockException(
         object, "could not obtain pessimistic lock", e);
     /*  75:    */ }
   /*  76:    */ }
コード例 #9
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();
  }
コード例 #10
0
 @Override
 public Statistics getStatistics() {
   return delegate.getStatistics();
 }