QueryFailedError: вставка или обновление таблицы "graph" нарушает ограничение внешнего ключа "FK_0e40 ......" - PullRequest
8 голосов
/ 17 марта 2020

Я создал очень маленький репозиторий .

Пожалуйста, посмотрите на мое возможное исправление ниже.


У меня есть граф и сущность узла графа. Граф знает только о своем узле начального графа, а сам узел знает о том, к какому графу он принадлежит и как о его преемнике.

@Entity()
export class Graph extends BaseEntity {
  @PrimaryGeneratedColumn("uuid")
  public id: string;

  @Column({ nullable: true })
  public startNodeId?: string;

  @ManyToOne(() => GraphNode)
  @JoinColumn({ name: "startNodeId" })
  public startNode?: GraphNode;
}

@Entity()
export class GraphNode extends BaseEntity {
  @PrimaryGeneratedColumn("uuid")
  public id: string;

  @PrimaryColumn("uuid")
  public graphId: string;

  @ManyToOne(() => Graph, { onDelete: "CASCADE" })
  @JoinColumn({ name: "graphId" })
  public graph: Graph;

  @Column({ nullable: true })
  public successorGraphNodeId?: string;

  @ManyToOne(() => GraphNode)
  @JoinColumn({ name: "successorGraphNodeId" })
  public successorGraphNode?: GraphNode;
}

Как видите, начальный узел графа может быть нулевым. Кроме того, узел графа может не иметь преемника, поэтому это поле также может быть нулевым. Важно, чтобы узел графа имел составной первичный ключ, потому что он всегда принадлежит одному графу.

Я создал несколько очень базовых действий хранилища CRUD для создания графа и узла графа. Позже я хочу обновить идентификатор начального узла этого графа.

Хранилище узлов графа просто создает новую сущность

  public createGraphNode(graphId: string, successorGraphNodeId?: string): Promise<GraphNode> {
    const graphNode: GraphNode = new GraphNode();
    graphNode.graphId = graphId;
    graphNode.successorGraphNodeId = successorGraphNodeId;
    return graphNode.save();
  }

Хранилище графиков создает новую сущность и может обновлять его начальный идентификатор узла

  public createGraph(startNodeId?: string): Promise<Graph> {
    const graph: Graph = new Graph();
    graph.startNodeId = startNodeId;
    return graph.save();
  }

  public updateStartNodeId(graphId: string, startNodeId: string): Promise<UpdateResult> {
    return this.update(graphId, {
      startNodeId
    });
  }

При запуске приложения я создаю новый график. После этого я создаю новый узел графа и назначаю ему идентификатор графа. Этот узел графа не имеет преемника. Наконец, я назначаю узел графа как начальный узел графа.

const graph: Graph = await graphsRepository.createGraph();
const graphNode: GraphNode = await graphNodesRepository.createGraphNode(graph.id);
await graphsRepository.updateStartNodeId(graph.id, graphNode.id);

При этом я получаю следующую ошибку базы данных

QueryFailedError: вставка или обновление в таблицу "graph "нарушает ограничение внешнего ключа" FK_0e4022833a9efc062c01637e552 "

Кажется, моя сущность неверна. Кто-нибудь знает, как это исправить?

Заранее спасибо


Возможно, у меня есть исправление для этого

Графическая сущность

Создание ссылки на ПК с помощью referencedColumnName: "id"

@ManyToOne(() => GraphNode)
@JoinColumn({ name: "startNodeId", referencedColumnName: "id" })
public startNode?: GraphNode;

Сущность узла графа

Сделайте то же самое для узла-преемника графа

@ManyToOne(() => GraphNode)
@JoinColumn({ name: "successorGraphNodeId", referencedColumnName: "id" })
public successorGraphNode?: GraphNode;

Также добавьте декоратор Unique к сущности и пометьте поле id как уникальное

@Unique(["id"])

Единственная проблема, с которой я столкнулся, заключается в том, что я не знаю, почему мне нужно ее решить таким образом.

  • Я не знаю, почему я должен ссылаться на PK таблицы ссылок через referencedColumnName: "id", это должно быть очевидно
  • Я также не знаю почему Я должен пометить столбец идентификатора как уникальный через @Unique(["id"]), потому что это поле всегда будет уникальным
...