TypeORM AfterInsert()无法在另一个表中添加用户ID [英] TypeORM AfterInsert() can't add userId in another table
本文介绍了TypeORM AfterInsert()无法在另一个表中添加用户ID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有一个用户实体:
@Entity()
export class User extends BaseEntity {
@PrimaryGeneratedColumn('uuid')
id: string;
//...
@OneToOne(() => UserActive)
userActive: UserActive;
@AfterInsert()
public async handleAfterInsert() {
const userActive = new UserActive();
userActive.token = randomString();
userActive.user = this;
await getConnection().getRepository(UserActive).save(userActive);
}
}
和UserActive
:
export class UserActive extends BaseEntity {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({
length: 25,
unique: true,
})
token: string;
@OneToOne(() => User)
@JoinColumn()
user: User;
}
我需要将模块token
和用户id
插入到UserActive
中。this
第userActive.user = this;
行是对象user
(当然包括id
)。
当我插入新用户时,TypeORM返回错误:
中不存在密钥(userId)=(438dc281-3f03-45b0-bee8-76aecc894d14) 表用户&q;。
当然,当我更改为:
userActive.user = '438dc281-3f03-45b0-bee8-76aecc894d14'
则一切正常。
我使用的是Next.js
编辑:
我使用:
插入新用户const connection = getConnection().manager;
const user = new User();
user.name = name;
user.email = email;
user.password = await bcrypt.hash(password, 10);
await connection.save(user);
和我将方法handleAfterInsert
更改为:
@Entity()
export class User extends BaseEntity {
@PrimaryGeneratedColumn('uuid')
id: string;
//...
@OneToOne(() => UserActive)
userActive: UserActive;
@AfterInsert()
public async handleAfterInsert() {
const userActive = new UserActive();
userActive.token = randomString();
userActive.user = this;
await getConnection().manager.save(userActive);
}
}
但Nest返回与以前相同的错误。
编辑2:
我发现此问题:Retrieving ID in @AfterInsert operation
我尝试在Insert后将我的方法更改为:
@EventSubscriber()
export class UserSubscriber
implements EntitySubscriberInterface<User> {
listenTo() {
return User;
}
async afterInsert(event: InsertEvent<User>) {
const userActive = new UserActive();
userActive.token = randomString();
userActive.user = event.entity;
await getConnection().getRepository(UserActive).save(userActive);
}
}
但现在没有向表user active
添加任何内容,只向表user
添加了新用户。
推荐答案
我怀疑这是因为SAVE(USER)和SAVE(USERActive)是在不同的数据库事务中完成的,因此在执行SAVE(USERActive)时尚未将用户提交到数据库--即使它已生成ID,但尚未提交--因此SAVE(USERActive)事务看不到新用户,因此您会看到错误&USER"Y表中没有密钥(USERID=xxx)。
您可能能够修复此问题,但请使用entity manager而不是repository。您不能使用存储库,因为它仅限于一个实体,但您在这里处理的是两个实体(用户和用户活动)。将您的2个存储更改为使用相同的实体管理器,如下所示:
保存用户:
const connection: Connection = await createConnection();
const manager = connection.manager;
var user = new User();
user.Name = "John";
// etc
// N.B. Use entity manager, not repository, to save:
await manager.save(user);
并同样保存用户活动记录:
@Entity()
export class User extends BaseEntity {
// ...
@AfterInsert()
public async handleAfterInsert() {
const userActive = new UserActive();
userActive.token = randomString();
userActive.user = this;
// N.B. Use entity manager, not repository, here:
await getConnection().manager.save(userActive);
}
更新答案
我测试了上面的答案,但它确实不起作用-如果我启用typeorm logging,我可以看到有两个单独的交易。
我在与您相同的post中找到了答案:再往下看,您必须启用‘订阅者’连接选项--这一点都不明显。
我是这样做的:在项目的订阅者文件夹中创建‘AfterUser.ts’,并确保该文件夹包含在ormfig.json:
中的订阅者连接选项中{
// ...
"logging": true,
"entities": [ "entity/*.js" ],
"subscribers": [ "subscriber/*.js" ],
// ...
}
我怀疑您更新的解决方案中的问题是此行,因为这会创建一个新事务:
await getConnection().getRepository(UserActive).save(userActive);
您需要使用相同的实体管理器,如下所示:
await event.manager.getRepository(UserActive).save(userActive);
这篇关于TypeORM AfterInsert()无法在另一个表中添加用户ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文