# ManyToOneCycleLoader.java

    package org.codefilarete.stalactite.engine.runtime.cycle;

    import java.util.Map;
    import java.util.Set;

    import org.codefilarete.stalactite.engine.EntityPersister;
    import org.codefilarete.stalactite.engine.configurer.onetoone.FirstPhaseCycleLoadListener;
    import org.codefilarete.stalactite.engine.runtime.SecondPhaseRelationLoader;
    import org.codefilarete.stalactite.sql.result.BeanRelationFixer;

    /**
     * Loader in case of same entity type present in entity graph as child of itself : A.b -> B.c -> C.a
     * Sibling is not the purpose of this class.
     *
     * Implemented as such :
     * - very first query reads cycling entity type identifiers
     * - a secondary query is executed to load subgraph with above identifiers
     *
     * @param <SRC> type of root entity graph
     * @param <TRGT> cycling entity type (the one to be loaded)
     * @param <TRGTID> cycling entity identifier type
     *
     */
    public class ManyToOneCycleLoader<SRC, TRGT, TRGTID> extends AbstractCycleLoader<SRC, TRGT, TRGTID>
    	implements FirstPhaseCycleLoadListener<SRC, TRGTID> {

    	public ManyToOneCycleLoader(EntityPersister<TRGT, TRGTID> targetPersister) {
    		super(targetPersister);
    	}

    	/**
    	 * Implemented to read very first identifiers of source type
    	 */
    	@Override
    	public void onFirstPhaseRowRead(SRC src, TRGTID targetId) {
    		if (!SecondPhaseRelationLoader.isDefaultValue(targetId)) {
    			// TODO : we should know which relation is being filled instead of iterating over all of them, no ? see OneToManyCycleLoader
    			this.relations.forEach((relationName, configurationResult) -> {
    				if (configurationResult.getSourcePersister().getClassToPersist().isInstance(src)) {
    					this.currentRuntimeContext.get().addRelationToInitialize(relationName, src, targetId);
    				}
    			});
    		}
    	}

    	@Override
    	protected void applyRelationToSource(EntityRelationStorage<SRC, TRGTID> relationStorage,
    										 BeanRelationFixer<SRC, TRGT> beanRelationFixer,
    										 Map<TRGTID, TRGT> targetPerId) {
    		relationStorage.getEntitiesToFulFill().forEach(src -> {
    			Set<TRGTID> trgtids = relationStorage.getRelationToInitialize(src);
    			if (trgtids != null) {
    				trgtids.forEach(targetId -> beanRelationFixer.apply(src, targetPerId.get(targetId)));
    			}
    		});
    	}
    }