use of org.hibernate.cache.spi.access.EntityDataAccess in project hibernate-orm by hibernate.
the class EnabledCaching method evictEntityData.
@Override
public void evictEntityData(String entityName, Serializable identifier) {
final EntityPersister entityDescriptor = sessionFactory.getMetamodel().entityPersister(entityName);
final EntityDataAccess cacheAccess = entityDescriptor.getCacheAccessStrategy();
if (cacheAccess == null) {
return;
}
if (LOG.isDebugEnabled()) {
LOG.debugf("Evicting second-level cache: %s", MessageHelper.infoString(entityDescriptor, identifier, sessionFactory));
}
final Object key = cacheAccess.generateCacheKey(identifier, entityDescriptor, sessionFactory, null);
cacheAccess.evict(key);
}
use of org.hibernate.cache.spi.access.EntityDataAccess in project hibernate-orm by hibernate.
the class EnabledCaching method prime.
@Override
public void prime(Set<DomainDataRegionConfig> cacheRegionConfigs) {
for (DomainDataRegionConfig regionConfig : cacheRegionConfigs) {
final DomainDataRegion region = getRegionFactory().buildDomainDataRegion(regionConfig, this);
regionsByName.put(region.getName(), region);
if (!StringTypeDescriptor.INSTANCE.areEqual(region.getName(), regionConfig.getRegionName())) {
throw new HibernateException(String.format(Locale.ROOT, "Region [%s] returned from RegionFactory [%s] was named differently than requested name. Expecting `%s`, but found `%s`", region, getRegionFactory().getClass().getName(), regionConfig.getRegionName(), region.getName()));
}
for (EntityDataCachingConfig entityAccessConfig : regionConfig.getEntityCaching()) {
final EntityDataAccess entityDataAccess = entityAccessMap.put(entityAccessConfig.getNavigableRole(), region.getEntityDataAccess(entityAccessConfig.getNavigableRole()));
legacySecondLevelCacheNames.add(StringHelper.qualifyConditionally(getSessionFactory().getSessionFactoryOptions().getCacheRegionPrefix(), region.getName()));
}
if (regionConfig.getNaturalIdCaching().isEmpty()) {
legacyNaturalIdAccessesForRegion.put(region.getName(), Collections.emptySet());
} else {
final HashSet<NaturalIdDataAccess> accesses = new HashSet<>();
for (NaturalIdDataCachingConfig naturalIdAccessConfig : regionConfig.getNaturalIdCaching()) {
final NaturalIdDataAccess naturalIdDataAccess = naturalIdAccessMap.put(naturalIdAccessConfig.getNavigableRole(), region.getNaturalIdDataAccess(naturalIdAccessConfig.getNavigableRole()));
accesses.add(naturalIdDataAccess);
}
legacyNaturalIdAccessesForRegion.put(region.getName(), accesses);
}
for (CollectionDataCachingConfig collectionAccessConfig : regionConfig.getCollectionCaching()) {
final CollectionDataAccess collectionDataAccess = collectionAccessMap.put(collectionAccessConfig.getNavigableRole(), region.getCollectionDataAccess(collectionAccessConfig.getNavigableRole()));
legacySecondLevelCacheNames.add(StringHelper.qualifyConditionally(getSessionFactory().getSessionFactoryOptions().getCacheRegionPrefix(), region.getName()));
}
}
}
use of org.hibernate.cache.spi.access.EntityDataAccess in project hibernate-orm by hibernate.
the class BatchFetchQueue method isCached.
private boolean isCached(EntityKey entityKey, EntityPersister persister) {
final SharedSessionContractImplementor session = context.getSession();
if (context.getSession().getCacheMode().isGetEnabled() && persister.canReadFromCache()) {
final EntityDataAccess cache = persister.getCacheAccessStrategy();
final Object key = cache.generateCacheKey(entityKey.getIdentifier(), persister, session.getFactory(), session.getTenantIdentifier());
return CacheHelper.fromSharedCache(session, key, cache) != null;
}
return false;
}
use of org.hibernate.cache.spi.access.EntityDataAccess in project hibernate-orm by hibernate.
the class AbstractLockUpgradeEventListener method upgradeLock.
/**
* 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())) {
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 boolean cachingEnabled = persister.canWriteToCache();
SoftLock lock = null;
Object ck = null;
try {
if (cachingEnabled) {
EntityDataAccess cache = persister.getCacheAccessStrategy();
ck = cache.generateCacheKey(entry.getId(), persister, source.getFactory(), source.getTenantIdentifier());
lock = cache.lockItem(source, ck, entry.getVersion());
}
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 {
// so release the soft lock
if (cachingEnabled) {
persister.getCacheAccessStrategy().unlockItem(source, ck, lock);
}
}
}
}
use of org.hibernate.cache.spi.access.EntityDataAccess in project hibernate-orm by hibernate.
the class DefaultRefreshEventListener method onRefresh.
/**
* Handle the given refresh event.
*
* @param event The refresh event to be handled.
*/
public void onRefresh(RefreshEvent event, Map refreshedAlready) {
final EventSource source = event.getSession();
boolean isTransient;
if (event.getEntityName() != null) {
isTransient = !source.contains(event.getEntityName(), event.getObject());
} else {
isTransient = !source.contains(event.getObject());
}
if (source.getPersistenceContext().reassociateIfUninitializedProxy(event.getObject())) {
if (isTransient) {
source.setReadOnly(event.getObject(), source.isDefaultReadOnly());
}
return;
}
final Object object = source.getPersistenceContext().unproxyAndReassociate(event.getObject());
if (refreshedAlready.containsKey(object)) {
LOG.trace("Already refreshed");
return;
}
final EntityEntry e = source.getPersistenceContext().getEntry(object);
final EntityPersister persister;
final Serializable id;
if (e == null) {
persister = source.getEntityPersister(event.getEntityName(), object);
// refresh() does not pass an entityName
id = persister.getIdentifier(object, event.getSession());
if (LOG.isTraceEnabled()) {
LOG.tracev("Refreshing transient {0}", MessageHelper.infoString(persister, id, source.getFactory()));
}
final EntityKey key = source.generateEntityKey(id, persister);
if (source.getPersistenceContext().getEntry(key) != null) {
throw new PersistentObjectException("attempted to refresh transient instance when persistent instance was already associated with the Session: " + MessageHelper.infoString(persister, id, source.getFactory()));
}
} else {
if (LOG.isTraceEnabled()) {
LOG.tracev("Refreshing ", MessageHelper.infoString(e.getPersister(), e.getId(), source.getFactory()));
}
if (!e.isExistsInDatabase()) {
throw new UnresolvableObjectException(e.getId(), "this instance does not yet exist as a row in the database");
}
persister = e.getPersister();
id = e.getId();
}
// cascade the refresh prior to refreshing this entity
refreshedAlready.put(object, object);
Cascade.cascade(CascadingActions.REFRESH, CascadePoint.BEFORE_REFRESH, source, persister, object, refreshedAlready);
if (e != null) {
final EntityKey key = source.generateEntityKey(id, persister);
source.getPersistenceContext().removeEntity(key);
if (persister.hasCollections()) {
new EvictVisitor(source, object).process(object, persister);
}
}
if (persister.canWriteToCache()) {
Object previousVersion = null;
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(object);
}
final EntityDataAccess cache = persister.getCacheAccessStrategy();
final Object ck = cache.generateCacheKey(id, persister, source.getFactory(), source.getTenantIdentifier());
final SoftLock lock = cache.lockItem(source, ck, previousVersion);
cache.remove(source, ck);
source.getActionQueue().registerProcess((success, session) -> cache.unlockItem(session, ck, lock));
}
evictCachedCollections(persister, id, source);
String previousFetchProfile = source.getLoadQueryInfluencers().getInternalFetchProfile();
source.getLoadQueryInfluencers().setInternalFetchProfile("refresh");
Object result = persister.load(id, object, event.getLockOptions(), source);
// If it was transient, then set it to the default for the source.
if (result != null) {
if (!persister.isMutable()) {
// this is probably redundant; it should already be read-only
source.setReadOnly(result, true);
} else {
source.setReadOnly(result, (e == null ? source.isDefaultReadOnly() : e.isReadOnly()));
}
}
source.getLoadQueryInfluencers().setInternalFetchProfile(previousFetchProfile);
UnresolvableObjectException.throwIfNull(result, id, persister.getEntityName());
}
Aggregations