@Override
 public void lock(
     Serializable id, Object version, Object object, int timeout, SessionImplementor session)
     throws StaleObjectStateException, JDBCException {
   MapDatastoreProvider dataStore = getProvider(session);
   EntityKey key =
       EntityKeyBuilder.fromData(
           ((OgmEntityPersister) lockable).getRootEntityKeyMetadata(),
           identifierGridType,
           id,
           session);
   dataStore.writeLock(key, timeout);
   // FIXME check the version number as well and raise an optimistic lock exception if there is an
   // issue JPA 2 spec: 3.4.4.2
   // (Comment by Emmanuel)
 }
  private AssociationKey getCollectionMetadataKey() {
    if (collectionMetadataKey == null) {
      final Object[] columnValues = getKeyColumnValues();
      collectionMetadataKey = new AssociationKey(tableName, keyColumnNames, columnValues);
      // We have a collection on the main side
      if (collectionPersister != null) {
        EntityKey entityKey;
        // we are explicitly looking to update the non owning side
        if (inverse) {
          // look for the other side of the collection, build the key of the other side's entity
          OgmEntityPersister elementPersister =
              (OgmEntityPersister) collectionPersister.getElementPersister();
          entityKey = EntityKeyBuilder.fromPersister(elementPersister, (Serializable) key, session);
          collectionMetadataKey.setCollectionRole(buildCollectionRole(collectionPersister));
        } else {
          // we are on the right side, use the association property
          collectionMetadataKey.setCollectionRole(getUnqualifiedRole(collectionPersister));
          entityKey =
              EntityKeyBuilder.fromPersister(
                  (OgmEntityPersister) collectionPersister.getOwnerEntityPersister(),
                  (Serializable) key,
                  session);
        }
        collectionMetadataKey.setOwnerEntityKey(entityKey);
        // TODO add information on the collection type, set, map, bag, list etc

        AssociationKind type =
            collectionPersister.getElementType().isEntityType()
                ? AssociationKind.ASSOCIATION
                : AssociationKind.EMBEDDED;
        collectionMetadataKey.setAssociationKind(type);
        collectionMetadataKey.setRowKeyColumnNames(collectionPersister.getRowKeyColumnNames());
      }
      // We have a to-one on the main side
      else if (propertyType != null) {
        collectionMetadataKey.setAssociationKind(
            propertyType.isEntityType() ? AssociationKind.ASSOCIATION : AssociationKind.EMBEDDED);
        if (propertyType instanceof EntityType) {
          EntityType entityType = (EntityType) propertyType;
          OgmEntityPersister associatedPersister =
              (OgmEntityPersister) entityType.getAssociatedJoinable(session.getFactory());
          EntityKey entityKey =
              new EntityKey(
                  associatedPersister.getTableName(),
                  associatedPersister.getIdentifierColumnNames(),
                  columnValues);
          collectionMetadataKey.setOwnerEntityKey(entityKey);
          collectionMetadataKey.setRowKeyColumnNames(rowKeyColumnNames);
          collectionMetadataKey.setCollectionRole(getCollectionRoleFromToOne(associatedPersister));
        } else {
          throw new AssertionFailure(
              "Cannot detect associated entity metadata. propertyType is of unexpected type: "
                  + propertyType.getClass());
        }
      } else {
        throw new AssertionFailure(
            "Cannot detect associated entity metadata: collectionPersister and propertyType are both null");
      }
    }
    return collectionMetadataKey;
  }