private void updateInverseSideOfAssociationNavigation()

in core/src/main/java/org/hibernate/ogm/persister/impl/OgmCollectionPersister.java [624:697]


	private void updateInverseSideOfAssociationNavigation(SharedSessionContractImplementor session, Object entity, AssociationKey associationKey,
			Tuple associationRow, Action action, RowKey rowKey) {
		if ( associationType == AssociationType.EMBEDDED_FK_TO_ENTITY ) {
			// update the associated object
			Serializable entityId = (Serializable) gridTypeOfAssociatedId.nullSafeGet( associationRow, getElementColumnNames(), session, null );
			OgmEntityPersister persister = (OgmEntityPersister) getElementPersister();
			final EntityKey entityKey = EntityKeyBuilder.fromPersister( persister, entityId, session );

			final TuplePointer entityTuplePointer = getSharedTuplePointer( entityKey, entity, persister.getTupleContext( session ), session );
			final Tuple entityTuple = entityTuplePointer.getTuple();
			// the entity tuple could already be gone (not 100% sure this can happen but that feels right)
			if ( entityTuple == null ) {
				return;
			}
			if ( action == Action.ADD ) {
				for ( String columnName : associationKey.getColumnNames() ) {
					entityTuple.put( columnName, associationRow.get( columnName ) );
				}
			}
			else if ( action == Action.REMOVE ) {
				if ( hasIdentifier ) {
					throw new AssertionFailure( "A true OneToMany with an identifier for the collection: " + getRole() );
				}
				keyGridType.nullSafeSet( entityTuple, null, getKeyColumnNames(), session );
			}
			else {
				throw new AssertionFailure( "Unknown action type: " + action );
			}
			persister.insertOrUpdateTuple( entityKey, entityTuplePointer, persister.hasUpdateGeneratedProperties() || persister.hasInsertGeneratedProperties(), session );
		}
		else if ( associationType == AssociationType.ASSOCIATION_TABLE_TO_ENTITY ) {
			String[] elementColumnNames = getElementColumnNames();
			Object[] elementColumnValues = LogicalPhysicalConverterHelper.getColumnValuesFromResultset( associationRow, elementColumnNames );
			Serializable entityId = (Serializable) gridTypeOfAssociatedId.nullSafeGet( associationRow, elementColumnNames, session, null );

			if ( inverseCollectionPersister == null ) {
				return;
			}

			if ( entity == null ) {
				entity = session.getPersistenceContext().getEntity( session.generateEntityKey( entityId, getElementPersister() ) );
			}

			AssociationPersister associationPersister = inverseCollectionPersister.getAssociationPersister( entity, elementColumnValues, session );

			// TODO what happens when a row should be *updated* ?: I suspect ADD works OK as it's a put()
			if ( action == Action.ADD ) {
				RowKey inverseRowKey = getInverseRowKey( associationRow );

				Tuple inverseAssociationRow = new Tuple();
				associationPersister.getAssociation().put( inverseRowKey, inverseAssociationRow );
				for ( String columnName : inverseRowKey.getColumnNames() ) {
					inverseAssociationRow.put( columnName, associationRow.get( columnName ) );
				}
				associationPersister.getAssociation().put( inverseRowKey, inverseAssociationRow );
			}
			else if ( action == Action.REMOVE ) {
				// we try and match the whole tuple as it should be on both sides of the navigation
				if ( rowKey == null ) {
					throw new AssertionFailure( "Deleting a collection tuple that is not present: " + "table {"
							+ getTableName() + "} key column names {" + Arrays.toString( elementColumnNames )
							+ "} key column values {" + Arrays.toString( elementColumnValues ) + "}" );
				}

				RowKey inverseRowKey = getInverseRowKey( associationRow );
				associationPersister.getAssociation().remove( inverseRowKey );
			}
			else {
				throw new AssertionFailure( "Unknown action type: " + action );
			}

			associationPersister.flushToDatastore();
		}
	}