protected List persistEntities()

in grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/Neo4jEntityPersister.java [105:257]


    protected List<Serializable> persistEntities(final PersistentEntity pe, @SuppressWarnings("rawtypes") final Iterable objs) {

        GraphPersistentEntity graphPersistentEntity = (GraphPersistentEntity) pe;

        List<Serializable> idList = new ArrayList<>();
        if(graphPersistentEntity.hasDynamicAssociations()) {
            // dynamic association entities cannot be batch inserted
            for (Object obj : objs) {
                Serializable id = persistEntity(pe, obj);
                if(id != null) {
                    idList.add(id);
                }
            }
        }
        else if(graphPersistentEntity.isNativeId() && !graphPersistentEntity.isRelationshipEntity()) {
            List<EntityAccess> entityAccesses = new ArrayList<>();
            // optimize batch inserts for multiple entities with native id
            final Neo4jSession session = getSession();

            StringBuilder createCypher = new StringBuilder(CypherBuilder.CYPHER_CREATE);
            int listIndex = 0;
            List<PendingOperation<Object,Serializable>> cascadingOperations = new ArrayList<>();
            final Map<String, Object> params = new HashMap<>(1);
            final Map<Integer, Integer> indexMap = new HashMap<>();
            int insertIndex = 0;
            final Iterator iterator = objs.iterator();
            boolean previous = false;
            while (iterator.hasNext()) {
                Object obj = iterator.next();
                listIndex++;
                if (shouldIgnore(session, obj)) {
                    EntityAccess entityAccess = createEntityAccess(pe, obj);
                    idList.add((Serializable) entityAccess.getIdentifier());
                    continue;
                }

                final EntityAccess entityAccess = createEntityAccess(pe, obj);
                GraphPersistentEntity persistentEntity = (GraphPersistentEntity) entityAccess.getPersistentEntity();
                if (getMappingContext().getProxyFactory().isProxy(obj)) {
                    idList.add(((EntityProxy) obj).getProxyKey());
                    continue;
                }

                session.registerPending(obj);

                Serializable identifier = (Serializable) entityAccess.getIdentifier();
                boolean isUpdate = identifier != null;
                if (isUpdate) {

                    registerPendingUpdate(session, persistentEntity, entityAccess, obj, identifier);
                    idList.add(identifier);
                }
                else {
                    final PendingInsertAdapter<Object, Serializable> pendingInsert = new PendingInsertAdapter<Object, Serializable>(persistentEntity, identifier, obj, entityAccess) {
                        @Override
                        public void run() {
                            if (cancelInsert(pe, entityAccess)) {
                                setVetoed(true);
                            }
                        }

                        @Override
                        public Serializable getNativeKey() {
                            return (Serializable) entityAccess.getIdentifier();
                        }
                    };
                    pendingInsert.addCascadeOperation(new PendingOperationAdapter<Object, Serializable>(persistentEntity, identifier, obj) {
                        @Override
                        public void run() {
                            firePostInsertEvent(pe, entityAccess);
                        }
                    });

                    cascadingOperations.addAll(pendingInsert.getCascadeOperations());
                    final List<PendingOperation<Object, Serializable>> preOperations = pendingInsert.getPreOperations();
                    for (PendingOperation preOperation : preOperations) {
                        preOperation.run();
                    }

                    pendingInsert.run();
                    pendingInsert.setExecuted(true);

                    // temporarily add null so it is replaced later
                    idList.add(null);

                    if(pendingInsert.isVetoed()) {
                        continue;
                    }

                    session.addPendingInsert(pendingInsert);

                    indexMap.put(insertIndex++, listIndex - 1);
                    entityAccesses.add(entityAccess);
                    if(previous) {
                        createCypher.append(CypherBuilder.COMMAND_SEPARATOR);
                    }
                    session.buildEntityCreateOperation(createCypher, String.valueOf(insertIndex), entityAccess.getPersistentEntity(), pendingInsert, params, cascadingOperations);
                    if(iterator.hasNext()) {
                        previous = true;
                    }

                }

            }
            if(insertIndex > 0) {

                QueryRunner statementRunner = session.hasTransaction() ? session.getTransaction().getNativeTransaction() : session.getNativeInterface();

                final String finalCypher = createCypher.toString() + " RETURN *";
                if(log.isDebugEnabled()) {
                    log.debug("CREATE Cypher [{}] for parameters [{}]", finalCypher, params);
                }

                if(graphPersistentEntity.hasDynamicAssociations()) {
                    params.remove(DYNAMIC_ASSOCIATION_PARAM);
                }

                final Result result = statementRunner.run(finalCypher, params);

                if(!result.hasNext()) {
                    throw new IdentityGenerationException("CREATE operation did not generate an identifier for entity " + pe.getJavaClass());
                }

                final Record record = result.next();
                for (int j = 0; j < insertIndex; j++) {
                    final Integer targetIndex = indexMap.get(j);
                    Assert.notNull(targetIndex, "Should never be null. Please file an issue");

                    final Node node = record.get("n" + (j + 1)).asNode();
                    if(node == null) {
                        throw new IdentityGenerationException("CREATE operation did not generate an identifier for entity " + pe.getJavaClass());
                    }
                    final long identifier = node.id();
                    final EntityAccess entityAccess = entityAccesses.get(j);
                    entityAccess.setIdentifier(identifier);
                    idList.set(targetIndex, identifier);
                    persistAssociationsOfEntity((GraphPersistentEntity) pe, entityAccess, false);

                }
            }
        }
        else {

            for (Object obj : objs) {
                final EntityAccess entityAccess = createEntityAccess(pe, obj);
                Serializable id = persistEntity(entityAccess.getPersistentEntity(), obj);
                if(id != null) {
                    idList.add(id);
                }
            }
        }
        return idList;
    }