无法建立OneToOne关系

时间:2020-06-27 13:54:32

标签: mysql node.js typescript orm typeorm

我正在使用Typeorm,并且试图在两个实体:OneToOneProject之间创建Resource关系。 为此,我做到了:

import { Entity, Column, PrimaryGeneratedColumn, OneToMany, OneToOne, JoinColumn, PrimaryColumn } from 'typeorm';
import { Customer } from './customer';

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

    @Column({ nullable: false })
    public name!: string;

    @Column({ nullable: true })
    public description!: string;
    
    @PrimaryColumn({ nullable: false })
    public customer_id!: number;

    @OneToOne(() => Customer)
    @JoinColumn({ name: 'customer_id' })
    public customer!: Customer;

    @Column({ default: false })
    public deleted: boolean = false;
}

然后我有Resource个实体:

import { Entity, Column, PrimaryGeneratedColumn, OneToOne, JoinColumn, PrimaryColumn } from 'typeorm';
import { Project } from './project';

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

    @Column({ nullable: false })
    public name!: string;

    @Column()
    public description: string = "";

    @Column()
    public deleted: boolean = false;

    @PrimaryColumn({ nullable: false })
    public project_id!: number;

    @OneToOne(() => Project)
    @JoinColumn({ name: 'project_id' })
    public project!: Project;
}

基本上,一个Resource可以与一个Project关联,因此我在OneToOne的{​​{1}}属性上方定义了一个project装饰器,然后,我还定义了一个名为Resource的列,我的project_id设计需要此列。

通常Typeorm会创建API列,因此我使用projectId属性:name指定了问题所在:

消息:“ ER_DUP_FIELDNAME:重复的列名'project_id'”, 代码:“ ER_DUP_FIELDNAME”, errno:1060, sqlMessage:“重复的列名'project_id'”, sqlState:'42S21', 索引:0, sql:“在project_idREL_1c2e17cbbe9905b63f1f870679resource)上创建唯一索引project_id”, 名称:“ QueryFailedError”, 查询:'在project_idREL_1c2e17cbbe9905b63f1f870679resource)上创建唯一索引project_id', 参数:[] }

我能够使用以下方法解决此问题:

project_id

但是我不明白为什么在第一个设置中这种方法不起作用,因为我对@JoinColumn({ name: 'project_id', referencedColumnName: 'id' }) 实体做的完全一样,特别是链接Project表并起作用了。

此外,我不确定这是否正确,这些是所创建的约束:

enter image description here

这是到目前为止的ER:

enter image description here

1 个答案:

答案 0 :(得分:2)

它没有用,因为您有一个名为project_id的字段(@PrimaryColumn)和另一个名为project且名称选项设置为project_id的字段。因此,您可以看到TypeORM试图创建两个具有相同名称的字段。这是错误的根源。

您可以删除字段public project_id !: number;。因为TypeORM加载了关系项目!自动(只有ID或整个实体,如果您愿意的话),这样就没用了。

如果您确实想要关系ID,请使用@RelationId装饰器。

以下示例:

import { Entity, Column, PrimaryGeneratedColumn, OneToOne, JoinColumn, PrimaryColumn, RelationId } from 'typeorm';
import { Project } from './project';

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

    @Column({ nullable: false })
    public name!: string;

    @Column()
    public description: string = "";

    @Column()
    public deleted: boolean = false;

    // CHANGES HERE
    @RelationId((resource: Resource) => resource.project)
    public project_id!: number;

    @OneToOne(() => Project)
    @JoinColumn()
    public project!: Project;
}

希望它会有所帮助:)