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); } }
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); } }
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; }
@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()); } }
@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()); } }
/* 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: */ }
@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(); }
@Override public Statistics getStatistics() { return delegate.getStatistics(); }