Search in sources :

Example 1 with EntityChangedEventInfo

use of com.haulmont.cuba.core.sys.persistence.EntityChangedEventInfo in project cuba by cuba-platform.

the class RdbmsStore method commit.

@Override
@SuppressWarnings("unchecked")
public Set<Entity> commit(CommitContext context) {
    if (log.isDebugEnabled())
        log.debug("commit: commitInstances=" + context.getCommitInstances() + ", removeInstances=" + context.getRemoveInstances());
    Set<Entity> saved = new HashSet<>();
    List<Entity> persisted = new ArrayList<>();
    List<BaseGenericIdEntity> identityEntitiesToStoreDynamicAttributes = new ArrayList<>();
    List<CategoryAttributeValue> attributeValuesToRemove = new ArrayList<>();
    EntityManager em = null;
    boolean softDeletionBefore;
    SavedEntitiesHolder savedEntitiesHolder;
    try (Transaction tx = getSaveTransaction(storeName, context.isJoinTransaction())) {
        em = persistence.getEntityManager(storeName);
        checkPermissions(context);
        softDeletionBefore = em.isSoftDeletion();
        em.setSoftDeletion(context.isSoftDeletion());
        List<BaseGenericIdEntity> entitiesToStoreDynamicAttributes = new ArrayList<>();
        // persist new
        for (Entity entity : context.getCommitInstances()) {
            if (entityStates.isNew(entity)) {
                if (isAuthorizationRequired(context)) {
                    attributeSecurity.beforePersist(entity);
                }
                em.persist(entity);
                saved.add(entity);
                persisted.add(entity);
                if (isAuthorizationRequired(context))
                    checkOperationPermitted(entity, EntityOp.CREATE);
                if (!context.isDiscardCommitted()) {
                    View view = getViewFromContextOrNull(context, entity);
                    entityFetcher.fetch(entity, view, true);
                    attributeSecurity.afterPersist(entity, view);
                }
                if (entityHasDynamicAttributes(entity)) {
                    if (entity instanceof BaseDbGeneratedIdEntity) {
                        identityEntitiesToStoreDynamicAttributes.add((BaseGenericIdEntity) entity);
                    } else {
                        entitiesToStoreDynamicAttributes.add((BaseGenericIdEntity) entity);
                    }
                }
            }
        }
        // merge the rest - instances can be detached or not
        for (Entity entity : context.getCommitInstances()) {
            if (!entityStates.isNew(entity)) {
                if (isAuthorizationRequired(context)) {
                    security.assertToken(entity);
                }
                security.restoreSecurityStateAndFilteredData(entity);
                if (isAuthorizationRequired(context)) {
                    attributeSecurity.beforeMerge(entity);
                }
                Entity merged = em.merge(entity);
                saved.add(merged);
                entityFetcher.fetch(merged, getViewFromContext(context, entity));
                attributeSecurity.afterMerge(merged);
                if (isAuthorizationRequired(context))
                    checkOperationPermitted(merged, EntityOp.UPDATE);
                if (entityHasDynamicAttributes(entity)) {
                    BaseGenericIdEntity originalBaseGenericIdEntity = (BaseGenericIdEntity) entity;
                    BaseGenericIdEntity mergedBaseGenericIdEntity = (BaseGenericIdEntity) merged;
                    mergeDynamicAttributes(originalBaseGenericIdEntity, mergedBaseGenericIdEntity);
                    entitiesToStoreDynamicAttributes.add(mergedBaseGenericIdEntity);
                }
            }
        }
        for (BaseGenericIdEntity entity : entitiesToStoreDynamicAttributes) {
            dynamicAttributesManagerAPI.storeDynamicAttributes(entity);
        }
        // remove
        for (Entity entity : context.getRemoveInstances()) {
            if (isAuthorizationRequired(context)) {
                security.assertToken(entity);
            }
            security.restoreSecurityStateAndFilteredData(entity);
            Entity e;
            if (entity instanceof SoftDelete) {
                attributeSecurity.beforeMerge(entity);
                e = em.merge(entity);
                entityFetcher.fetch(e, getViewFromContext(context, entity));
                attributeSecurity.afterMerge(e);
            } else {
                e = em.merge(entity);
            }
            if (isAuthorizationRequired(context))
                checkOperationPermitted(e, EntityOp.DELETE);
            em.remove(e);
            saved.add(e);
            if (entityHasDynamicAttributes(entity)) {
                Map<String, CategoryAttributeValue> dynamicAttributes = ((BaseGenericIdEntity) entity).getDynamicAttributes();
                // old values of dynamic attributes on deleted entity are used in EntityChangedEvent
                ((BaseGenericIdEntity) e).setDynamicAttributes(dynamicAttributes);
                // noinspection ConstantConditions
                for (CategoryAttributeValue categoryAttributeValue : dynamicAttributes.values()) {
                    if (!entityStates.isNew(categoryAttributeValue)) {
                        if (Stores.isMain(storeName)) {
                            em.remove(categoryAttributeValue);
                        } else {
                            attributeValuesToRemove.add(categoryAttributeValue);
                        }
                        saved.add(categoryAttributeValue);
                    }
                }
            }
        }
        if (!context.isDiscardCommitted() && isAuthorizationRequired(context) && userSessionSource.getUserSession().getConstraints().exists()) {
            security.calculateFilteredData(saved);
        }
        savedEntitiesHolder = SavedEntitiesHolder.setEntities(saved);
        if (context.isJoinTransaction()) {
            List<EntityChangedEventInfo> eventsInfo = entityChangedEventManager.collect(saved);
            persistenceSupport.processFlush(em, false);
            em.getDelegate().flush();
            List<EntityChangedEvent> events = new ArrayList<>(eventsInfo.size());
            for (EntityChangedEventInfo info : eventsInfo) {
                events.add(new EntityChangedEvent(info.getSource(), Id.of(info.getEntity()), info.getType(), info.getChanges()));
            }
            for (Entity entity : saved) {
                detachEntity(em, entity, getViewFromContext(context, entity));
            }
            entityChangedEventManager.publish(events);
        }
        tx.commit();
        if (em != null) {
            em.setSoftDeletion(softDeletionBefore);
        }
    }
    if (!attributeValuesToRemove.isEmpty()) {
        try (Transaction tx = getSaveTransaction(Stores.MAIN, context.isJoinTransaction())) {
            EntityManager entityManager = persistence.getEntityManager();
            for (CategoryAttributeValue entity : attributeValuesToRemove) {
                entityManager.remove(entity);
            }
            tx.commit();
        }
    }
    if (!identityEntitiesToStoreDynamicAttributes.isEmpty()) {
        try (Transaction tx = getSaveTransaction(storeName, context.isJoinTransaction())) {
            for (BaseGenericIdEntity entity : identityEntitiesToStoreDynamicAttributes) {
                dynamicAttributesManagerAPI.storeDynamicAttributes(entity);
            }
            tx.commit();
        }
    }
    Set<Entity> resultEntities = savedEntitiesHolder.getEntities(saved);
    reloadIfUnfetched(resultEntities, context);
    if (!context.isDiscardCommitted() && isAuthorizationRequired(context) && userSessionSource.getUserSession().getConstraints().exists()) {
        security.applyConstraints(resultEntities);
    }
    if (!context.isDiscardCommitted()) {
        if (isAuthorizationRequired(context)) {
            for (Entity entity : resultEntities) {
                if (!persisted.contains(entity)) {
                    attributeSecurity.afterCommit(entity);
                }
            }
        }
        // Update references from newly persisted entities to merged detached entities. Otherwise a new entity can
        // contain a stale instance of a merged one.
        entityReferencesNormalizer.updateReferences(persisted, resultEntities);
    }
    return context.isDiscardCommitted() ? Collections.emptySet() : resultEntities;
}
Also used : EntityChangedEventInfo(com.haulmont.cuba.core.sys.persistence.EntityChangedEventInfo) EntityChangedEvent(com.haulmont.cuba.core.app.events.EntityChangedEvent)

Aggregations

EntityChangedEvent (com.haulmont.cuba.core.app.events.EntityChangedEvent)1 EntityChangedEventInfo (com.haulmont.cuba.core.sys.persistence.EntityChangedEventInfo)1