Search code examples
foreign-keystypeormtypeorm-datamapper

TypeORM why is my relationship column undefined? foreign-key is undefined


I just use TypeORM and find the relationship column is undefined


@Entity({name: 'person'})
export class Person {
    @PrimaryGeneratedColumn('uuid')
    id!: string;

    @OneToOne( () => User)
    @JoinColumn()
    user!: User;

    @Column({
        type: "enum",
        enum: PersonTitle,
        default: PersonTitle.Blank
        })
    title?: string;

    @Column({type: 'varchar', default: ''})
    first_name!: string;

    @Column('varchar')
    last_name!: string;

    @ManyToOne(() => Organization, org => org.people, { nullable: true})
    belong_organization!: Organization;

and I also have Organization entity:

export class Organization {
    @PrimaryGeneratedColumn('uuid')
    id!: string;
...
}

when I use Repository like:

 const db = await getDatabaseConnection()
 const prep = db.getRepository<Person>('person')
 presult = await prep.findOne({where: {id}})
 console.log(result)

my result is:

Person {
  id: '75c37eb9-1d88-4d0c-a927-1f9e3d909aef',
  user: undefined,
  title: 'Mr.',
  first_name: 'ss',
  last_name: 'ls',
  belong_organization: undefined,  // I just want to know why is undefined? even I can find in database the column
  expertise: [],
  introduction: 'input introduction',
  COVID_19: false,
  contact: undefined
}

the database table like:

"id"    "title" "first_name"    "last_name" "expertise" "COVID_19"  "userId"    "belongOrganizationId"  "introduction"
"75c37eb9-1d88-4d0c-a927-1f9e3d909aef"  "Mr."   "test"  "tester"    "nothing"   "0" "be426167-f471-4092-80dc-7aef67f13bac"  "8fc50c9e-b598-483e-a00b-1d401c1b3d61"  "input introduction"

I want to show organization id, how typeORM do it? Foreign-Key is present undefined?


Solution

  • You need to either lazy load the relation or you need to specify the relation in the find

    Lazy:

    @Entity({name: 'person'})
    class Person {
        ...
        @ManyToOne(() => Organization, org => org.people, { nullable: true})
        belong_organization!: Organization;
        ...
    }
    
    ...
    
    async logOrganization() {
        const db = await getDatabaseConnection()
        const prep = db.getRepository<Person>('person')
        presult = await prep.findOne({where: {id}})
        console.log(await result.belong_organization)
    }
    

    Find

    const prep = db.getRepository<Person>('person')
    presult = await prep.findOne({
        where: { id },
        relations: ["belong_organization"]
    })
    

    You could also always do an eager load, but i'd advise against this since then it would always do the join when it fetches a person.

    If you want to query the belong_organizationId you need to add its field to the person entity. This field is usual something like belongOrganizationId

    That would make

    @Entity({name: 'person'})
    class Person {
        ...
        @Column()
        belongOrganizationId:number
    
        @ManyToOne(() => Organization, org => org.people, { nullable: true})
        belong_organization!: Organization;
        ...
    }
    

    This would make it possible to query for its id too.

    You could also query it more directly but this leaves you with some pretty ugly and unmaintainable code:

    const findOptions: {
        where :{
            id,
            'belong_organization.id': belong_organizationId
        }
    }