use of org.hibernate.reactive.persister.entity.impl.ReactiveEntityPersister in project hibernate-reactive by hibernate.
the class ReactiveStatelessSessionImpl method reactiveGet.
@Override
public <T> CompletionStage<T> reactiveGet(Class<? extends T> entityClass, Object id, LockMode lockMode, EntityGraph<T> fetchGraph) {
checkOpen();
if (fetchGraph != null) {
getLoadQueryInfluencers().getEffectiveEntityGraph().applyGraph((RootGraphImplementor<T>) fetchGraph, GraphSemantic.FETCH);
}
ReactiveEntityPersister persister = (ReactiveEntityPersister) getFactory().getMetamodel().entityPersister(entityClass);
LockOptions lockOptions = getNullSafeLockOptions(lockMode);
return persister.reactiveLoad((Serializable) id, null, lockOptions, this).whenComplete((v, e) -> {
if (getPersistenceContext().isLoadFinished()) {
getPersistenceContext().clear();
}
getLoadQueryInfluencers().getEffectiveEntityGraph().clear();
}).thenApply(entity -> (T) entity);
}
use of org.hibernate.reactive.persister.entity.impl.ReactiveEntityPersister in project hibernate-reactive by hibernate.
the class DefaultReactiveLockEventListener method doUpgradeLock.
private CompletionStage<Void> doUpgradeLock(Object object, EntityEntry entry, LockOptions lockOptions, EventSource source) {
final EntityPersister persister = entry.getPersister();
final boolean canWriteToCache = persister.canWriteToCache();
final SoftLock lock;
final Object cacheKey;
if (canWriteToCache) {
EntityDataAccess cache = persister.getCacheAccessStrategy();
cacheKey = cache.generateCacheKey(entry.getId(), persister, source.getFactory(), source.getTenantIdentifier());
lock = cache.lockItem(source, cacheKey, entry.getVersion());
} else {
cacheKey = null;
lock = null;
}
try {
return ((ReactiveEntityPersister) persister).lockReactive(entry.getId(), entry.getVersion(), object, lockOptions, source).thenAccept(v -> entry.setLockMode(lockOptions.getLockMode())).whenComplete((r, e) -> {
// so release the soft lock
if (canWriteToCache) {
persister.getCacheAccessStrategy().unlockItem(source, cacheKey, lock);
}
});
} catch (HibernateException he) {
// in case lockReactive() throws an exception
if (canWriteToCache) {
persister.getCacheAccessStrategy().unlockItem(source, cacheKey, lock);
}
throw he;
}
}
use of org.hibernate.reactive.persister.entity.impl.ReactiveEntityPersister in project hibernate-reactive by hibernate.
the class DefaultReactiveLoadEventListener method loadFromDatasource.
/**
* Performs the process of loading an entity from the configured
* underlying datasource.
*
* @param event The load event
* @param persister The persister for the entity being requested for load
*
* @return The object loaded from the datasource, or null if not found.
*/
protected CompletionStage<Object> loadFromDatasource(LoadEvent event, EntityPersister persister) {
CompletionStage<Object> entity = ((ReactiveEntityPersister) persister).reactiveLoad(event.getEntityId(), event.getInstanceToLoad(), event.getLockOptions(), event.getSession());
final StatisticsImplementor statistics = event.getSession().getFactory().getStatistics();
if (event.isAssociationFetch() && statistics.isStatisticsEnabled()) {
statistics.fetchEntity(event.getEntityClassName());
}
return entity;
}
use of org.hibernate.reactive.persister.entity.impl.ReactiveEntityPersister in project hibernate-reactive by hibernate.
the class EntityTypes method loadByUniqueKey.
/**
* Load an instance by a unique key that is not the primary key.
*
* @param entityType The {@link EntityType} of the association
* @param key The unique key property value.
* @param session The originating session.
*
* @return The loaded entity
*
* @throws HibernateException generally indicates problems performing the load.
*/
static CompletionStage<Object> loadByUniqueKey(EntityType entityType, Object key, SharedSessionContractImplementor session) throws HibernateException {
SessionFactoryImplementor factory = session.getFactory();
String entityName = entityType.getAssociatedEntityName();
String uniqueKeyPropertyName = entityType.getRHSUniqueKeyPropertyName();
ReactiveEntityPersister persister = (ReactiveEntityPersister) factory.getMetamodel().entityPersister(entityName);
// TODO: implement 2nd level caching?! natural id caching ?! proxies?!
EntityUniqueKey euk = new EntityUniqueKey(entityName, uniqueKeyPropertyName, key, entityType.getIdentifierOrUniqueKeyType(factory), persister.getEntityMode(), factory);
PersistenceContext persistenceContext = session.getPersistenceContextInternal();
Object result = persistenceContext.getEntity(euk);
if (result != null) {
return completedFuture(persistenceContext.proxyFor(result));
} else {
return persister.reactiveLoadByUniqueKey(uniqueKeyPropertyName, key, session).thenApply(loaded -> {
// add it to the Persistence Context
if (loaded != null) {
persistenceContext.addEntity(euk, loaded);
}
return loaded;
});
}
}
use of org.hibernate.reactive.persister.entity.impl.ReactiveEntityPersister in project hibernate-reactive by hibernate.
the class ReactiveEntityUpdateAction method reactiveExecute.
@Override
public CompletionStage<Void> reactiveExecute() 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 = getPreviousVersion();
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());
setLock(cache.lockItem(session, ck, previousVersion));
} else {
ck = null;
}
ReactiveEntityPersister reactivePersister = (ReactiveEntityPersister) persister;
CompletionStage<Void> update = veto ? voidFuture() : reactivePersister.updateReactive(id, getState(), getDirtyFields(), hasDirtyCollection(), getPreviousState(), previousVersion, instance, getRowId(), session);
return update.thenApply(res -> {
final EntityEntry entry = session.getPersistenceContextInternal().getEntry(instance);
if (entry == null) {
throw new AssertionFailure("possible non-threadsafe access to session");
}
return entry;
}).thenCompose(entry -> {
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(getState(), persister.getPropertyTypes(), persister.getPropertyCheckability(), getState(), session);
return processGeneratedProperties(id, reactivePersister, session, instance).thenAccept(v -> entry.postUpdate(instance, getState(), getNextVersion())).thenApply(v -> entry);
}
return completedFuture(entry);
}).thenAccept(entry -> {
final StatisticsImplementor statistics = factory.getStatistics();
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, getState(), getNextVersion(), getSession());
setCacheEntry(persister.getCacheEntryStructure().structure(ce));
final boolean put = cacheUpdate(persister, getPreviousVersion(), ck);
if (put && statistics.isStatisticsEnabled()) {
statistics.entityCachePut(StatsHelper.INSTANCE.getRootEntityRole(persister), getPersister().getCacheAccessStrategy().getRegion().getName());
}
}
}
session.getPersistenceContextInternal().getNaturalIdHelper().manageSharedNaturalIdCrossReference(persister, id, getState(), getPreviousNaturalIdValues(), CachedNaturalIdValueSource.UPDATE);
postUpdate();
if (statistics.isStatisticsEnabled() && !veto) {
statistics.updateEntity(getPersister().getEntityName());
}
});
}
Aggregations