BloodStainedCrow
BloodStainedCrow

Reputation: 11

TypeORM One-To-One Relation: Entity column not found on either side?

My postgreSQL DB contains three Entities:

@Entity()
export class User {

    constructor(email: string, displayname: string, passwordHash: string, salt: string) {
        this.email = email
        this.displayname = displayname;
        this.passwordHash = passwordHash;
        this.salt = salt;
    }

    @PrimaryColumn()
    email!: string;

    @Column()
    passwordHash!: string;

    @Column()
    displayname!: string;

    @Column()
    salt!: string;

    @OneToOne(type => Cafe, Cafe => Cafe.owner, {cascade: true})
    cafe!: Cafe;
}


@Entity()
export class Cafe {
    @PrimaryGeneratedColumn()
    id!: number;

    //TESTING
    @Column()
    name!: string;
    
    @OneToOne(type => User, User => User.cafe)
    owner!: User;

    @OneToOne(type => Gamestate, Gamestate => Gamestate.cafe, { cascade: ["insert", "remove", "soft-remove", "recover"] })
    gamestate!: Gamestate;
}


@Entity()
export class Gamestate {
    @PrimaryGeneratedColumn()
    id!: number;

    @Column()
    name!: string;

    @OneToOne(type => Cafe, Cafe => Cafe.gamestate)
    cafe!: Cafe;

    public update(): void {
        //TODO: do update Logic here
    }
}

When creating a user with cafe and gamestate filled, they are properly cascaded into the DB. But when I try to find a Gamestate via

const foundGamestate = await connection.getRepository(Gamestate).find({ where: { cafe: { name: "Test" } }});

I get an error:

EntityColumnNotFound: No entity column "cafe" was found.

Even after trying to find a Cafe instead, the Error persists, so it seems like neither side actually has the One-To-One Relation?

const foundCafe = await connection.getRepository(Cafe).find({ where: { gamestate: { name: "Test" } }});

EntityColumnNotFound: No entity column "gamestate" was found.

Is my Entity setup wrong, or am I using find/where incorrectly?

Upvotes: 1

Views: 13252

Answers (2)

user14195530
user14195530

Reputation:

This took me some time to figure. The relation part on: |

return this.messageRepository.find({ relations: ['user', 'sender'] })
is the same name as the variable you define in entity, not the table name

 @OneToOne(() => User)
    @JoinColumn({ name: "userId" })
    user: User;

    @OneToOne(() => User)
    @JoinColumn({ name: "senderId" })
    sender: User;

Upvotes: 0

Eranga Heshan
Eranga Heshan

Reputation: 5814

Update:

When using find method, typeorm does not allow adding where conditions on properties of related entities as of now.

There are 2 open issues to handle this behavior and once either of those is solved, the following answer would work:

Issues:


You missed adding the required @JoinColumn() annotation on one side of your OneToOne relation. See this article for more info.

Update your Cafe entity as below:

@Entity()
export class Cafe {
    @PrimaryGeneratedColumn()
    id!: number;

    //TESTING
    @Column()
    name!: string;
    
    @OneToOne(type => User, user => user.cafe)
    @JoinColumn()
    owner!: User;

    @OneToOne(type => Gamestate, gamestate => gamestate.cafe, { cascade: ["insert", "remove", "soft-remove", "recover"] })
    @JoinColumn()
    gamestate!: Gamestate;
}

Then use the following syntax to query:

const foundGamestate = await connection.getRepository(Gamestate).find({
    relations: ["cafe"],
    where: { cafe: { name: "Test" } }
});

Hope this helps you. Cheers 🍻!

Upvotes: 2

Related Questions