Невозможно вставить в столбец "Идентификатор" ошибка при попытке вставить объект, который имеет вложенный родительский объект.
У меня есть 2 объекта с отношением Один ко многим в моей модели Mikro-Orm (v3.6.15) (подключенной к Postgresql - pg v8.3.0):
Уйгулама (родитель)
@Entity({ tableName: "Uygulamalar", collection: "Uygulamalar" })
export class Uygulama {
@PrimaryKey({ fieldName: "Id" })
id!: number;
@Property({ fieldName: "Adi" })
adi!: string;
@Property({ fieldName: "Kod" })
kod!: string;
@Property({ fieldName: "UygulamaSahibi" })
uygulamaSahibi!: string;
@Property({ fieldName: "createdAt" })
createdAt = new Date();
@Property({ fieldName: "updatedAt", onUpdate: () => new Date() })
updatedAt = new Date();
@OneToMany({ entity: () => Modul, mappedBy: "rootUygulama", cascade: [] })
moduller = new Collection<Modul>(this);
}
Модуль (Ребенок)
export class Modul {
@PrimaryKey({ fieldName: "Id" })
id!: number;
@Property({ fieldName: "Adi" })
adi!: string;
@Property({ fieldName: "Kod" })
kod!: string;
@Property({ fieldName: "createdAt" })
createdAt = new Date();
@Property({ fieldName: "updatedAt", onUpdate: () => new Date() })
updatedAt = new Date();
@ManyToOne({ entity: () => Uygulama, joinColumn: "UygulamaId", cascade: [],})
rootUygulama!: Uygulama;
@OneToMany({ entity: () => Ekran, mappedBy: "rootModul", orphanRemoval: true,})
ekranlar = new Collection<Ekran>(this);
}
У меня есть конечная точка отдыха (Expressjs) для создания объекта Modul из опубликованного тела запроса Http:
router.post("/", async (req, res) => {
const modul = DI.modulRepository.create(req.body);
await DI.modulRepository.persistAndFlush(modul);
res.send(modul);
});
Когда я пытаюсь разместить объект JSON ниже, чтобы создать новый модуль (объект rootUygulama уже находится в базе данных):
{
"adi": "Deneme Modülü 3",
"kod": "DM1",
"rootUygulama": {
"id": 66,
"adi": "Deneme Uygulaması",
"kod": "DU",
"uygulamaSahibi": "xxxxxx",
"createdAt": "2020-07-24T21:18:47.874Z",
"updatedAt": "2020-07-24T21:18:47.874Z",
"moduller": [
]
}
}
Я получаю ошибку:
[query] insert into "Uygulamalar" ("Adi", "Id", "Kod", "UygulamaSahibi", "createdAt", "updatedAt") values ('Deneme Uygulaması', 66, 'DU', 'szengin', '2020-07-25 00:18:47.874', '2020-07-25 00:18:47.874') returning "Id" [took 6 ms]
node_modules/mikro-orm/dist/utils/Logger.js:22
[query] rollback
node_modules/mikro-orm/dist/utils/Logger.js:22
(node:14344) UnhandledPromiseRejectionWarning: error: insert into "Uygulamalar" ("Adi", "Id", "Kod", "UygulamaSahibi", "createdAt", "updatedAt") values ($1, $2, $3, $4, $5, $6) returning "Id" - cannot insert into column "Id"
at Parser.parseErrorMessage (d:\NODEJS\BildirimYonetimi\backend\node_modules\pg-protocol\dist\parser.js:278:15)
at Parser.handlePacket (d:\NODEJS\BildirimYonetimi\backend\node_modules\pg-protocol\dist\parser.js:126:29)
at Parser.parse (d:\NODEJS\BildirimYonetimi\backend\node_modules\pg-protocol\dist\parser.js:39:38)
at Socket.<anonymous> (d:\NODEJS\BildirimYonetimi\backend\node_modules\pg-protocol\dist\index.js:8:42)
at Socket.emit (events.js:311:20)
at Socket.EventEmitter.emit (domain.js:482:12)
at addChunk (_stream_readable.js:294:12)
at readableAddChunk (_stream_readable.js:275:11)
at Socket.Readable.push (_stream_readable.js:209:10)
at TCP.onStreamRead (internal/stream_base_commons.js:186:23)
<node_internals>/internal/process/warning.js:32
(node:14344) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
<node_internals>/internal/process/warning.js:32
(node:14344) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Когда я отправляю JSON, как показано ниже, объект создается и успешно вставляется в базу данных
{
"adi": "Deneme Modülü 3",
"kod": "DM1",
"rootUygulama": 66
}
Даже если я установил пустой каскадный массив в репозиторий атрибутов отношений, он пытается вставить родительский объект и терпит неудачу.
Мне что-то не хватает в конфигурации?
Редактировать:
Как определить свойство rootUygulama для моего клиента Typescript?
export interface Modul {
id: number;
adi: string;
kod: string;
createdAt: Date;
updatedAt: Date;
rootUygulama: Uygulama;
ekranlar: Array<Ekran>;
}
Если это будет похоже
rootUygulama: Uygulama | number;
1 ответ
Дело не в каскадировании, поведение правильное. Когда вы передаете только PK, он рассматривается как существующий объект, если вы передаете объект, он считается новым объектом. Дело не в том, установлен ли ПК или нет, если вы хотите такое поведение, вам нужно его запрограммировать самостоятельно.
MikroORM работает на основе отслеживания набора изменений, поэтому только управляемые объекты (сущности, загруженные из базы данных) могут создавать запросы на обновление. Если вы хотите запустить запрос обновления дляrootUygulama
объект, затем используйте em.nativeUpdate()
. Если вы хотите по-прежнему отправлять полезные данные с ним как с объектом, но вас волнует только PK, вы также можете явно объединить этот объект с EM (таким образом он становится управляемым, как если бы вы загрузили его из базы данных).
const modul = DI.modulRepository.create(req.body);
// if we see PK, we merge, so it won't be considered as new object
if (modul.rootUygulama.id) {
DI.em.merge(modul.rootUygulama);
// here we could also fire the `em.nativeUpdate(Uygulama, modul.rootUygulama);`
// to fire an update query, but then you should use `em.transactional()` to have that update query inside the same TX as the flush
}
await DI.modulRepository.persistAndFlush(modul);
res.send(modul);
Кстати, я настоятельно рекомендую не отключать каскадирование, если вы действительно не понимаете, что делаете, поскольку по умолчанию используется каскадное слияние и сохранение, которое вы обычно хотите / нуждаетесь.