typeorm icon indicating copy to clipboard operation
typeorm copied to clipboard

column "x" specified more than once

Open melihorhan opened this issue 4 years ago • 11 comments

Issue Description

I get an error while saving over an embedded object. It holds both the user and its related user id. For example;

  @ManyToOne(() => User)
  @JoinColumn({ name: 'created_by' })
  createdBy: User;

  @Column({ name: "created_by", nullable: true })
  createdById: number;

When I want to save data, the created_by and updated_by fields are duplicates trying to save to the db. As seen below, the created_by and updated_by fields are duplicated.

'INSERT INTO "role"("name", "type", "description", "created_by", "updated_by", "created_at", "updated_at", "deleted_at", "created_by", "updated_by", "created_host", "updated_host") VALUES ($1, DEFAULT, $2, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, $3, $4) RETURNING "id", "created_at", "updated_at", "deleted_at"'

As a result, I get the following error.

'column "created_by" specified more than once'

These are my entities :

//base entity
export abstract class EntityBase extends BaseEntity {
    @PrimaryGeneratedColumn()
    id: number;
}

//embedded entity
export class CuBy {

    @ManyToOne(() => User)
    @JoinColumn({ name: 'created_by' })
    createdBy: User;

    @ManyToOne(() => User)
    @JoinColumn({ name: 'updated_by' })
    updatedBy: User;

    @Column({ name: "created_by", nullable: true })
    createdById: number;

    @Column({ name: "updated_by", nullable: true })
    updatedById: number;

     static new(): CuBy {

        const currentUser = HttpContext.currentUser();
        const cu = new CuBy();

        cu.createdBy = new User();
        cu.updatedBy = new User();

        cu.createdBy.id = currentUser.id;
        cu.updatedBy.id = currentUser.id;

        return cu;
    }

}

export enum RoleType {
    SUPER_ADMIN = 10,
    ADMIN = 15,
    MODERATOR = 20,
    SUPER_MODERATOR = 25
}

@Entity("role")
@Unique("index_type", ["type"])
export class Role extends EntityBase {
   
    @IsString({ always: true })
    @Column({ unique: true, length: 50 })
    name: string

    @Column({ name: "type", type: "enum", enum: RoleType, nullable: true })
    type: RoleType

    @IsOptional({ always: true })
    @IsString({ always: true })
    @Column({ nullable: true, length: 256 })
    description: string

    @Column(() => CuBy, { prefix: false })
    userBy: CuBy

    static async with(name: string, description: string) {
        const role = new Role();
        role .name = name;
        role .description = description;
        await role.save();
    }
}

@EventSubscriber()
export class EverythingSubscriber implements EntitySubscriberInterface {

    constructor(connection: Connection) {
        connection.subscribers.push(this);
    }

    beforeInsert(event: InsertEvent<any>) {
        event.metadata.embeddeds.forEach(t=>{
            if(t.type.name === CuBy.name){
                event.entity["userBy"] = CuBy.new();
            }
        })
    }
}



Any idea how to solve this?

My Environment

Dependency Version
Operating System
Node.js version v12.3.0
Typescript version v3.7.5
TypeORM version v0.2.29

Additional Context

Relevant Database Driver(s)

  • [ ] aurora-data-api
  • [ ] aurora-data-api-pg
  • [ ] better-sqlite3
  • [ ] cockroachdb
  • [ ] cordova
  • [ ] expo
  • [ ] mongodb
  • [ ] mysql
  • [ ] nativescript
  • [ ] oracle
  • [x] 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.

melihorhan avatar Dec 05 '20 09:12 melihorhan

I believe you don't need to (and in this case shouldn't) use @JoinColumn if you have manually defined the createdById column. The matching between relation and relation id column is based on the property name rather than the database name, so the custom column name shouldn't make a difference either.

nebkat avatar Dec 05 '20 19:12 nebkat

@nebkat hi, I established this relationship by following here. I guess there is a problem with embedded objects. If I move the fields on the embedded object to the role entity, there is no problem.

@Entity("role")
@Unique("index_type", ["type"])
export class Role extends EntityBase {
   
    @IsString({ always: true })
    @Column({ unique: true, length: 50 })
    name: string

    @Column({ name: "type", type: "enum", enum: RoleType, nullable: true })
    type: RoleType

    @IsOptional({ always: true })
    @IsString({ always: true })
    @Column({ nullable: true, length: 256 })
    description: string

    @ManyToOne(() => User)
    @JoinColumn({ name: 'created_by' })
    createdBy: User;

    @ManyToOne(() => User)
    @JoinColumn({ name: 'updated_by' })
    updatedBy: User;

    @Column({ name: "created_by", nullable: true })
    createdById: number;

    @Column({ name: "updated_by", nullable: true })
    updatedById: number;

    static async with(name: string, description: string) {
        const currentUser = HttpContext.currentUser();
        const role = new Role();

        role .name = name;
        role .description = description;

         roleEntity.createdBy = new User();
         roleEntity.updatedBy = new User();

         roleEntity.createdBy.id = currentUser.id;
         roleEntity.updatedBy.id = currentUser.id;

         await role.save();
    }
}

melihorhan avatar Dec 06 '20 10:12 melihorhan

i have the same issue. @melihorhan do you find a way to solve this?

yusef-ho avatar Oct 19 '21 19:10 yusef-ho

i have the same issue. @melihorhan do you find a way to solve this?

@yusef-ho Unfortunately I couldn't solve this problem. The contributors needs to review it.

melihorhan avatar Oct 19 '21 19:10 melihorhan

Is there any solution to this issue?

nadavkaner avatar Nov 11 '21 09:11 nadavkaner

TBH it's unlikely there is an issue, because we have similar use cases and they are test-covered. But you can create a PR with a minimal reproduction failing test and I'll check it.

pleerock avatar Nov 11 '21 11:11 pleerock

If one uses Single Table Inheritance and tries to reference columns in both the parent and child table models using the @Column decorator, one will get his error as well...

bombillazo avatar Aug 30 '22 06:08 bombillazo

Also getting this issue. Seems to happen when the column name doesn't use camel case.

awonihlgard avatar Jan 11 '24 15:01 awonihlgard

I solved the problem by using the method upstairs. you use 'created_by' to join table , and the same cloumn in the entity cause the issue, you delete the '@Column' above the cloumn, then you can use the cloumn to query or display but do not need to assignment.

YQinglin avatar Apr 17 '24 07:04 YQinglin

any updates?

zolzaya avatar Apr 20 '24 14:04 zolzaya

any updates on this? I'm running into the same issue.

BradStell avatar Jun 23 '24 04:06 BradStell