use of org.hibernate.cache.spi.entry.CacheEntry in project hibernate-orm by hibernate.
the class AbstractEntityPersister method initializeLazyProperty.
public Object initializeLazyProperty(String fieldName, Object entity, SharedSessionContractImplementor session) {
final EntityEntry entry = session.getPersistenceContext().getEntry(entity);
final InterceptorImplementor interceptor = ((PersistentAttributeInterceptable) entity).$$_hibernate_getInterceptor();
assert interceptor != null : "Expecting bytecode interceptor to be non-null";
if (hasCollections()) {
final Type type = getPropertyType(fieldName);
if (type.isCollectionType()) {
// we have a condition where a collection attribute is being access via enhancement:
// we can circumvent all the rest and just return the PersistentCollection
final CollectionType collectionType = (CollectionType) type;
final CollectionPersister persister = factory.getMetamodel().collectionPersister(collectionType.getRole());
// Get/create the collection, and make sure it is initialized! This initialized part is
// different from proxy-based scenarios where we have to create the PersistentCollection
// reference "ahead of time" to add as a reference to the proxy. For bytecode solutions
// we are not creating the PersistentCollection ahead of time, but instead we are creating
// it on first request through the enhanced entity.
// see if there is already a collection instance associated with the session
// NOTE : can this ever happen?
final Serializable key = getCollectionKey(persister, entity, entry, session);
PersistentCollection collection = session.getPersistenceContext().getCollection(new CollectionKey(persister, key));
if (collection == null) {
collection = collectionType.instantiate(session, persister, key);
collection.setOwner(entity);
session.getPersistenceContext().addUninitializedCollection(persister, collection, key);
}
// HHH-11161 Initialize, if the collection is not extra lazy
if (!persister.isExtraLazy()) {
session.initializeCollection(collection, false);
}
interceptor.attributeInitialized(fieldName);
if (collectionType.isArrayType()) {
session.getPersistenceContext().addCollectionHolder(collection);
}
// update the "state" of the entity's EntityEntry to over-write UNFETCHED_PROPERTY reference
// for the collection to the just loaded collection
final EntityEntry ownerEntry = session.getPersistenceContext().getEntry(entity);
if (ownerEntry == null) {
// not good
throw new AssertionFailure("Could not locate EntityEntry for the collection owner in the PersistenceContext");
}
ownerEntry.overwriteLoadedStateCollectionValue(fieldName, collection);
// EARLY EXIT!!!
return collection;
}
}
final Serializable id = session.getContextEntityIdentifier(entity);
if (entry == null) {
throw new HibernateException("entity is not associated with the session: " + id);
}
if (LOG.isTraceEnabled()) {
LOG.tracev("Initializing lazy properties of: {0}, field access: {1}", MessageHelper.infoString(this, id, getFactory()), fieldName);
}
if (session.getCacheMode().isGetEnabled() && canReadFromCache() && isLazyPropertiesCacheable()) {
final EntityDataAccess cacheAccess = getCacheAccessStrategy();
final Object cacheKey = cacheAccess.generateCacheKey(id, this, session.getFactory(), session.getTenantIdentifier());
final Object ce = CacheHelper.fromSharedCache(session, cacheKey, cacheAccess);
if (ce != null) {
final CacheEntry cacheEntry = (CacheEntry) getCacheEntryStructure().destructure(ce, factory);
final Object initializedValue = initializeLazyPropertiesFromCache(fieldName, entity, session, entry, cacheEntry);
interceptor.attributeInitialized(fieldName);
// NOTE EARLY EXIT!!!
return initializedValue;
}
}
return initializeLazyPropertiesFromDatastore(fieldName, entity, session, id, entry);
}
use of org.hibernate.cache.spi.entry.CacheEntry in project hibernate-orm by hibernate.
the class EntityUpdateAction method execute.
@Override
public void execute() throws HibernateException {
final Serializable id = getId();
final EntityPersister persister = getPersister();
final SharedSessionContractImplementor 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.canWriteToCache()) {
final EntityDataAccess 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.canWriteToCache()) {
if (persister.isCacheInvalidationRequired() || entry.getStatus() != Status.MANAGED) {
persister.getCacheAccessStrategy().remove(session, ck);
} else if (session.getCacheMode().isPutEnabled()) {
// 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.getStatistics().entityCachePut(StatsHelper.INSTANCE.getRootEntityRole(persister), getPersister().getCacheAccessStrategy().getRegion().getName());
}
}
}
session.getPersistenceContext().getNaturalIdHelper().manageSharedNaturalIdCrossReference(persister, id, state, previousNaturalIdValues, CachedNaturalIdValueSource.UPDATE);
postUpdate();
if (factory.getStatistics().isStatisticsEnabled() && !veto) {
factory.getStatistics().updateEntity(getPersister().getEntityName());
}
}
Aggregations