Search in sources :

Example 1 with StateCommitter

use of org.qi4j.spi.entitystore.StateCommitter in project qi4j-sdk by Qi4j.

the class UnitOfWorkInstance method complete.

public void complete() throws UnitOfWorkCompletionException {
    checkOpen();
    // Copy list so that it cannot be modified during completion
    List<UnitOfWorkCallback> currentCallbacks = callbacks == null ? null : new ArrayList<>(callbacks);
    // Commit state to EntityStores
    List<StateCommitter> committers = applyChanges();
    // Check callbacks
    notifyBeforeCompletion(currentCallbacks);
    // Commit all changes
    for (StateCommitter committer : committers) {
        committer.commit();
    }
    close();
    // Call callbacks
    notifyAfterCompletion(currentCallbacks, COMPLETED);
    callbacks = currentCallbacks;
}
Also used : UnitOfWorkCallback(org.qi4j.api.unitofwork.UnitOfWorkCallback) StateCommitter(org.qi4j.spi.entitystore.StateCommitter)

Example 2 with StateCommitter

use of org.qi4j.spi.entitystore.StateCommitter in project qi4j-sdk by Qi4j.

the class PreferencesEntityStoreMixin method applyChanges.

@Override
public StateCommitter applyChanges(final EntityStoreUnitOfWork unitofwork, final Iterable<EntityState> state) {
    return new StateCommitter() {

        @Override
        public void commit() {
            try {
                synchronized (root) {
                    for (EntityState entityState : state) {
                        DefaultEntityState state = (DefaultEntityState) entityState;
                        if (state.status().equals(EntityStatus.NEW)) {
                            Preferences entityPrefs = root.node(state.identity().identity());
                            writeEntityState(state, entityPrefs, unitofwork.identity(), unitofwork.currentTime());
                        } else if (state.status().equals(EntityStatus.UPDATED)) {
                            Preferences entityPrefs = root.node(state.identity().identity());
                            writeEntityState(state, entityPrefs, unitofwork.identity(), unitofwork.currentTime());
                        } else if (state.status().equals(EntityStatus.REMOVED)) {
                            root.node(state.identity().identity()).removeNode();
                        }
                    }
                    root.flush();
                }
            } catch (BackingStoreException e) {
                throw new EntityStoreException(e);
            }
        }

        @Override
        public void cancel() {
        }
    };
}
Also used : DefaultEntityState(org.qi4j.spi.entitystore.helpers.DefaultEntityState) BackingStoreException(java.util.prefs.BackingStoreException) StateCommitter(org.qi4j.spi.entitystore.StateCommitter) EntityState(org.qi4j.spi.entity.EntityState) DefaultEntityState(org.qi4j.spi.entitystore.helpers.DefaultEntityState) EntityStoreException(org.qi4j.spi.entitystore.EntityStoreException) Preferences(java.util.prefs.Preferences)

Example 3 with StateCommitter

use of org.qi4j.spi.entitystore.StateCommitter in project qi4j-sdk by Qi4j.

the class UnitOfWorkInstance method applyChanges.

private List<StateCommitter> applyChanges() throws UnitOfWorkCompletionException {
    List<StateCommitter> committers = new ArrayList<>();
    for (EntityStoreUnitOfWork entityStoreUnitOfWork : storeUnitOfWork.values()) {
        try {
            StateCommitter committer = entityStoreUnitOfWork.applyChanges();
            committers.add(committer);
        } catch (Exception e) {
            // Cancel all previously prepared stores
            for (StateCommitter committer : committers) {
                committer.cancel();
            }
            if (e instanceof ConcurrentEntityStateModificationException) {
                // If we cancelled due to concurrent modification, then create the proper exception for it!
                ConcurrentEntityStateModificationException mee = (ConcurrentEntityStateModificationException) e;
                Collection<EntityReference> modifiedEntityIdentities = mee.modifiedEntities();
                Collection<EntityComposite> modifiedEntities = new ArrayList<>();
                for (EntityReference modifiedEntityIdentity : modifiedEntityIdentities) {
                    Collection<EntityInstance> instances = instanceCache.values();
                    for (EntityInstance instance : instances) {
                        if (instance.identity().equals(modifiedEntityIdentity)) {
                            modifiedEntities.add(instance.<EntityComposite>proxy());
                        }
                    }
                }
                throw new ConcurrentEntityModificationException(modifiedEntities);
            } else {
                throw new UnitOfWorkCompletionException(e);
            }
        }
    }
    return committers;
}
Also used : EntityComposite(org.qi4j.api.entity.EntityComposite) EntityStoreUnitOfWork(org.qi4j.spi.entitystore.EntityStoreUnitOfWork) ArrayList(java.util.ArrayList) EntityInstance(org.qi4j.runtime.entity.EntityInstance) ConcurrentEntityModificationException(org.qi4j.api.unitofwork.ConcurrentEntityModificationException) UnitOfWorkCompletionException(org.qi4j.api.unitofwork.UnitOfWorkCompletionException) UnitOfWorkException(org.qi4j.api.unitofwork.UnitOfWorkException) EntityTypeNotFoundException(org.qi4j.api.unitofwork.EntityTypeNotFoundException) NoSuchEntityException(org.qi4j.api.unitofwork.NoSuchEntityException) ConcurrentEntityStateModificationException(org.qi4j.spi.entitystore.ConcurrentEntityStateModificationException) EntityNotFoundException(org.qi4j.spi.entitystore.EntityNotFoundException) ConcurrentEntityModificationException(org.qi4j.api.unitofwork.ConcurrentEntityModificationException) UnitOfWorkCompletionException(org.qi4j.api.unitofwork.UnitOfWorkCompletionException) ConcurrentEntityStateModificationException(org.qi4j.spi.entitystore.ConcurrentEntityStateModificationException) EntityReference(org.qi4j.api.entity.EntityReference) Collection(java.util.Collection) StateCommitter(org.qi4j.spi.entitystore.StateCommitter)

