Skip to content

TypeError: (row[prop.name] ?? prop.fieldNames.map) is not iterable when adding items to object collection #6360

@ksemasinghe

Description

@ksemasinghe

Describe the bug

I am running into an error when attempting to create a collection for an entity. I suspect it might have to do with a compound foreign key. Perhaps related to the other issue I opened: #6359.

In any case here is the setup, which is more or less the same as the linked one.

Here is the simplified table schema (Postgres)

create table org (
    id serial primary key
);

create table auth_user (
    id serial primary key,
    org_id int not null references org,

    unique (id, org_id)
);

create table activity_note
(
    id         serial
        primary key,
    user_id    integer                                not null,
    org_id     integer                                not null
        references org
            on update restrict on delete cascade,
    unique (id, org_id),
    foreign key (org_id, user_id) references auth_user (org_id, id)
        on update restrict
);

Reproduction

Here are the entity schema definitions. These were generated using the entity generator

class Org {
  id!: number;
}

const OrgSchema = new EntitySchema({
  class: Org,
  tableName: "org",
  properties: {
    id: { primary: true, type: 'integer' },
  }
});

class ActivityNote {
  id!: number;
  auth_user!: AuthUser;
  org!: Org;
  content!: string;
}

export const ActivityNoteSchema = new EntitySchema({
  class: ActivityNote,
  tableName: "activity_note",
  uniques: [{ name: "activity_note_id_org_id_key", properties: ["id", "org"] }],
  properties: {
    id: { primary: true, type: "integer" },
    content: { type: "text", nullable: false },
    auth_user: {
      kind: "m:1",
      entity: () => AuthUser,
      fieldNames: ["org_id", "auth_user_id"],
      referencedColumnNames: ["org_id", "id"],
    },
    org: {
      kind: "m:1",
      entity: () => Org,
      fieldName: "org_id",
      deleteRule: "cascade",
    },
  },
});

class AuthUser{
  org!: Org;
  id!: number;
  activityNoteCollection = new Collection<ActivityNote>(this);
}

const UserSchema = new EntitySchema({
  class: AuthUser,
  tableName: "auth_user",
  properties: {
    org: { kind: "m:1", entity: () => Org, fieldName: "org_id" },
    id: { primary: true, type: "integer", unique: "auth_user_id_key" },
    activityNoteCollection: {
      kind: "1:m",
      entity: () => ActivityNote,
      mappedBy: "auth_user",
    }
  },
});

test('Query', async () => {
  const em = orm.em.fork();

  await em.insert(new Org());
  const org = em.getReference(Org, 1);

  const user = new AuthUser();
  user.org = org;

  const notes = ["1", "2", "3"];

  user.activityNoteCollection.add(notes.map((n) => {
    const note = new ActivityNote();
    note.content = n;
    note.org = org;

    return note;
  }));

  await em.persistAndFlush(user);
});

This will generate the following error if connected to a postgres database with that schema

(row[prop.name] ?? prop.fieldNames.map) is not iterable
TypeError: (row[prop.name] ?? prop.fieldNames.map) is not iterable
    at /reproreproduction/node_modules/@mikro-orm/knex/AbstractSqlDriver.js:415:64
    at Array.forEach (<anonymous>)
    at /reproreproduction/node_modules/@mikro-orm/knex/AbstractSqlDriver.js:412:23
    at Array.map (<anonymous>)
    at PostgreSqlDriver.nativeInsertMany (/reproreproduction/node_modules/@mikro-orm/knex/AbstractSqlDriver.js:409:25)
    at ChangeSetPersister.persistNewEntitiesBatch (/reproreproduction/node_modules/@mikro-orm/core/unit-of-work/ChangeSetPersister.js:132:39)
    at ChangeSetPersister.persistNewEntities (/reproreproduction/node_modules/@mikro-orm/core/unit-of-work/ChangeSetPersister.js:114:24)
    at ChangeSetPersister.executeInserts (/reproreproduction/node_modules/@mikro-orm/core/unit-of-work/ChangeSetPersister.js:37:25)
    at ChangeSetPersister.runForEachSchema (/reproreproduction/node_modules/@mikro-orm/core/unit-of-work/ChangeSetPersister.js:80:31)
    at ChangeSetPersister.executeInserts (/reproreproduction/node_modules/@mikro-orm/core/unit-of-work/ChangeSetPersister.js:32:25)
    at UnitOfWork.commitCreateChangeSets (/reproreproduction/node_modules/@mikro-orm/core/unit-of-work/UnitOfWork.js:774:39)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at UnitOfWork.persistToDatabase (/reproreproduction/node_modules/@mikro-orm/core/unit-of-work/UnitOfWork.js:741:13)
    at PostgreSqlConnection.transactional (/reproreproduction/node_modules/@mikro-orm/knex/AbstractSqlConnection.js:58:25)
    at UnitOfWork.doCommit (/reproreproduction/node_modules/@mikro-orm/core/unit-of-work/UnitOfWork.js:313:17)
    at UnitOfWork.commit (/reproreproduction/node_modules/@mikro-orm/core/unit-of-work/UnitOfWork.js:286:13)
    at SqlEntityManager.flush (/reproreproduction/node_modules/@mikro-orm/core/EntityManager.js:1327:9)
    at SqlEntityManager.persistAndFlush (/reproreproduction/node_modules/@mikro-orm/core/EntityManager.js:1290:9)
    at Object.<anonymous> (/reproreproduction/src/example.test.ts:98:3)

From some logging, it looks like row is being returned like so row: { content: '1', auth_user: 2, org: 1 }, and the auth_user lookup is expected to be an array but its not.

What driver are you using?

@mikro-orm/postgresql

MikroORM version

6.4.4

Node.js version

20.5.0

Operating system

MacOS

Validations

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions