private void putAssociationOperation(
      Association association,
      AssociationKey associationKey,
      AssociationOperation action,
      AssociatedEntityKeyMetadata associatedEntityKeyMetadata) {
    Relationship relationship =
        associationQueries
            .get(associationKey.getMetadata())
            .findRelationship(dataBase, associationKey, action.getKey());

    if (relationship != null) {
      for (String relationshipProperty : associationKey.getMetadata().getRowKeyIndexColumnNames()) {
        relationship.setProperty(relationshipProperty, action.getValue().get(relationshipProperty));
      }

      for (String column :
          associationKey
              .getMetadata()
              .getColumnsWithoutKeyColumns(action.getValue().getColumnNames())) {
        if (!isRowKeyColumn(associationKey.getMetadata(), column)) {
          relationship.getEndNode().setProperty(column, action.getValue().get(column));
        }
      }

      GraphLogger.log("Updated relationship: %1$s", relationship);
    } else {
      relationship =
          createRelationship(associationKey, action.getValue(), associatedEntityKeyMetadata);
      GraphLogger.log("Created relationship: %1$s", relationship);
    }
  }
  @Override
  public void removeAssociation(AssociationKey key, AssociationContext associationContext) {
    // If this is the inverse side of a bi-directional association, we don't manage the relationship
    // from this side
    if (key.getMetadata().isInverse()) {
      return;
    }

    associationQueries.get(key.getMetadata()).removeAssociation(dataBase, key);
  }
  /**
   * Returns the entity key on the other side of association row represented by the given row key.
   *
   * <p><b>Note:</b> May only be invoked if the row key actually contains all the columns making up
   * that entity key. Specifically, it may <b>not</b> be invoked if the association has index
   * columns (maps, ordered collections), as the entity key columns will not be part of the row key
   * in this case.
   */
  private EntityKey getEntityKey(AssociationKey associationKey, RowKey rowKey) {
    String[] associationKeyColumns =
        associationKey.getMetadata().getAssociatedEntityKeyMetadata().getAssociationKeyColumns();
    Object[] columnValues = new Object[associationKeyColumns.length];
    int i = 0;

    for (String associationKeyColumn : associationKeyColumns) {
      columnValues[i] = rowKey.getColumnValue(associationKeyColumn);
      i++;
    }

    EntityKeyMetadata entityKeyMetadata =
        associationKey.getMetadata().getAssociatedEntityKeyMetadata().getEntityKeyMetadata();
    return new EntityKey(entityKeyMetadata, columnValues);
  }
  @Override
  public void insertOrUpdateAssociation(
      AssociationKey key, Association association, AssociationContext associationContext) {
    Map<SerializableRowKey, Map<String, Object>> associationRows =
        ((SerializableMapAssociationSnapshot) association.getSnapshot()).getUnderlyingMap();

    for (AssociationOperation action : association.getOperations()) {
      switch (action.getType()) {
        case CLEAR:
          associationRows.clear();
        case PUT:
          associationRows.put(
              new SerializableRowKey(action.getKey()),
              MapHelpers.associationRowToMap(action.getValue()));
          break;
        case REMOVE:
          associationRows.remove(new SerializableRowKey(action.getKey()));
          break;
      }
    }

    final Cache<AK> associationCache = getCacheManager().getAssociationCache(key.getMetadata());
    associationCache.put(
        new Element(getKeyProvider().getAssociationCacheKey(key), associationRows));
  }
 @Override
 public void removeAssociation(AssociationKey key, AssociationContext associationContext) {
   Cache<AK, Map<RowKey, Map<String, Object>>> cache =
       getCacheManager().getAssociationCache(key.getMetadata());
   AK cacheKey = getKeyProvider().getAssociationCacheKey(key);
   AtomicMapLookup.removeAtomicMap(cache, cacheKey);
 }
 /**
  * When dealing with some scenarios like, for example, a bidirectional association, OGM calls this
  * method twice:
  *
  * <p>the first time with the information related to the owner of the association and the {@link
  * RowKey}, the second time using the same {@link RowKey} but with the {@link AssociationKey}
  * referring to the other side of the association.
  *
  * @param associatedEntityKeyMetadata
  */
 private Relationship createRelationship(
     AssociationKey associationKey,
     Tuple associationRow,
     AssociatedEntityKeyMetadata associatedEntityKeyMetadata) {
   switch (associationKey.getMetadata().getAssociationKind()) {
     case EMBEDDED_COLLECTION:
       return createRelationshipWithEmbeddedNode(
           associationKey, associationRow, associatedEntityKeyMetadata);
     case ASSOCIATION:
       return findOrCreateRelationshipWithEntityNode(
           associationKey, associationRow, associatedEntityKeyMetadata);
     default:
       throw new AssertionFailure(
           "Unrecognized associationKind: " + associationKey.getMetadata().getAssociationKind());
   }
 }
 @Override
 public Association createAssociation(AssociationKey key, AssociationContext associationContext) {
   final Cache<AK> associationCache = getCacheManager().getAssociationCache(key.getMetadata());
   Map<SerializableRowKey, Map<String, Object>> association =
       new HashMap<SerializableRowKey, Map<String, Object>>();
   associationCache.put(new Element(getKeyProvider().getAssociationCacheKey(key), association));
   return new Association(new SerializableMapAssociationSnapshot(association));
 }
 @Override
 public Association getAssociation(AssociationKey key, AssociationContext associationContext) {
   Cache<AK, Map<RowKey, Map<String, Object>>> cache =
       getCacheManager().getAssociationCache(key.getMetadata());
   AK cacheKey = getKeyProvider().getAssociationCacheKey(key);
   Map<RowKey, Map<String, Object>> atomicMap =
       AtomicMapLookup.getFineGrainedAtomicMap(cache, cacheKey, false);
   return atomicMap == null ? null : new Association(new MapAssociationSnapshot(atomicMap));
 }
 private void removeAssociationOperation(
     Association association,
     AssociationKey associationKey,
     AssociationOperation action,
     AssociatedEntityKeyMetadata associatedEntityKeyMetadata) {
   associationQueries
       .get(associationKey.getMetadata())
       .removeAssociationRow(dataBase, associationKey, action.getKey());
 }
 /**
  * The only properties added to a relationship are the columns representing the index of the
  * association.
  */
 private void applyProperties(
     AssociationKey associationKey, Tuple associationRow, Relationship relationship) {
   String[] indexColumns = associationKey.getMetadata().getRowKeyIndexColumnNames();
   for (int i = 0; i < indexColumns.length; i++) {
     String propertyName = indexColumns[i];
     Object propertyValue = associationRow.get(propertyName);
     relationship.setProperty(propertyName, propertyValue);
   }
 }
