typeorm: Foreign key not showing on a find call

Issue type:

[x ] question [ ] bug report [ ] feature request [ ] documentation issue

Database system/driver:

[ ] cordova [ ] mongodb [ ] mssql [x ] mysql / mariadb [ ] oracle [ ] postgres [ ] sqlite [ ] sqljs [ ] react-native [ ] expo

TypeORM version:

[ x] latest [ ] @next [ ] 0.x.x (or put your version here)

Steps to reproduce or a small repository showing the problem: In order to reproduce the problem you need to have 2 entities, one called Photo and the other one called User. User has an auto-generated id of type string and a name. Photo has also an auto-generated id, which is also an string, and has a @ManyToOne reference to User, more specifically, to userId. However, whenever I do a repository.find({]) the userId field is not returned, however it is stored inside photo’s table. I am using nestjs framework.

What I have now is the following code:

User entity:

        @Entity()
        export class User extends RootEntity {
            @PrimaryColumn()
            public id: string;

            public name: string;
        }

Photo entity:


        @Entity()
        export class Photo extends RootEntity {
            @PrimaryGeneratedColumn()
            public id: string;

            @ManyToOne((type) => User)
            public user: User;
        }

My create-photo.dto.ts:


        export class CreatePhotoDto {
            @IsDefined()
            public user: User;
        }

My photo service class:


        @Injectable()
        export class PhotoService {
            constructor(
                @InjectRepository(Photo)
                private readonly photoRepository: Repository<Photo>,
            ) {}

            public createPhoto(photo: CreatePhotoDto) {
                this.photoRepository.save(photo);
           }
            public findAll() {
                return this.photoRepository.find({});
            }
       }

My photo controller class:


        @Controller("photo")
        export class PhotoController {
            constructor(private readonly photoService: PhotoService) {}

            @Get()
            public findAll() {
                return this.photoService.findAll();
            }
         @Post()
            public createPhoto(@Body() createPhotoDto: CreatePhotoDto) {
                this.photoService.createPhoto(createphotoDto);
            }

       }

Whenever I call to findAll, it returns just the id of the photo. Thanks in advance.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 5
  • Comments: 17 (6 by maintainers)

Commits related to this issue

Most upvoted comments

Change your code to:

  @Entity()
        export class Photo extends RootEntity {
            @PrimaryGeneratedColumn()
            public id: string;

            @Column()
            public userId: number;

            @ManyToOne((type) => User)
            public user: User;
        }

How do you expect userId to be when its not defined in your model.

I had the same problem, but adding eager: true as a connection option fixed it. From https://typeorm.io/#/relations

eager: boolean - If set to true, the relation will always be loaded with the main entity when using find* methods or QueryBuilder on this entity

       @Entity()
        export class Photo extends RootEntity {
            @PrimaryGeneratedColumn()
            public id: string;

            @ManyToOne((type) => User, { eager: true })
            public user: User;
        }

I guess you do something wrong. Create a PR with a failing test and minimal reproduction code and lets see if it fails on CI.

if we explicitly declare something like @JoinColumn({name: "userId"}) will it work? I see no, on my setup. Please stop blaming the users and try to fix it. userId is a valid field in the db and if we select it in find() function, e.g. Photo.find({select: ["id", "userId"]}), it should be a valid request and valid SQL.

Seems to be working fine now, Dec 2020:

@Field(type => MyModel)
@ManyToOne(type => MyModel, mod => mod.items)
mod: MyModel;

@Column()
@Field()
modelId: string;

There are some caveats though. Note that the modelId column is non nullable, so when seeding the proper way would be model2.myModelId = myModel.id vs the standard model2.myModel = myModel. Also, queries may need to be rewritten:

  let entity = await MyModel.findOne({ where: {user: {id: 'asdf'}} }) as any; //vs
  let entity = await MyModel.findOne({ where: {userId: 'asdf'} }) as any;

In my opinion, defining an id column is preferred to eager loading or manually defining relations. Getting FK only (vs all fields) improves performance. Also a full query may cause errors when you try to save a model with nested objects: the server might try to overwrite those nested objects in the DB. Defining the FK ids explicitly give you the most control.

Also, in my opinion, TypeORM should make these FK ids available by default and search by id by default. Forcing you to manually create this id column, despite it already being created in the DB/TypeORM backend, seems brittle to me.

I had the same problem, but adding eager: true as a connection option fixed it. From https://typeorm.io/#/relations

eager: boolean - If set to true, the relation will always be loaded with the main entity when using find* methods or QueryBuilder on this entity

       @Entity()
        export class Photo extends RootEntity {
            @PrimaryGeneratedColumn()
            public id: string;

            @ManyToOne((type) => User, { eager: true })
            public user: User;
        }

Hey there, actually I am having this problem now. Actually it has been working fine for 3-4 months and now suddenly I don’t get foreign key id anymore. I do not want to use eager as I don’t want whole relation. I need just the id. Have you found any other solution to this?