private void executeBatchUpdate()

in mongodb/src/main/java/org/hibernate/ogm/datastore/mongodb/MongoDBDialect.java [1605:1718]


	private void executeBatchUpdate(Map<MongoCollection<Document>, BatchInsertionTask> inserts, List<Tuple> insertTuples,
			GroupedChangesToEntityOperation groupedOperation) {
		EntityKey entityKey = groupedOperation.getEntityKey();
		MongoCollection<Document> collection = getCollection( entityKey );
		Document insertStatement = null;
		Document updateStatement = new Document();
		WriteConcern writeConcern = null;

		final UpdateOptions updateOptions = new UpdateOptions().upsert( true );
		for ( Operation operation : groupedOperation.getOperations() ) {
			if ( operation instanceof InsertOrUpdateTupleOperation ) {
				InsertOrUpdateTupleOperation tupleOperation = (InsertOrUpdateTupleOperation) operation;
				Tuple tuple = tupleOperation.getTuplePointer().getTuple();
				MongoDBTupleSnapshot snapshot = (MongoDBTupleSnapshot) tuple.getSnapshot();
				writeConcern = mergeWriteConcern( writeConcern, getWriteConcern( tupleOperation.getTupleContext() ) );

				if ( SnapshotType.INSERT == tuple.getSnapshotType() ) {
					Document document = getCurrentDocument( snapshot, insertStatement, entityKey );
					insertStatement = objectForInsert( tuple, document );

					getOrCreateBatchInsertionTask( inserts, entityKey.getMetadata(), collection )
							.put( entityKey, insertStatement );
					insertTuples.add( tuple );
				}
				else {
					updateStatement = objectForUpdate( tuple, tupleOperation.getTupleContext(), updateStatement );
				}
			}
			else if ( operation instanceof InsertOrUpdateAssociationOperation ) {
				InsertOrUpdateAssociationOperation updateAssociationOperation = (InsertOrUpdateAssociationOperation) operation;
				Association association = updateAssociationOperation.getAssociation();
				AssociationKey associationKey = updateAssociationOperation.getAssociationKey();
				AssociationContext associationContext = updateAssociationOperation.getContext();
				AssociationStorageStrategy storageStrategy = getAssociationStorageStrategy( associationKey, associationContext );
				String collectionRole = associationKey.getMetadata().getCollectionRole();

				Object rows = getAssociationRows( association, associationKey, associationContext );
				Object toStore = associationKey.getMetadata().getAssociationType() == AssociationType.ONE_TO_ONE ? ( (List<?>) rows ).get( 0 ) : rows;

				if ( storageStrategy == AssociationStorageStrategy.IN_ENTITY ) {
					writeConcern = mergeWriteConcern( writeConcern, getWriteConcern( associationContext ) );
					if ( insertStatement != null ) {
						// The association is updated in a new document
						MongoHelpers.setValue( insertStatement, collectionRole, rows );
					}
					else {
						// The association is updated on an existing document
						addSetToQuery( updateStatement, collectionRole, toStore );

						Document document = getDocument( association, associationContext );

						// The document might be null when deleting detached entities
						if ( document != null ) {
							MongoHelpers.setValue( document, associationKey.getMetadata().getCollectionRole(), toStore );
						}
					}
				}
				else {
					MongoDBAssociationSnapshot associationSnapshot = (MongoDBAssociationSnapshot) association.getSnapshot();
					MongoCollection<Document> associationCollection = getAssociationCollection( associationKey, storageStrategy, associationContext );
					Document query = associationSnapshot.getQueryObject();
					Document update = new Document( "$set", new Document( ROWS_FIELDNAME, toStore ) );
					associationCollection.updateOne( query, update, updateOptions );
				}
			}
			else if ( operation instanceof RemoveAssociationOperation ) {
				if ( insertStatement != null ) {
					throw new IllegalStateException( "RemoveAssociationOperation not supported in the INSERT case" );
				}

				RemoveAssociationOperation removeAssociationOperation = (RemoveAssociationOperation) operation;
				AssociationKey associationKey = removeAssociationOperation.getAssociationKey();
				AssociationContext associationContext = removeAssociationOperation.getContext();

				AssociationStorageStrategy storageStrategy = getAssociationStorageStrategy( associationKey, associationContext );

				if ( storageStrategy == AssociationStorageStrategy.IN_ENTITY ) {
					writeConcern = mergeWriteConcern( writeConcern, getWriteConcern( associationContext ) );
					String collectionRole = associationKey.getMetadata().getCollectionRole();

					if ( associationContext.getEntityTuplePointer().getTuple() != null ) {
						MongoHelpers.resetValue( ( (MongoDBTupleSnapshot) associationContext.getEntityTuplePointer().getTuple().getSnapshot() ).getDbObject(),
								collectionRole );
					}
					addUnsetToQuery( updateStatement, collectionRole );
				}
				else {
					MongoCollection<Document> associationCollection = getAssociationCollection( associationKey, storageStrategy, associationContext ).withWriteConcern( getWriteConcern( associationContext ) );
					Document query = associationKeyToObject( associationKey, storageStrategy );
					DeleteResult result = associationCollection.deleteMany( query );
					long nAffected = -1;
					if ( result.wasAcknowledged() ) {
						nAffected = result.getDeletedCount();
					}
					log.removedAssociation( nAffected );
				}
			}
			else {
				throw new IllegalStateException( operation.getClass().getSimpleName() + " not supported here" );
			}
		}

		if ( updateStatement != null && !updateStatement.isEmpty() ) {
			Document documentId = prepareIdObject( entityKey );

			Document fieldsToUpdate = updateStatement.get( "$set", Document.class );
			provider.getBinaryStorageManager().storeContentToBinaryStorage( fieldsToUpdate, entityKey.getMetadata(), documentId.get( "_id" ) );

			Document fieldsToDelete = updateStatement.get( "$unset", Document.class );
			provider.getBinaryStorageManager().removeFieldsFromBinaryStorage( fieldsToDelete, entityKey.getMetadata(), documentId.get( "_id" ) );

			collection. withWriteConcern( writeConcern ).updateOne( documentId, updateStatement, updateOptions );
		}
	}