I got the error
QueryFailedError: null value in column "id" of relation "workspaces" violates not-null constraint
when trying to run cli: yarn create:workspace wsp_name
here is the cli file:
import { Injectable } from '@nestjs/common';
import { Command, Positional } from 'nestjs-command';
import { WorkspacesCommandService } from '../application/commands/workspaces.command.service';
import { CreateWorkspaceDto } from '../interfaces/dto/create-workspace.dto';
@Injectable()
export class WorkspaceCommandLine {
constructor(private _workspaceCommandService: WorkspacesCommandService) {}
@Command({
command: 'create:workspace <name>',
describe: 'create a workspace',
})
async create(
@Positional({ alias: 'n', describe: 'Name', name: 'name', type: 'string' }) name: string
// @Positional({ alias: 'd', describe: 'Domain', name: 'domain', type: 'string' }) domain?: string
) {
const createWorkspaceDto: CreateWorkspaceDto = {
// domain,
name,
};
try {
console.info('======================CREATE WORKSPACE ============================');
const createdWorkspace = await this._workspaceCommandService.create(createWorkspaceDto);
console.info('Created workspace..', createdWorkspace);
} catch (err) {
// console.error(err);
process.exit(1);
}
process.exit(1);
}
}
and this is the entity file:
import { WorkspaceStatusEnum } from '@shared/interfaces/workspace.enum';
import {
Column,
CreateDateColumn,
Entity,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';
@Entity('workspaces')
export class Workspace {
@PrimaryGeneratedColumn()
id: string;
@Column()
name: string;
@Column({ nullable: true })
domain: string;
@Column({
default: WorkspaceStatusEnum.PENDING,
// enum: WorkspaceStatusEnum,
// type: 'enum',
})
status: WorkspaceStatusEnum;
@CreateDateColumn({ name: 'created_at' })
createdAt: Date;
@UpdateDateColumn({ name: 'updated_at' })
updatedAt: Date;
}
I did test in jestjs for function create in commandService and it can create normally. here is the command service to test:
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Workspace } from '@shared/infrastructures/data-access/ORMs/workspaces';
import { WorkspacesRepository } from '@shared/infrastructures/data-access/repositories/workspaces.repository';
import { plainToClass } from 'class-transformer';
import { CreateWorkspaceDto } from '../../interfaces/dto/create-workspace.dto';
import { DeleteWorkspaceDto } from '../../interfaces/dto/delete-workspace.dto';
import { UpdateWorkspaceDto } from '../../interfaces/dto/update-workspace.dto';
@Injectable()
export class WorkspacesCommandService {
constructor(
@InjectRepository(WorkspacesRepository)
private readonly _workspacesRepository: WorkspacesRepository
) {}
async create({ ...createWorkspaceDto }: CreateWorkspaceDto) {
try {
// Check and validate
this.checkUniqueDomain(createWorkspaceDto.domain);
this.checkValidateDomain(createWorkspaceDto.domain);
const workspace = await this._workspacesRepository.save(createWorkspaceDto);
return plainToClass(Workspace, workspace);
} catch (error) {
console.log(error);
throw new Error('Failed to create workspace');
}
}
async update({ ...updateWorkspaceDto }: UpdateWorkspaceDto) {
try {
if (!(await this._workspacesRepository.findOne(updateWorkspaceDto.id))) {
throw new Error('Workspace not found');
}
// Check and validate
this.checkUniqueDomain(updateWorkspaceDto.domain);
this.checkValidateDomain(updateWorkspaceDto.domain);
await this._workspacesRepository.update(updateWorkspaceDto.id, updateWorkspaceDto);
const workspace = await this._workspacesRepository.findOneOrFail({
id: updateWorkspaceDto.id,
});
return workspace;
} catch (error) {
throw new Error('Failed to update workspace');
}
}
async delete({ ...deleteWorkspaceDto }: DeleteWorkspaceDto) {
try {
const workspace = await this._workspacesRepository.findOne(deleteWorkspaceDto.id);
if (!workspace) {
throw new Error('Workspace not found');
}
await this._workspacesRepository.remove(workspace);
} catch (error) {
throw new Error('Failed to delete workspace');
}
}
async checkUniqueDomain(domain: string) {
const existingWorkspace = await this._workspacesRepository.findOne({
domain: domain,
});
if (existingWorkspace) {
throw new Error('Workspace domain already exists');
}
}
async checkValidateDomain(domain: string) {
const domainRegex = new RegExp('^((?!-)[A-Za-z0–9-]{1,63}(?<!-).)+[A-Za-z]{2,6}$');
const isValidDomain = domainRegex.test(domain);
if (!isValidDomain) {
throw new Error('Invalid domain');
}
}
}
My question is: did I implement something wrong? What are the flow when it runs from the cli to the db (I use postgres)? Where and when it generate the id and other attribute by default?