我正在使用TypeORM的存储库模式和一个简单的表,两列,estate_num
作为主键,estateId
与mysql。
如果主键记录不存在,则要插入的repository.save
method is supposed,否则,请对其进行更新。
相反,出现以下错误:
query: SELECT `estate`.`estate_num` AS `estate_estate_num`, `estate`.`estateId` AS `estate_estateId` FROM `estate` `estate` WHERE (`estate`.`estate_num` = ?) -- PARAMETERS: ["0"]
query: START TRANSACTION
query: INSERT INTO `estate`(`estate_num`, `estateId`) VALUES (?, ?) -- PARAMETERS: ["0","caae4e67796e4ac000743f009210fcb0467fdf87d0fbbf6107359cf53f5b544b79eefdfdd78f95d50301f20a9c3212cd3970af22b722e59313813e8c5d2732d0"]
query failed: INSERT INTO `estate`(`estate_num`, `estateId`) VALUES (?, ?) -- PARAMETERS: ["0","caae4e67796e4ac000743f009210fcb0467fdf87d0fbbf6107359cf53f5b544b79eefdfdd78f95d50301f20a9c3212cd3970af22b722e59313813e8c5d2732d0"]
error: { Error: ER_DUP_ENTRY: Duplicate entry '0' for key 'PRIMARY'
我可以手动运行SELECT
,这是我确定要插入还是更新的方式。它会返回与预期的estate_num
相匹配的一行。
为此的实体模型是:
@Entity()
export class Estate {
@PrimaryColumn({
name: 'estate_num',
})
estateNum: number;
@Column({
name: 'estateId',
})
estateId: string;
}
注意:estate_num
不是不是自动递增的,因此将始终提供密钥。我知道这很奇怪。
谢谢!
答案 0 :(得分:1)
我有同样的问题。我做错了。
在我以多种方式执行此操作之前,但是使用了错误的方式。
首先,我是这样做的:
const user = User.create({ id: 1, username: "newName" })
user.save();
给我一个ID Duplicate Entry
的错误
第二,我是这样做的:
const user = User.create({ id: 1, username: "newName" })
User.save(user);
相同错误,重复条目。
第三次我是这样的:
const user = User.findOneOrFaile(1);
const newUser = { ...user, ..req.body }
User.save(newUser);
相同的错误。
我刚刚得到了帮助,应该这样做。您需要获取实例并使用Object.assign()
try {
const user: User = await User.findOneOrFail(id);
Object.assign(user, { ...req.body }); <---- SO ITS LIKE THIS
await user.save();
res.json({
meta: {},
payload: {
...req.body
}
});
} catch (error) {
logger.error(error);
res.status(404).json({
error
});
}
答案 1 :(得分:1)
从日志中很明显,您已将ID作为字符串-- PARAMETERS: ["0"]
进行了传递,但是Estate
实体estateNum
的类型为number
。将ID转换为数字,然后再传递给repository.save
。
答案 2 :(得分:-1)
我整理了以下ts文件以进行测试:
Assembly.GetExecutingAssembly().GetTypes().Select(t => t.Namespace).ToList();
它按预期方式工作(基于以下日志输出):
import 'reflect-metadata';
import { createConnection } from 'typeorm';
import { Estate } from './entity/Estate';
createConnection().then(async connection => {
const estate = new Estate();
estate.estateNum = 0;
estate.estateId = 'alpha';
await connection.getRepository(Estate).save(estate);
estate.estateId = 'beta';
await connection.getRepository(Estate).save(estate);
});
我确实注意到,如果您不等待保存结果,typeorm将尝试两次插入该行(因为第一次保存在第二次开始之前未完成)。
这可能是您的问题吗?
(请注意,在此示例中我使用了sqlite3)。