这是我的实体:
import { BaseEntity, Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from 'typeorm';
import { Client } from './client.entity';
@Entity({ name: 'directory_dir' })
export class Directory extends BaseEntity {
@PrimaryGeneratedColumn("uuid", { name: 'dir_id' })
id: string;
@Column( { name: 'dir_name' } )
name: string;
@JoinColumn({ name: 'cli_client_id'})
@ManyToOne(() => Client, { eager: true })
client: Client;
}
表是通过liquidbase创建的:
<changeSet id="3" author="Me">
<createTable tableName="DIRECTORY_DIR">
<column name="DIR_ID" type="uuid">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="DIR_NAME" type="varchar(64)">
<constraints nullable="false"/>
</column>
<column name="CLI_CLIENT_ID" type="uuid">
<constraints nullable="false" foreignKeyName="FK_DIRECTORY_DIR_CLI_CLIENT_ID" references="CLIENT_CLI(CLI_ID)"/>
</column>
</createTable>
</changeSet>
我努力把它插入到数据库中。我尝试了几种语法,但每次,我得到一个错误,因为id不是自动生成的:
列' dir_id ';关系"directory_dir"违反非空约束
我试过了:
const directory = new Directory();
/* Also tried this one
* const directory = this.directoryRepository.create({
* name: makeDirRequest.name,
* client: user.client
* });
*/
directory.name = makeDirRequest.name;
directory.client = user.client;
this.logger.log('directory', JSON.stringify(directory));
// Also tried with insert instead of save
return await this.directoryRepository.save(directory);
在日志中,我可以看到没有dir_id
,但是,在我理解它的方式中,它应该不是一个问题,因为我希望TypeOrm在生成INSERT
语句时这样做。
当我用SQL语句在数据库中插入实体时,我可以很容易地从typeORM中找到它们,因此typeORM配置似乎没问题。
问题来自于PostgreSQL中表的定义。为了解释如何自动生成主键,必须提供默认值。
在Liquibase中像这样声明列可以完成以下工作:
<column name="DIR_ID" type="uuid" defaultValue="gen_random_uuid()">
<constraints primaryKey="true" nullable="false"/>
</column>
我刚刚添加了defaultValue="gen_random_uuid()"
。
gen_random_uuid()
是新的uuid_generate_v4()
,可从Postgres 13
从这里开始,我可以创建实体并像这样插入它:
return await Directory.create({
name: makeDirRequest.name,
client: user.client
}).save();