【问题标题】:TypeORM save incorrectly attempts to insert instead of updateTypeORM 保存错误地尝试插入而不是更新
【发布时间】:2021-03-17 21:54:51
【问题描述】:

我对 TypeORM 有一个奇怪的问题。对于这个实体:

@Entity({name:"registered_items"})
export class RegisteredItem {

    @PrimaryColumn({name: 'itemid', type: 'bigint'})
    itemId?: number;

    @Column({name: 'somestring', length: 15, nullable: true})
    someString?: string;

    //.. more strings

    @Column({name: 'registertimestamp', nullable: true})
    registerTimestamp?: Date;    

    @Column({name: 'isenabled'})
    isEnabled?: boolean;
    
    //..more booleans
}

TypeORM 未能检测到该行已存在与该 itemId 并尝试执行插入而不是更新,

而有了这个更简单的实体:

@Entity({name:"something_simple"})
export class SomethingSimple {

    @PrimaryColumn({name: 'thingid', length: 32})
    thingId?: string;

    @Column({name: 'something', nullable: true, type: "smallint"})
    something?: number;

    @CreateDateColumn({name: 'inserttimestamp'})
    inserttimestamp?: Date;
}

它按预期工作,在项目不存在时执行插入,并在项目存在时更新。为什么它无法与第一个实体一起发挥预期作用? 两种情况下的代码是等价的:

getRepository(RegisteredItem).save(item)
//and:
getRepository(SomethingSimple).save(s)

我可以在调试日志中看到它在确定要采取的操作之前正确执行了 SELECT,但没有从 SELECT 结果中得出正确的结论。 当我手动执行此操作时(而不是 getRepository(..).save().. ):

const exists = await getRepository(RegisteredItem).hasId(item);
if(exists) {
    return getRepository(RegisteredItem).update({itemId: item.itemId}, item);
}
else {
    return getRepository(RegisteredItem).insert(item);
}

选择了正确的分支。

当尝试使用await getRepository(RegisteredItem).findOne({itemId: <something>}) 预加载实体并尝试保存该实体时,由于主键违规,该操作也会失败。

那么为什么 getRepository.save() 对一个实体不起作用?使用的数据库是 PostgreSQL。

【问题讨论】:

    标签: typeorm


    【解决方案1】:

    我遇到了同样的问题,直到我做了 findone 然后 .save, 首先使用 data= this.userRepository.findOne(id) 获取要更新的数据,然后您可以将 userRepository.save(data) 应用于此数据。 这是我的源代码尝试做同样的事情:

    const userUpdated = await this.userRepository.findOne(id)
          let dataUpdated = {
            ...userUpdated,
            username: data.payload.username,
            firstname: data.payload.firstname,
            lastname: data.payload.lastname,
            email: data.payload.email,
            company: data.payload.selectedCompany,
            roles: data.payload.selectedRoles
          }
    
          const user = await this.userRepository.save(dataUpdated);
    

    【讨论】:

    • 我尝试了这种方法,但由于某种奇怪的原因它对我不起作用。
    • 请告诉我您是否与多对多合作?只是一个简单的杂物,所以我可以与您分享我在这两种情况下所做的事情,因为我遇到了这个问题,但现在我解决了它
    • 在这种情况下,实体之间根本没有关系。
    • 试试这个:await this.roleRepository.update(id, { ...data.payload });常量角色 = 等待 this.roleRepository.find({ id });返回{角色,成功:真,};
    • 那应该是什么结果?如果是这样,那么我不妨明确地进行存在检查。我担心的是为什么 TypeORM 执行的隐式 SELECT 无法检测到一种实体的存在,但对另一种实体却成功了。
    猜你喜欢
    • 2019-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-21
    • 1970-01-01
    • 2018-01-29
    • 1970-01-01
    相关资源
    最近更新 更多