Issue of Primary key in TypeORM - node.js

I have one BaseEntity which is common for multiple modules. so I have created some common column in this entity class. all the classes will extend this class.
export abstract class BaseEntity {
#PrimaryGeneratedColumn('uuid')
id: string;
#CreateDateColumn({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })
createdAt: Date;
#UpdateDateColumn({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })
modifiedAt: Date;
#DeleteDateColumn({ type: 'timestamp' })
deletedAt: Date;
}
my Certificate class is extending BaseEntity. now I want to generate value of certificateNo automatically.
Entity({ name: 'certificate' })
export class Certificate extends BaseEntity {
#ApiProperty()
#Generated('increment')
certificateNo: string;
#ApiProperty()
#Column({ type: 'varchar', length: 100 })
requestStatus: RequestStatus;
#ApiProperty()
#Column({ type: 'varchar', length: 100 })
sponser: string;
}
in the certificateNo column as soon as I put #Column() decorator it gives error. otherwise this column does not get created in database. DB is postgres.
#ApiProperty()
#Column() //if I write #Column() error comes. If I dont write ,column not created in DB
#Generated('increment')
certificateNo: string;
Error is:-
[Nest] 24080 - 12/01/2021, 12:59:35 PM [ExceptionHandler] syntax error at or near "NOT" +4ms
QueryFailedError: syntax error at or near "NOT"

You should specify a correct column type for the "certificateNo" property. See below:
#Entity({ name: "certificate" })
export class Certificate extends BaseEntity {
#Column({type: "integer"})
#Generated("increment")
certificateNo: number;
#Column({ type: "varchar", length: 100 })
requestStatus: string;
#Column({ type: "varchar", length: 100 })
sponser: string;
}

Related

Typeorm migration with bi-directional manytomany resulting in TypeError: Class exends value undefined is not a constructor or null

I'm working on a nestjs project with TypeORM. I'm setting up a bidirectional ManyToMany relationship between two entities: Notes and Gcalevents. Every Note could be linked to multiple Gcalevents, and every Gcalevent could be linked to many Notes.
Snippets from my entity definitions look like this:
base.entity.ts:
export class BaseEntity {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column({ type: 'boolean', default: true })
isActive: boolean;
... // some more fields
}
note.entity.ts:
import { Gcalevent } from './gcalevent.entity';
import { BaseEntity } from './base.entity';
#Entity({ name: 'note' })
export class Note extends BaseEntity {
#Column({ type: 'varchar', length: 300 })
title: string;
...
#ManyToMany(() => Gcalevent, (gcalevent) => gcalevent.notes)
#JoinTable()
gcalevents: Gcalevent[]
}
gcalevent.entity.ts:
import { Note } from "./note.entity";
#Entity({ name: 'gcalevent' })
export class Gcalevent {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column({
type: 'varchar',
nullable: false,
})
eventId: string;
...
#ManyToMany(() => Note, (note) => note.gcalevents)
notes: Note[]
}
I believe I'm declaring the ManyToMany relationships correctly, but when I try to generate the TypeORM migration, I get the error TypeError: Class extends value undefined is not a constructor or null, which points to both the note.entity and gcalevent.entity files
I'm guessing this has something to do with the gcalevent.entity and note.entity files importing each other, combined with the note.entity file importing BaseEntity, but not sure how to fix it!
I had the same problem, I've found here
this "workaround" for the issue.
Try using "strings" instead of "types" in the #ManyToMany decorator:
note.entity.ts:
import { Gcalevent } from './gcalevent.entity';
import { BaseEntity } from './base.entity';
#Entity({ name: 'note' })
export class Note extends BaseEntity {
#Column({ type: 'varchar', length: 300 })
title: string;
...
#ManyToMany("Gcalevent","notes")
#JoinTable()
gcalevents: Gcalevent[]
}
gcalevent.entity.ts:
import { Note } from "./note.entity";
#Entity({ name: 'gcalevent' })
export class Gcalevent {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column({
type: 'varchar',
nullable: false,
})
eventId: string;
...
#ManyToMany("Note","gcalevents")
notes: Note[]
}

Insert or update on table violates foreign key constraint error

I'm trying to make a POST-request and getting this error
{
"msg": "insert or update on table "client" violates foreign key constraint "FK_e61c5ecfaabf7e6d9285fbfb070""
}
My Client entity:
#Entity()
export default class Client extends BaseEntity {
#PrimaryGeneratedColumn()
clientId: number;
#Column({ type: 'enum', enum: ClientStatus, default: ClientStatus.NOT_CLIENT })
clientStatus: ClientStatus;
#Column({ nullable: true })
countryOfResidence: string;
#Column({ nullable: true, length: 30 })
firstName: string;
#Column({ nullable: true, length: 30 })
lastName: string;
#Column({ nullable: true, length: 30 })
surName: string;
#OneToOne(() => Passport)
#JoinColumn({ referencedColumnName: 'passportId', name: 'passportId' })
passportId: string;
#OneToOne(() => AuthVerification)
#JoinColumn({ referencedColumnName: 'mobilePhone', name: 'mobilePhone' })
mobilePhone: string;
#OneToOne(() => UserProfile, (userProfile) => userProfile.clientId)
userProfile: UserProfile;
}
My AuthVerification entity:
#Entity()
class AuthVerification extends BaseEntity {
#PrimaryColumn()
#OneToOne(() => Client)
mobilePhone: string;
#Column({ nullable: true })
email: string;
#Column({ nullable: false, length: 6 })
verificationCode: string;
}
Line in migration where constraint key mentioned:
await queryRunner.query(
`ALTER TABLE "client" ADD CONSTRAINT "FK_e61c5ecfaabf7e6d9285fbfb070" FOREIGN KEY ("mobilePhone") REFERENCES "auth_verification"("mobilePhone") ON DELETE NO ACTION ON UPDATE NO ACTION`
);
So, I can't figure out where the problem is.

