Skip to content

When requesting nested relations on foreign key primary entities, relation becomes empty entity rather than null #7041

@Nick-Abbott

Description

@Nick-Abbott

Issue Description

When you run a select/find query on an entity whose relation has the foreign key as primary and request a nested relation (i.e ['admin', 'admin.organization']) you receive an entity with null values rather than null.

For example, with 3 entities User, Admin, and Organization User -> Admin -> Organization and Admin has the user foreign relation as the primary key, if you request a User but ask for ['admin', 'admin.organization'] in relations it will return the User with an empty Admin object rather than null. If you only request ['admin'] without admin.organization it works properly.

Expected Behavior

After querying for the entity and the relation was not found it would return the value 'null' for that relation.

Actual Behavior

After querying the entity and the relation was not found, the relation is set to an entity with all values as null

// relations: ['admin', 'admin.organization']
User {
  id: '95bf24be-2e6d-48e5-8ee4-4663e2eb4562',
  randomField: 'bar',
  admin: Admin { randomField: null, organization: null }
}
// relations: ['admin']
User {
  id: '6a59f304-cd4c-4e00-b50c-f7b6e9790745',
  randomField: 'bar',
  admin: null
}

Steps to Reproduce

  1. Create 3 entities with relations between them and one with foreign key as primary
@Entity()
export class User extends BaseEntity {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  randomField: string;

  @OneToOne(() => Admin, admin => admin.user, { nullable: true })
  admin: Admin;
}

@Entity()
export class Admin extends BaseEntity {
  @OneToOne(() => User, user => user.admin, { primary: true })
  @JoinColumn()
  user: User;

  @OneToOne(() => Organization, org => org.admin)
  @JoinColumn()
  organization: Organization;

  @Column()
  randomField: string;
}

@Entity()
export class Organization extends BaseEntity {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @OneToOne(() => Admin, admin => admin.organization)
  admin: Admin;

  @Column()
  randomField: string;
}
  1. Create a User entity but not an Admin entity
  2. Run a findOne query on the User entity you added and request admin be included:
(async () => {
  const connection = await createConnection();
  let testUser = User.create({ randomField: 'foo' });
  try {
    await testUser.save();
    console.log(await User.findOne(testUser.id, { relations: ['admin', 'admin.organization'] }));
    console.log(await User.findOne(testUser.id, { relations: ['admin'] }));
  } finally {
    await testUser.remove();
    await connection.close();
  }
})();
User {
  id: '2494498f-75d2-4fbc-b4b6-a43f910252b7',
  randomField: 'foo',
  admin: Admin { randomField: null, organization: null }
}
User {
  id: '2494498f-75d2-4fbc-b4b6-a43f910252b7',
  randomField: 'foo',
  admin: null
}

My Environment

Dependency Version
Operating System Windows 10 v1909
Node.js version v12.13.0
Typescript version v4.0.3
TypeORM version v0.2.28

Additional Context

This example was created using one-to-one relationships but works with any relationship where the primary key is the foreign key

Interesting aside... Moving the JoinColumn between admin and organization from admin to organization causes the 'admin.organization' relationship to fail as the ON part of the left join is not populated

Relevant Database Driver(s)

  • aurora-data-api
  • aurora-data-api-pg
  • better-sqlite3
  • cockroachdb
  • cordova
  • expo
  • mongodb
  • mysql
  • nativescript
  • oracle
  • postgres
  • react-native
  • sap
  • sqlite
  • sqlite-abstract
  • sqljs
  • sqlserver

Are you willing to resolve this issue by submitting a Pull Request?

  • Yes, I have the time, and I know how to start.
  • Yes, I have the time, but I don't know how to start. I would need guidance.
  • No, I don't have the time, although I believe I could do it if I had the time...
  • No, I don't have the time and I wouldn't even know how to start.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions