@Override
  protected void resetCollectionParent(
      final DatabaseConnector connector,
      final ObjectAdapter parent,
      final Iterator<ObjectAdapter> elements) {
    LOG.debug("Saving polymorphic list");

    ObjectSpecification elementSpecification;
    while (elements.hasNext()) {
      final ObjectAdapter thisAdapter = elements.next();
      elementSpecification = thisAdapter.getSpecification();

      // Reinstall collection parent
      final StringBuffer update = new StringBuffer();
      update.append("INSERT INTO ");
      update.append(table);
      update.append(" (");
      // list of column names
      super.getIdMapping().appendColumnNames(update);
      update.append("," + getForeignKeyName());
      update.append(", " + itemIdColumnName);
      update.append("," + classColumnName);
      update.append(") VALUES (");

      // Row ID column
      final Object pojo = thisAdapter.getObject();
      final RootOid transientRootOid = oidGenerator.createTransientOid(pojo);

      final RootOid persistentRootOid = oidGenerator.createPersistent(pojo, transientRootOid);

      polyIdMapper.appendObjectId(connector, update, persistentRootOid);

      // polyIdMapper.appendObjectId(connector, update,
      // thisAdapter.getOid());
      update.append(",");

      // Foreign key ID column
      getForeignKeyMapping().appendInsertValues(connector, update, parent);
      update.append(",");

      // item Id column
      final RootOid oid = (RootOid) thisAdapter.getOid();
      getIdMapping().appendObjectId(connector, update, oid);

      // Class name column
      update.append(",?)");
      connector.addToQueryValues(elementSpecification.getFullIdentifier());

      connector.insert(update.toString());
    }
  }
  @Override
  public void createTables(final DatabaseConnector connection) {
    if (super.needsTables(connection)) {
      super.createTables(connection);
    }

    if (!connection.hasColumn(table, classColumnName)) {
      addColumn(connection, classColumnName, Defaults.TYPE_LONG_STRING());
      addColumn(connection, itemIdColumnName, Defaults.TYPE_PK());
    }
  }
 @Override
 protected void clearCollectionParent(
     final DatabaseConnector connector, final ObjectAdapter parent) {
   // Delete collection parent
   final StringBuffer sql = new StringBuffer();
   sql.append("DELETE FROM ");
   sql.append(table);
   sql.append(" WHERE ");
   appendCollectionWhereValues(connector, parent, sql);
   connector.update(sql.toString());
 }
 protected void addColumn(
     final DatabaseConnector connection, final String columnName, final String columnType) {
   final StringBuffer sql = new StringBuffer();
   sql.append("alter table ");
   sql.append(table);
   sql.append(" add ");
   sql.append(columnName);
   sql.append(" ");
   sql.append(columnType);
   connection.update(sql.toString());
 }
  @Override
  protected void loadCollectionIntoList(
      final DatabaseConnector connector,
      final ObjectAdapter parent,
      final String table,
      final ObjectSpecification specification,
      final IdMappingAbstract idMappingAbstract,
      final Map<ObjectAssociation, FieldMapping> fieldMappingByField,
      final VersionMapping versionMapping,
      final List<ObjectAdapter> list) {
    LOG.debug("Loading polymorphic list");

    final StringBuffer sql = new StringBuffer();
    sql.append("select ");
    super.getIdMapping().appendColumnNames(sql);

    sql.append("," + getForeignKeyName());
    sql.append("," + classColumnName);
    sql.append("," + itemIdColumnName);

    sql.append(" from ");
    sql.append(table);
    sql.append(" where ");
    appendCollectionWhereValues(connector, parent, sql);

    final Results rs = connector.select(sql.toString());

    final SpecificationLoaderSpi reflector = IsisContext.getSpecificationLoader();
    final JdbcPolymorphicObjectReferenceMapping idMapping =
        (JdbcPolymorphicObjectReferenceMapping) idMappingAbstract;

    while (rs.next()) {
      final ObjectSpecification itemSpecification =
          reflector.loadSpecification(rs.getString(classColumnName));
      idMapping.setObjectSpecification(itemSpecification);

      // Load new recordSet for the actual class
      final ObjectMapping itemMapper = objectMappingLookup.getMapping(itemSpecification, connector);
      final TypedOid oid = idMapping.recreateOid(rs, itemSpecification);
      final ObjectAdapter loadedObject = itemMapper.getObject(connector, oid);

      LOG.debug("  element  " + loadedObject.getOid());

      list.add(loadedObject);
    }
    rs.close();
  }
 @Override
 public boolean needsTables(final DatabaseConnector connection) {
   return super.needsTables(connection) || !connection.hasColumn(table, classColumnName);
 }