Unable to create TypeORM DTO in Nest.js with Foreign Key Column

DB Entity
#Entity()
export class Estimate {
#PrimaryGeneratedColumn()
estimateId: number;
#ManyToOne(() => Customer, (customer) => customer.customerId)
customer: Customer;
#ManyToOne(() => Organization, (organization) => organization.organizationId)
organization: Organization;
#ManyToMany(() => Item)
#JoinTable()
items: Item[];
#ManyToMany(() => Tax)
#JoinTable()
taxes: Tax[];
#Column({ type: 'varchar', length: 36 })
estimateNumber: string;
#Column({ type: 'varchar', length: 36 })
orderNumber: string;
#Column({ type: 'timestamptz' })
estimateDate: string;
#Column({ type: 'timestamptz' })
expiryDate: string;
#Column({ type: 'varchar', length: 75 })
salesPersonName: string;
#Column({ type: 'money' })
subTotal: number;
#Column({ type: 'varchar', length: 12 })
discountType: string;
... trimmed
}
My DTO
export class CreateEstimateDto {
customer: number; // error
organization: number; // error
items: number[]; // error
taxes: number[]; // error
estimateNumber: string;
orderNumber: string;
estimateDate: string;
expiryDate: string;
salesPersonName: string;
subTotal: number;
...trimmed
}
service.ts
import { Injectable } from '#nestjs/common';
import { InjectRepository } from '#nestjs/typeorm';
import { Repository } from 'typeorm';
import { CreateEstimateDto } from './dto/create-estimate.dto';
import { UpdateEstimateDto } from './dto/update-estimate.dto';
import { Estimate } from './entities/estimate.entity';
#Injectable()
export class EstimatesService {
constructor(
#InjectRepository(Estimate)
private estimateRepository: Repository<Estimate>,
) {}
create(createEstimateDto: CreateEstimateDto) {
return this.estimateRepository.insert(createEstimateDto); // type mismatch
}
}
Getting error
Argument of type 'CreateEstimateDto' is not assignable to parameter of type 'QueryDeepPartialEntity<Estimate> | QueryDeepPartialEntity<Estimate>[]'.
Type 'CreateEstimateDto' is not assignable to type 'QueryDeepPartialEntity<Estimate>'.
Types of property 'customer' are incompatible.
Type 'number' is not assignable to type '(() => string) | QueryDeepPartialEntity<Customer>'.ts(2345)
The following columns are foreign key columns
customer, organization, items, taxes
Workaround 1:
I can make DTO field's type to any - that will come as {} object in swagger spec
What is actually happening here is that it's trying to convert integer to category type and error happens here. You can fetch foreign relations and then pass it through insert method. As I know there is no straight way of doing this in nest.
Edit
for example for your customer relation you can do this:
const customer = customerRepository.findOne(createEstimateDto.customer);
and then pass it to insert method:
return this.estimateRepository.insert(Object.assign(createEstimateDto, { customer }));

Use repository.clear() to clear two tables with ManyToOne

Is there any ways to clear two tables connected with ManyToOne?
Table A
#Entity('table_A')
export class TableA{
#PrimaryGeneratedColumn()
id: number;
#Column()
B_ID: number;
#ManyToOne(() => TableB)
tableB: TableB;
#Column()
userId: number;
#ManyToOne(() => User)
user: User;
}
Table B
#Entity('table_B')
export class TableB{
#PrimaryGeneratedColumn()
id: number;
#Column({ name: 'time', type: 'text' })
time: Date;
#Column({ name: 'msgid', type: 'int', nullable: true })
msgid: number;
#Column({ name: 'event', type: 'text', nullable: true })
event: string;
}
I can use this.tableARepository.clear(); to clear Table_A but when I run this.tableBRepository.clear(); Data in Table A restores.
Anyone have a clue on this? Any help is much appreciated.

Find - relations xxx not found

I am trying to return and entity including its relation but I am getting an error saying relation xxx not found. I am using the repository pattern.
#Entity({ name: 'person' })
export class PersonEntity {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column({ type: 'number' })
statusId: number;
#ManyToOne(() => StatusEntity, status => status.id)
status: StatusEntity;
}
#Entity({ name: 'statuses' })
export class StatusEntity {
#PrimaryGeneratedColumn('increment')
id: number;
#Column({ type: 'varchar', length: 256 })
name: string;
}
I am using postgres and I have a foreign key declared:
"public"."person" ADD CONSTRAINT "FK_person_statusid" FOREIGN KEY ("statusId") REFERENCES "public"."statuses"("id")
In my service:
public async getAll(): Promise<PersonEntity[]> {
return await this.personRepository.find({ relations: ['statuses'] });
}
#Entity({ name: 'person' })
export class PersonEntity {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column({ type: 'number' })
statusId: number;
#ManyToOne(() => StatusEntity)
#JoinTable()
status: StatusEntity;
}
#Entity({ name: 'status' })
export class StatusEntity {
#PrimaryGeneratedColumn()
id: number;
#Column({ type: 'varchar', length: 256 })
name: string;
}
Note that I have changed StatusEntity name from statuses to status.
Could you delete the foreign key you created manually, and then update your entity like below and try?
#Entity({ name: 'person' })
export class PersonEntity {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column({ type: 'number' })
statusId: number;
#ManyToOne(() => StatusEntity)
#JoinColumn({ name: 'statusId })
status: StatusEntity;
}

Resources