当试图使用TypeORM (在NestJ中)将带有默认值的主列的实体保存到DB时,我遇到了问题。
TL;博士--在default
似乎什么都不做的情况下,如何用TypeORM设置默认列值?
编辑1:好的,所以default
似乎是DB级的,以前有点漏掉了,但是@BeforeInsert()
仍然应该做到这一点(但没有)。
编辑2:很明显,@BeforeInsert()
钩子起作用,但只有在使用.save(new UserSession(userId))
而不是.save({ userId: userId })
调用.save()
(当然需要在UserSession
中使用适当的构造函数)时才能工作。
设置
我有一个实体UserSession
,注意sessionId
字段,它应该有一个默认值,不管cryptoRandomString({ length: 128, type: 'alphanumeric' })
返回什么。
@Entity('user_session')
export class UserSession {
@PrimaryColumn({
name: 'session_id',
default: () => cryptoRandomString({ length: 128, type: 'alphanumeric' })
})
sessionId: string
@Column({
name: 'user_id',
})
userId: string
}
然后,我使用TypeORM存储库.save()
函数将对象写入数据库,如下所示:
@Injectable()
export class AuthService {
constructor(
@InjectRepository(UserSession)
private readonly userSessionRepository: Repository<UserSession>
) {}
async createNewSession(userId: string): Promise<void> {
// Create new session
const session = await this.userSessionRepository.save({
userId: userId
})
// If only it got that far...
}
}
误差
此时,如果没有“手动”设置,我希望TypeORM可以为sessionId
设置一个默认值。但是,它只抛出一个错误:
[Nest] 23088 - 04/06/2021, 23:18:44 [ExceptionsHandler] ER_NO_DEFAULT_FOR_FIELD: Field 'session_id' doesn't have a default value +4032ms
QueryFailedError: ER_NO_DEFAULT_FOR_FIELD: Field 'session_id' doesn't have a default value
at new QueryFailedError (E:\SAC\projects\api-flexrent\node_modules\typeorm\error\QueryFailedError.js:12:28)
at Query.<anonymous> (E:\SAC\projects\api-flexrent\node_modules\typeorm\driver\mysql\MysqlQueryRunner.js:217:45)
at Query.<anonymous> (E:\SAC\projects\api-flexrent\node_modules\mysql\lib\Connection.js:526:10)
at Query._callback (E:\SAC\projects\api-flexrent\node_modules\mysql\lib\Connection.js:488:16)
at Query.Sequence.end (E:\SAC\projects\api-flexrent\node_modules\mysql\lib\protocol\sequences\Sequence.js:83:24)
at Query.ErrorPacket (E:\SAC\projects\api-flexrent\node_modules\mysql\lib\protocol\sequences\Query.js:92:8)
at Protocol._parsePacket (E:\SAC\projects\api-flexrent\node_modules\mysql\lib\protocol\Protocol.js:291:23)
at Parser._parsePacket (E:\SAC\projects\api-flexrent\node_modules\mysql\lib\protocol\Parser.js:433:10)
at Parser.write (E:\SAC\projects\api-flexrent\node_modules\mysql\lib\protocol\Parser.js:43:10)
at Protocol.write (E:\SAC\projects\api-flexrent\node_modules\mysql\lib\protocol\Protocol.js:38:16)
绝望
在花了一段时间在好的旧谷歌上之后,我尝试了几种不同的版本,它们都不起作用(并且抛出了相同的错误):
@PrimaryColumn({
name: 'session_id',
default: cryptoRandomString({ length: 128, type: 'alphanumeric' })
})
sessionId: string
或
@PrimaryColumn({
name: 'session_id',
default: () => 'cryptoRandomString({ length: 128, type: "alphanumeric" })' // Why would that even work
})
sessionId: string
或
@PrimaryColumn({
name: 'session_id',
default: 'cryptoRandomString({ length: 128, type: "alphanumeric" })' // Why would that even work
})
sessionId: string
或
@PrimaryColumn({
name: 'session_id',
default: 'please work'
})
sessionId: string
或者不是在@PrimaryColumn()
中设置@BeforeInsert()
,而是使用@BeforeInsert()
,这显然不是在使用.save()
时调用的
@BeforeInsert()
beforeInsertAction(): void {
this.sessionId = cryptoRandomString({ length: 128, type: 'alphanumeric' })
}
唯一起作用的是为UserSession
类使用构造函数并在其中设置sessionId
(我认为这有点违背了TypeORM中default
值的目的?):
constructor(
userId: string
) {
this.userId = userId
this.sessionId = cryptoRandomString({ length: 128, type: 'alphanumeric' })
}
把它称为
const session = await this.userSessionRepository.save(new UserSession(userId))
我错过什么了吗?一开始,我是不是完全搞错了?我再也不知道了。
发布于 2022-02-18 22:02:31
我最终找到了解决问题的方法.
我现在像这样定义我的实体类:
@Entity('user')
export class User {
@PrimaryColumn({
name: 'user_id',
type: 'varchar',
length: 32
})
userId: string = cryptoRandomString({ length: 32, type: 'alphanumeric' })
@Column({
name: 'session_id',
type: 'varchar',
length: 128
})
sessionId: string = cryptoRandomString({ length: 128, type: 'alphanumeric' })
@Column({
name: 'email',
type: 'varchar',
length: 128
})
email: string
}
现在我可以使用存储库的.create()
创建新的用户实体了
const user: User = this.userRepo.create({ email: 'hello.world@example.com' })
它创建以下对象:
user: {
userId: 'ivWW8oMGD8oMh2FL0vM3Grrh2FL0M3Di'
sessionId: 'vM3DiW8oMGrh2FL0vM3DiW8oMGrh2FL0vM3DiW8oMGrh2FL0vM3DiW8oMGrh2FL0...'
email: 'hello.world@example.com'
}
然后,可以使用.save()
方法再次保存以下内容:
await this.userRepo.save(user)
https://stackoverflow.com/questions/67844341
复制相似问题