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 );
}
}