use of org.hibernate.event.internal.EntityState.DETACHED in project hibernate-reactive by hibernate.
the class DefaultReactiveMergeEventListener method entityIsDetached.
protected CompletionStage<Void> entityIsDetached(MergeEvent event, MergeContext copyCache) {
LOG.trace("Merging detached instance");
final Object entity = event.getEntity();
final EventSource source = event.getSession();
final EntityPersister persister = source.getEntityPersister(event.getEntityName(), entity);
final String entityName = persister.getEntityName();
Serializable requestedId = event.getRequestedId();
Serializable id;
if (requestedId == null) {
id = persister.getIdentifier(entity, source);
} else {
id = requestedId;
// check that entity id = requestedId
Serializable entityId = persister.getIdentifier(entity, source);
if (!persister.getIdentifierType().isEqual(id, entityId, source.getFactory())) {
throw LOG.mergeRequestedIdNotMatchingIdOfPassedEntity();
}
}
String previousFetchProfile = source.getLoadQueryInfluencers().getInternalFetchProfile();
source.getLoadQueryInfluencers().setInternalFetchProfile("merge");
// we must clone embedded composite identifiers, or
// we will get back the same instance that we pass in
final Serializable clonedIdentifier = (Serializable) persister.getIdentifierType().deepCopy(id, source.getFactory());
return source.unwrap(ReactiveSession.class).reactiveGet((Class<?>) persister.getMappedClass(), clonedIdentifier).thenCompose(result -> {
if (result != null) {
// before cascade!
copyCache.put(entity, result, true);
Object target = unproxyManagedForDetachedMerging(entity, result, persister, source);
if (target == entity) {
throw new AssertionFailure("entity was not detached");
} else if (!source.getEntityName(target).equals(entityName)) {
throw new WrongClassException("class of the given object did not match class of persistent copy", event.getRequestedId(), entityName);
} else if (isVersionChanged(entity, source, persister, target)) {
final StatisticsImplementor statistics = source.getFactory().getStatistics();
if (statistics.isStatisticsEnabled()) {
statistics.optimisticFailure(entityName);
}
throw new StaleObjectStateException(entityName, id);
}
// copy created before we actually copy
return cascadeOnMerge(source, persister, entity, copyCache).thenCompose(v -> fetchAndCopyValues(persister, entity, target, source, copyCache)).thenAccept(v -> {
// copyValues() (called by fetchAndCopyValues) works by reflection,
// so explicitly mark the entity instance dirty
markInterceptorDirty(entity, target, persister);
event.setResult(result);
});
} else {
// really persistent
return entityIsTransient(event, copyCache);
}
}).whenComplete((v, e) -> source.getLoadQueryInfluencers().setInternalFetchProfile(previousFetchProfile));
}
Aggregations