Example 4 with StateCommitter

use of org.qi4j.spi.entitystore.StateCommitter in project qi4j-sdk by Qi4j.

the class SQLEntityStoreMixin method applyChanges.

@Override
public StateCommitter applyChanges(final EntityStoreUnitOfWork unitofwork, final Iterable<EntityState> states) {
    return new StateCommitter() {

        @Override
        public void commit() {
            Connection connection = null;
            PreparedStatement insertPS = null;
            PreparedStatement updatePS = null;
            PreparedStatement removePS = null;
            try {
                connection = database.getConnection();
                connection.setAutoCommit(false);
                insertPS = database.prepareInsertEntityStatement(connection);
                updatePS = database.prepareUpdateEntityStatement(connection);
                removePS = database.prepareRemoveEntityStatement(connection);
                for (EntityState state : states) {
                    EntityStatus status = state.status();
                    DefaultEntityState defState = ((SQLEntityState) state).getDefaultEntityState();
                    Long entityPK = ((SQLEntityState) state).getEntityPK();
                    if (EntityStatus.REMOVED.equals(status)) {
                        database.populateRemoveEntityStatement(removePS, entityPK, state.identity());
                        removePS.addBatch();
                    } else {
                        StringWriter writer = new StringWriter();
                        writeEntityState(defState, writer, unitofwork.identity());
                        writer.flush();
                        if (EntityStatus.UPDATED.equals(status)) {
                            Long entityOptimisticLock = ((SQLEntityState) state).getEntityOptimisticLock();
                            database.populateUpdateEntityStatement(updatePS, entityPK, entityOptimisticLock, defState.identity(), writer.toString(), unitofwork.currentTime());
                            updatePS.addBatch();
                        } else if (EntityStatus.NEW.equals(status)) {
                            database.populateInsertEntityStatement(insertPS, defState.identity(), writer.toString(), unitofwork.currentTime());
                            insertPS.addBatch();
                        }
                    }
                }
                removePS.executeBatch();
                insertPS.executeBatch();
                updatePS.executeBatch();
                connection.commit();
            } catch (SQLException sqle) {
                SQLUtil.rollbackQuietly(connection);
                if (LOGGER.isDebugEnabled()) {
                    StringWriter sb = new StringWriter();
                    sb.append("SQLException during commit, logging nested exceptions before throwing EntityStoreException:\n");
                    SQLException e = sqle;
                    while (e != null) {
                        e.printStackTrace(new PrintWriter(sb, true));
                        e = e.getNextException();
                    }
                    LOGGER.debug(sb.toString());
                }
                throw new EntityStoreException(sqle);
            } catch (RuntimeException re) {
                SQLUtil.rollbackQuietly(connection);
                throw new EntityStoreException(re);
            } finally {
                SQLUtil.closeQuietly(insertPS);
                SQLUtil.closeQuietly(updatePS);
                SQLUtil.closeQuietly(removePS);
                SQLUtil.closeQuietly(connection);
            }
        }

        @Override
        public void cancel() {
        }
    };
}
Also used : SQLEntityState(org.qi4j.entitystore.sql.internal.SQLEntityState) DefaultSQLEntityState(org.qi4j.entitystore.sql.internal.SQLEntityState.DefaultSQLEntityState) DefaultEntityState(org.qi4j.spi.entitystore.helpers.DefaultEntityState) SQLException(java.sql.SQLException) Connection(java.sql.Connection) PreparedStatement(java.sql.PreparedStatement) SQLEntityState(org.qi4j.entitystore.sql.internal.SQLEntityState) EntityState(org.qi4j.spi.entity.EntityState) DefaultSQLEntityState(org.qi4j.entitystore.sql.internal.SQLEntityState.DefaultSQLEntityState) DefaultEntityState(org.qi4j.spi.entitystore.helpers.DefaultEntityState) StringWriter(java.io.StringWriter) EntityStatus(org.qi4j.spi.entity.EntityStatus) StateCommitter(org.qi4j.spi.entitystore.StateCommitter) EntityStoreException(org.qi4j.spi.entitystore.EntityStoreException) PrintWriter(java.io.PrintWriter)

Aggregations

StateCommitter (org.qi4j.spi.entitystore.StateCommitter)4 EntityState (org.qi4j.spi.entity.EntityState)2 EntityStoreException (org.qi4j.spi.entitystore.EntityStoreException)2 DefaultEntityState (org.qi4j.spi.entitystore.helpers.DefaultEntityState)2 PrintWriter (java.io.PrintWriter)1 StringWriter (java.io.StringWriter)1 Connection (java.sql.Connection)1 PreparedStatement (java.sql.PreparedStatement)1 SQLException (java.sql.SQLException)1 ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1 BackingStoreException (java.util.prefs.BackingStoreException)1 Preferences (java.util.prefs.Preferences)1 EntityComposite (org.qi4j.api.entity.EntityComposite)1 EntityReference (org.qi4j.api.entity.EntityReference)1 ConcurrentEntityModificationException (org.qi4j.api.unitofwork.ConcurrentEntityModificationException)1 EntityTypeNotFoundException (org.qi4j.api.unitofwork.EntityTypeNotFoundException)1 NoSuchEntityException (org.qi4j.api.unitofwork.NoSuchEntityException)1 UnitOfWorkCallback (org.qi4j.api.unitofwork.UnitOfWorkCallback)1 UnitOfWorkCompletionException (org.qi4j.api.unitofwork.UnitOfWorkCompletionException)1