use of org.hibernate.cache.spi.entry.CacheEntry in project hibernate-orm by hibernate.
the class ReadWriteTest method testQueryCacheInvalidation.
@Test
public void testQueryCacheInvalidation() throws Exception {
Statistics stats = sessionFactory().getStatistics();
stats.clear();
SecondLevelCacheStatistics slcs = stats.getSecondLevelCacheStatistics(Item.class.getName());
sessionFactory().getCache().evictEntityRegion(Item.class.getName());
TIME_SERVICE.advance(1);
assertEquals(0, slcs.getPutCount());
assertEquals(0, slcs.getElementCountInMemory());
assertEquals(0, slcs.getEntries().size());
ByRef<Long> idRef = new ByRef<>(null);
withTxSession(s -> {
Item item = new Item();
item.setName("widget");
item.setDescription("A really top-quality, full-featured widget.");
s.persist(item);
idRef.set(item.getId());
});
assertEquals(1, slcs.getPutCount());
assertEquals(1, slcs.getElementCountInMemory());
assertEquals(1, slcs.getEntries().size());
withTxSession(s -> {
Item item = s.get(Item.class, idRef.get());
assertEquals(slcs.getHitCount(), 1);
assertEquals(slcs.getMissCount(), 0);
item.setDescription("A bog standard item");
});
assertEquals(slcs.getPutCount(), 2);
CacheEntry entry = (CacheEntry) slcs.getEntries().get(idRef.get());
Serializable[] ser = entry.getDisassembledState();
assertTrue(ser[0].equals("widget"));
assertTrue(ser[1].equals("A bog standard item"));
withTxSession(s -> {
Item item = s.load(Item.class, idRef.get());
s.delete(item);
});
}
use of org.hibernate.cache.spi.entry.CacheEntry in project hibernate-orm by hibernate.
the class TwoPhaseLoad method doInitializeEntity.
private static void doInitializeEntity(final Object entity, final EntityEntry entityEntry, final boolean readOnly, final SharedSessionContractImplementor session, final PreLoadEvent preLoadEvent) throws HibernateException {
final PersistenceContext persistenceContext = session.getPersistenceContext();
final EntityPersister persister = entityEntry.getPersister();
final Serializable id = entityEntry.getId();
final Object[] hydratedState = entityEntry.getLoadedState();
final boolean debugEnabled = LOG.isDebugEnabled();
if (debugEnabled) {
LOG.debugf("Resolving associations for %s", MessageHelper.infoString(persister, id, session.getFactory()));
}
String entityName = persister.getEntityName();
String[] propertyNames = persister.getPropertyNames();
final Type[] types = persister.getPropertyTypes();
for (int i = 0; i < hydratedState.length; i++) {
final Object value = hydratedState[i];
Boolean overridingEager = getOverridingEager(session, entityName, propertyNames[i], types[i]);
if (value == LazyPropertyInitializer.UNFETCHED_PROPERTY) {
// No resolution is necessary, unless the lazy property is a collection.
if (types[i].isCollectionType()) {
// IMPLEMENTATION NOTE: this is a lazy collection property on a bytecode-enhanced entity.
// HHH-10989: We need to resolve the collection so that a CollectionReference is added to StatefulPersistentContext.
// As mentioned above, hydratedState[i] needs to remain LazyPropertyInitializer.UNFETCHED_PROPERTY
// so do not assign the resolved, unitialized PersistentCollection back to hydratedState[i].
types[i].resolve(value, session, entity, overridingEager);
}
} else if (value != PropertyAccessStrategyBackRefImpl.UNKNOWN) {
// we know value != LazyPropertyInitializer.UNFETCHED_PROPERTY
hydratedState[i] = types[i].resolve(value, session, entity, overridingEager);
}
}
// Must occur after resolving identifiers!
if (session.isEventSource()) {
preLoadEvent.setEntity(entity).setState(hydratedState).setId(id).setPersister(persister);
final EventListenerGroup<PreLoadEventListener> listenerGroup = session.getFactory().getServiceRegistry().getService(EventListenerRegistry.class).getEventListenerGroup(EventType.PRE_LOAD);
for (PreLoadEventListener listener : listenerGroup.listeners()) {
listener.onPreLoad(preLoadEvent);
}
}
persister.setPropertyValues(entity, hydratedState);
final SessionFactoryImplementor factory = session.getFactory();
if (persister.canWriteToCache() && session.getCacheMode().isPutEnabled()) {
if (debugEnabled) {
LOG.debugf("Adding entity to second-level cache: %s", MessageHelper.infoString(persister, id, session.getFactory()));
}
final Object version = Versioning.getVersion(hydratedState, persister);
final CacheEntry entry = persister.buildCacheEntry(entity, hydratedState, version, session);
final EntityDataAccess cache = persister.getCacheAccessStrategy();
final Object cacheKey = cache.generateCacheKey(id, persister, factory, session.getTenantIdentifier());
// we need to be careful not to clobber the lock here in the cache so that it can be rolled back if need be
if (session.getPersistenceContext().wasInsertedDuringTransaction(persister, id)) {
cache.update(session, cacheKey, persister.getCacheEntryStructure().structure(entry), version, version);
} else {
final SessionEventListenerManager eventListenerManager = session.getEventListenerManager();
try {
eventListenerManager.cachePutStart();
final boolean put = cache.putFromLoad(session, cacheKey, persister.getCacheEntryStructure().structure(entry), version, useMinimalPuts(session, entityEntry));
if (put && factory.getStatistics().isStatisticsEnabled()) {
factory.getStatistics().entityCachePut(StatsHelper.INSTANCE.getRootEntityRole(persister), cache.getRegion().getName());
}
} finally {
eventListenerManager.cachePutEnd();
}
}
}
if (persister.hasNaturalIdentifier()) {
persistenceContext.getNaturalIdHelper().cacheNaturalIdCrossReferenceFromLoad(persister, id, persistenceContext.getNaturalIdHelper().extractNaturalIdValues(hydratedState, persister));
}
boolean isReallyReadOnly = readOnly;
if (!persister.isMutable()) {
isReallyReadOnly = true;
} else {
final Object proxy = persistenceContext.getProxy(entityEntry.getEntityKey());
if (proxy != null) {
// there is already a proxy for this impl
// only set the status to read-only if the proxy is read-only
isReallyReadOnly = ((HibernateProxy) proxy).getHibernateLazyInitializer().isReadOnly();
}
}
if (isReallyReadOnly) {
// no need to take a snapshot - this is a
// performance optimization, but not really
// important, except for entities with huge
// mutable property values
persistenceContext.setEntryStatus(entityEntry, Status.READ_ONLY);
} else {
// take a snapshot
TypeHelper.deepCopy(hydratedState, persister.getPropertyTypes(), persister.getPropertyUpdateability(), // after setting values to object
hydratedState, session);
persistenceContext.setEntryStatus(entityEntry, Status.MANAGED);
}
persister.afterInitialize(entity, session);
if (debugEnabled) {
LOG.debugf("Done materializing entity %s", MessageHelper.infoString(persister, id, session.getFactory()));
}
if (factory.getStatistics().isStatisticsEnabled()) {
factory.getStatistics().loadEntity(persister.getEntityName());
}
}
use of org.hibernate.cache.spi.entry.CacheEntry in project hibernate-orm by hibernate.
the class EntityInsertAction method execute.
@Override
public void execute() throws HibernateException {
nullifyTransientReferencesIfNotAlready();
final EntityPersister persister = getPersister();
final SharedSessionContractImplementor session = getSession();
final Object instance = getInstance();
final Serializable id = getId();
final boolean veto = preInsert();
if (!veto) {
persister.insert(id, getState(), instance, session);
PersistenceContext persistenceContext = session.getPersistenceContext();
final EntityEntry entry = persistenceContext.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);
}
persistenceContext.registerInsertedKey(persister, getId());
}
final SessionFactoryImplementor factory = session.getFactory();
if (isCachePutEnabled(persister, session)) {
final CacheEntry ce = persister.buildCacheEntry(instance, getState(), version, session);
cacheEntry = persister.getCacheEntryStructure().structure(ce);
final EntityDataAccess cache = persister.getCacheAccessStrategy();
final Object ck = cache.generateCacheKey(id, persister, factory, session.getTenantIdentifier());
final boolean put = cacheInsert(persister, ck);
if (put && factory.getStatistics().isStatisticsEnabled()) {
factory.getStatistics().entityCachePut(StatsHelper.INSTANCE.getRootEntityRole(persister), cache.getRegion().getName());
}
}
handleNaturalIdPostSaveNotifications(id);
postInsert();
if (factory.getStatistics().isStatisticsEnabled() && !veto) {
factory.getStatistics().insertEntity(getPersister().getEntityName());
}
markExecuted();
}
use of org.hibernate.cache.spi.entry.CacheEntry in project hibernate-orm by hibernate.
the class ReadWriteTest method testStaleWritesLeaveCacheConsistent.
@Test
public void testStaleWritesLeaveCacheConsistent() throws Exception {
Statistics stats = sessionFactory().getStatistics();
stats.clear();
ByRef<VersionedItem> itemRef = new ByRef<>(null);
withTxSession(s -> {
VersionedItem item = new VersionedItem();
item.setName("steve");
item.setDescription("steve's item");
s.save(item);
itemRef.set(item);
});
final VersionedItem item = itemRef.get();
Long initialVersion = item.getVersion();
// manually revert the version property
item.setVersion(new Long(item.getVersion().longValue() - 1));
try {
withTxSession(s -> s.update(item));
fail("expected stale write to fail");
} catch (Exception e) {
log.debug("Rollback was expected", e);
}
// check the version value in the cache...
SecondLevelCacheStatistics slcs = stats.getSecondLevelCacheStatistics(VersionedItem.class.getName());
Object entry = slcs.getEntries().get(item.getId());
Long cachedVersionValue;
cachedVersionValue = (Long) ((CacheEntry) entry).getVersion();
assertEquals(initialVersion.longValue(), cachedVersionValue.longValue());
withTxSession(s -> {
VersionedItem item2 = s.load(VersionedItem.class, item.getId());
s.delete(item2);
});
}
use of org.hibernate.cache.spi.entry.CacheEntry in project hibernate-orm by hibernate.
the class Loader method instanceNotYetLoaded.
/**
* The entity instance is not in the session cache
*/
private Object instanceNotYetLoaded(final ResultSet rs, final int i, final Loadable persister, final String rowIdAlias, final EntityKey key, final LockMode lockMode, final EntityKey optionalObjectKey, final Object optionalObject, final List hydratedObjects, final SharedSessionContractImplementor session) throws HibernateException, SQLException {
final String instanceClass = getInstanceClass(rs, i, persister, key.getIdentifier(), session);
// see if the entity defines reference caching, and if so use the cached reference (if one).
if (session.getCacheMode().isGetEnabled() && persister.canUseReferenceCacheEntries()) {
final EntityDataAccess cache = persister.getCacheAccessStrategy();
final Object ck = cache.generateCacheKey(key.getIdentifier(), persister, session.getFactory(), session.getTenantIdentifier());
final Object cachedEntry = CacheHelper.fromSharedCache(session, ck, cache);
if (cachedEntry != null) {
CacheEntry entry = (CacheEntry) persister.getCacheEntryStructure().destructure(cachedEntry, factory);
return ((ReferenceCacheEntryImpl) entry).getReference();
}
}
final Object object;
if (optionalObjectKey != null && key.equals(optionalObjectKey)) {
// its the given optional object
object = optionalObject;
} else {
// instantiate a new instance
object = session.instantiate(instanceClass, key.getIdentifier());
}
// need to hydrate it.
// grab its state from the ResultSet and keep it in the Session
// (but don't yet initialize the object itself)
// note that we acquire LockMode.READ even if it was not requested
LockMode acquiredLockMode = lockMode == LockMode.NONE ? LockMode.READ : lockMode;
loadFromResultSet(rs, i, object, instanceClass, key, rowIdAlias, acquiredLockMode, persister, session);
// materialize associations (and initialize the object) later
hydratedObjects.add(object);
return object;
}
Aggregations