Exemple #11
0
  private RowKey convert(AssociationKey associationKey, Neo4jTupleAssociationSnapshot snapshot) {
    String[] columnNames = associationKey.getMetadata().getRowKeyColumnNames();
    Object[] values = new Object[columnNames.length];

    for (int i = 0; i < columnNames.length; i++) {
      values[i] = snapshot.get(columnNames[i]);
    }

    return new RowKey(columnNames, values);
  }
 private Relationship createRelationshipWithEmbeddedNode(
     AssociationKey associationKey,
     Tuple associationRow,
     AssociatedEntityKeyMetadata associatedEntityKeyMetadata) {
   EntityKey embeddedKey = getEntityKey(associationRow, associatedEntityKeyMetadata);
   Relationship relationship =
       associationQueries
           .get(associationKey.getMetadata())
           .createRelationshipForEmbeddedAssociation(dataBase, associationKey, embeddedKey);
   applyProperties(associationKey, associationRow, relationship);
   return relationship;
 }
 /**
  * Remove an association row
  *
  * @param executionEngine the {@link ExecutionEngine} used to run the query
  * @param associationKey represents the association
  * @param rowKey represents a row in an association
  */
 public void removeAssociationRow(
     ExecutionEngine executionEngine, AssociationKey associationKey, RowKey rowKey) {
   Object[] relationshipValues;
   if (associationKey.getMetadata().getRowKeyIndexColumnNames().length > 0) {
     int length = associationKey.getMetadata().getRowKeyIndexColumnNames().length;
     relationshipValues = new Object[length];
     String[] indexColumnNames = associationKey.getMetadata().getRowKeyIndexColumnNames();
     for (int i = 0; i < indexColumnNames.length; i++) {
       for (int j = 0; j < rowKey.getColumnNames().length; j++) {
         if (indexColumnNames[i].equals(rowKey.getColumnNames()[j])) {
           relationshipValues[i] = rowKey.getColumnValues()[j];
         }
       }
     }
   } else {
     relationshipValues = getEntityKey(associationKey, rowKey).getColumnValues();
   }
   Object[] queryValues =
       ArrayHelper.concat(associationKey.getEntityKey().getColumnValues(), relationshipValues);
   executionEngine.execute(removeAssociationRowQuery, params(queryValues));
 }
 @Override
 public Association createAssociation(AssociationKey key, AssociationContext associationContext) {
   // TODO we don't verify that it does not yet exist assuming that this ahs been done before by
   // the calling code
   // should we improve?
   Cache<AK, Map<RowKey, Map<String, Object>>> cache =
       getCacheManager().getAssociationCache(key.getMetadata());
   AK cacheKey = getKeyProvider().getAssociationCacheKey(key);
   Map<RowKey, Map<String, Object>> atomicMap =
       AtomicMapLookup.getFineGrainedAtomicMap(cache, cacheKey, true);
   return new Association(new MapAssociationSnapshot(atomicMap));
 }
 private Relationship createRelationshipWithTargetNode(
     AssociationKey associationKey, Tuple associationRow, Node targetNode) {
   EntityKey entityKey = associationKey.getEntityKey();
   Node ownerNode =
       entityQueries
           .get(entityKey.getMetadata())
           .findEntity(dataBase, entityKey.getColumnValues());
   Relationship relationship =
       ownerNode.createRelationshipTo(
           targetNode, withName(associationKey.getMetadata().getCollectionRole()));
   applyProperties(associationKey, associationRow, relationship);
   return relationship;
 }
  @Override
  public Association getAssociation(AssociationKey key, AssociationContext associationContext) {
    final Cache<AK> associationCache = getCacheManager().getAssociationCache(key.getMetadata());
    final Element element = associationCache.get(getKeyProvider().getAssociationCacheKey(key));

    if (element == null) {
      return null;
    } else {
      @SuppressWarnings("unchecked")
      Map<SerializableRowKey, Map<String, Object>> associationRows =
          (Map<SerializableRowKey, Map<String, Object>>) element.getObjectValue();
      return new Association(new SerializableMapAssociationSnapshot(associationRows));
    }
  }
  @Override
  public void insertOrUpdateAssociation(
      AssociationKey key, Association association, AssociationContext associationContext) {
    // If this is the inverse side of a bi-directional association, we don't create a relationship
    // for this; this
    // will happen when updating the main side
    if (key.getMetadata().isInverse()) {
      return;
    }

    for (AssociationOperation action : association.getOperations()) {
      applyAssociationOperation(association, key, action, associationContext);
    }
  }
 @Override
 public void removeAssociation(AssociationKey key, AssociationContext associationContext) {
   getCacheManager()
       .getAssociationCache(key.getMetadata())
       .remove(getKeyProvider().getAssociationCacheKey(key));
 }