/*
  * Example with target node:
  *
  * MATCH (n:ENTITY:table {id: {0}}) -[r:role] -  (t {id: {1}})
  * RETURN r
  *
  * Example with relationship indexes:
  *
  * MATCH (n:ENTITY:table {id: {0}}) -[r:role {index: {1}}] -  (t)
  * RETURN r
  */
 private static String initFindRelationshipQuery(
     EntityKeyMetadata ownerEntityKeyMetadata, AssociationKeyMetadata associationKeyMetadata) {
   int offset = 0;
   StringBuilder queryBuilder = new StringBuilder("MATCH ");
   queryBuilder.append("(n:");
   queryBuilder.append(ENTITY);
   queryBuilder.append(":");
   appendLabel(ownerEntityKeyMetadata, queryBuilder);
   appendProperties(ownerEntityKeyMetadata, queryBuilder);
   queryBuilder.append(") - ");
   queryBuilder.append("[r");
   queryBuilder.append(":");
   appendRelationshipType(queryBuilder, associationKeyMetadata);
   offset = ownerEntityKeyMetadata.getColumnNames().length;
   if (associationKeyMetadata.getRowKeyIndexColumnNames().length > 0) {
     appendProperties(queryBuilder, associationKeyMetadata.getRowKeyIndexColumnNames(), offset);
     queryBuilder.append("] - (t");
   } else {
     queryBuilder.append("] - (t");
     appendProperties(
         queryBuilder,
         associationKeyMetadata
             .getAssociatedEntityKeyMetadata()
             .getEntityKeyMetadata()
             .getColumnNames(),
         offset);
   }
   queryBuilder.append(")");
   queryBuilder.append(" RETURN r");
   return queryBuilder.toString();
 }
 @Override
 public DuplicateInsertPreventionStrategy getDuplicateInsertPreventionStrategy(
     EntityKeyMetadata entityKeyMetadata) {
   // Only for non-composite keys (= one column) Neo4j supports unique key constraints; Hence an
   // explicit look-up
   // is required to detect duplicate insertions when using composite keys
   return entityKeyMetadata.getColumnNames().length == 1
       ? DuplicateInsertPreventionStrategy.NATIVE
       : DuplicateInsertPreventionStrategy.LOOK_UP;
 }
 /*
  * Example with association:
  *
  * MATCH (n:ENTITY:table {id: {0}}) -[r:role] - (e)
  * DELETE r
  *
  * Example with embedded collection:
  *
  * MATCH (n:ENTITY:table {id: {0}}) -[r:role] - (e:EMBEDDED)
  * DELETE r, e
  *
  * Example with indexes:
  *
  * MATCH (n:ENTITY:table {id: {0}}) -[r:role {index: {1}}] - (e)
  * DELETE r
  */
 private static String initRemoveAssociationRowQuery(
     EntityKeyMetadata ownerEntityKeyMetadata, AssociationKeyMetadata associationKeyMetadata) {
   StringBuilder queryBuilder = new StringBuilder("MATCH ");
   queryBuilder.append("(n:");
   queryBuilder.append(ENTITY);
   queryBuilder.append(":");
   appendLabel(ownerEntityKeyMetadata, queryBuilder);
   appendProperties(ownerEntityKeyMetadata, queryBuilder);
   queryBuilder.append(") - ");
   queryBuilder.append("[r");
   queryBuilder.append(":");
   appendRelationshipType(queryBuilder, associationKeyMetadata);
   int offset = ownerEntityKeyMetadata.getColumnNames().length;
   boolean hasIndexColumns = associationKeyMetadata.getRowKeyIndexColumnNames().length > 0;
   if (hasIndexColumns) {
     appendProperties(queryBuilder, associationKeyMetadata.getRowKeyIndexColumnNames(), offset);
   }
   queryBuilder.append("] - (e");
   if (associationKeyMetadata.getAssociationKind() == AssociationKind.EMBEDDED_COLLECTION) {
     queryBuilder.append(":");
     queryBuilder.append(EMBEDDED);
   }
   if (!hasIndexColumns) {
     appendProperties(
         queryBuilder,
         associationKeyMetadata
             .getAssociatedEntityKeyMetadata()
             .getEntityKeyMetadata()
             .getColumnNames(),
         offset);
   }
   queryBuilder.append(")");
   queryBuilder.append(" DELETE r");
   if (associationKeyMetadata.getAssociationKind() == AssociationKind.EMBEDDED_COLLECTION) {
     queryBuilder.append(", e");
   }
   return queryBuilder.toString();
 }