Search in sources :

Example 1 with ReachabilityFieldManager

use of org.datanucleus.store.fieldmanager.ReachabilityFieldManager in project datanucleus-core by datanucleus.

the class ReachabilityAtCommitHandler method execute.

/**
 * Method to perform the "persistence-by-reachability" at commit.
 */
public void execute() {
    try {
        this.executing = true;
        if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
            NucleusLogger.PERSISTENCE.debug(Localiser.msg("010032"));
        }
        // from makePersistent in this txn, or enlisted existing objects) then run reachability checks
        if (!persistedIds.isEmpty() && !flushedNewIds.isEmpty()) {
            Set currentReachables = new HashSet();
            // Run "reachability" on all known persistent objects for this txn
            Object[] ids = persistedIds.toArray();
            Set objectNotFound = new HashSet();
            for (int i = 0; i < ids.length; i++) {
                if (!deletedIds.contains(ids[i])) {
                    if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
                        NucleusLogger.PERSISTENCE.debug("Performing reachability algorithm on object with id \"" + ids[i] + "\"");
                    }
                    try {
                        ObjectProvider op = ec.findObjectProvider(ec.findObject(ids[i], true, true, null));
                        if (!op.isDeleted() && !currentReachables.contains(ids[i])) {
                            // Make sure all of its relation fields are loaded before continuing. Is this necessary, since its enlisted?
                            op.loadUnloadedRelationFields();
                            // Add this object id since not yet reached
                            if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
                                NucleusLogger.PERSISTENCE.debug(Localiser.msg("007000", StringUtils.toJVMIDString(op.getObject()), ids[i], op.getLifecycleState()));
                            }
                            currentReachables.add(ids[i]);
                            // Go through all relation fields using ReachabilityFieldManager
                            ReachabilityFieldManager pcFM = new ReachabilityFieldManager(op, currentReachables);
                            int[] relationFieldNums = op.getClassMetaData().getRelationMemberPositions(ec.getClassLoaderResolver());
                            if (relationFieldNums != null && relationFieldNums.length > 0) {
                                op.provideFields(relationFieldNums, pcFM);
                            }
                        }
                    } catch (NucleusObjectNotFoundException ex) {
                        objectNotFound.add(ids[i]);
                    }
                } else {
                // Was deleted earlier so ignore
                }
            }
            // Remove any of the "reachable" instances that are no longer "reachable"
            flushedNewIds.removeAll(currentReachables);
            Object[] nonReachableIds = flushedNewIds.toArray();
            if (nonReachableIds != null && nonReachableIds.length > 0) {
                // TODO See CORE-3276 for a possible change to this
                for (int i = 0; i < nonReachableIds.length; i++) {
                    if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
                        NucleusLogger.PERSISTENCE.debug(Localiser.msg("010033", nonReachableIds[i]));
                    }
                    try {
                        if (!objectNotFound.contains(nonReachableIds[i])) {
                            ObjectProvider op = ec.findObjectProvider(ec.findObject(nonReachableIds[i], true, true, null));
                            if (!op.getLifecycleState().isDeleted() && !ec.getApiAdapter().isDetached(op.getObject())) {
                                // Null any relationships for relation fields of this object
                                op.replaceFields(op.getClassMetaData().getNonPKMemberPositions(), new NullifyRelationFieldManager(op));
                                ec.flush();
                            }
                        }
                    } catch (NucleusObjectNotFoundException ex) {
                    // just ignore if the object does not exist anymore
                    }
                }
                // B). Remove the objects
                for (int i = 0; i < nonReachableIds.length; i++) {
                    try {
                        if (!objectNotFound.contains(nonReachableIds[i])) {
                            ObjectProvider op = ec.findObjectProvider(ec.findObject(nonReachableIds[i], true, true, null));
                            op.deletePersistent();
                        }
                    } catch (NucleusObjectNotFoundException ex) {
                    // just ignore if the file does not exist anymore
                    }
                }
            }
            // Make sure any updates are flushed
            ec.flushInternal(true);
        }
        if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
            NucleusLogger.PERSISTENCE.debug(Localiser.msg("010034"));
        }
    } finally {
        this.executing = false;
    }
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) NullifyRelationFieldManager(org.datanucleus.store.fieldmanager.NullifyRelationFieldManager) ReachabilityFieldManager(org.datanucleus.store.fieldmanager.ReachabilityFieldManager) ObjectProvider(org.datanucleus.state.ObjectProvider) NucleusObjectNotFoundException(org.datanucleus.exceptions.NucleusObjectNotFoundException) HashSet(java.util.HashSet)

Aggregations

HashSet (java.util.HashSet)1 Set (java.util.Set)1 NucleusObjectNotFoundException (org.datanucleus.exceptions.NucleusObjectNotFoundException)1 ObjectProvider (org.datanucleus.state.ObjectProvider)1 NullifyRelationFieldManager (org.datanucleus.store.fieldmanager.NullifyRelationFieldManager)1 ReachabilityFieldManager (org.datanucleus.store.fieldmanager.ReachabilityFieldManager)1