TypeORM M2O O2M Relationship Внешний ключ имеет значение NULL при использовании каскада для вставки

В настоящее время я пытаюсь создать отношения Many To One и One to Many, используя TypeORM без Typescript.

У меня настроены следующие объекты:

./entity/proposal

module.exports = {
    name: "Proposal",
    columns: {
        id: {
            primary: true,
            type: "int",
            generated: true
        },
        name: {
            type: "varchar",
            length: 60
        },
        description: {
            type: "varchar",
            default: "",
            length: 150
        },
        createdAt: {
            createDate: true
        },
        updatedAt: {
            updateDate: true
        }
    },
    relations: {
        sections: {
            target: "Section",
            type: "one-to-many",
            treeParent: true,
            cascade: true,
            inverseSide: 'Proposal'
        }
    }
}

./entity/section

module.exports = {
    name: "Section",
    columns: {
        id: {
            primary: true,
            type: "int",
            generated: true
        },
        name: {
            type: "varchar",
            length: 60,
            default: "New Section"
        },
        order: {
            type: "int"
        }
    },
    relations: {
      proposal: {
          target: "Proposal",
          type: "many-to-one",
          joinColumn: true,
          nullable: false
      }
  }
}

Отсюда я создал две функции: одну для вставки предложения и другую функцию, которую я использую для создания фиктивных данных, которые используют каскадную функцию для вставки строк (как в этом примере: https://github.com/typeorm/javascript-example)

./controller/createProposal.js

const getRepository = require('typeorm').getRepository

const createProposal = async proposal => {

    let proposalRepository = getRepository("Proposal");
    let result = await proposalRepository.save(proposal)
            .then( savedProposal  => {
                return savedProposal
            })
            .catch( err => {
                return {
                    message: "There was an issue saving the proposal",
                    err: err
                }
            });

    return result

}

module.exports = createProposal

./controller/mockData.js

const createProposal = require('../proposal/createProposal')

const insertMockData = async () => {

  let section1 = {
    name: "Letter",
    order: 1
  }

  let section2 = {
    name: "Cloud",
    order: 2
  }

  let proposal = {
    name: "Cloud Proposal",
    description: "Cloud Proposal",
    sections: [
      section1, section2
    ] 
  }

  let result = await createProposal(proposal)

}

module.exports = insertMockData

Использование функции insertMockData() с nullable: true приводит к следующему:

=== Proposal Table ===
id  name                 description
1   "Cloud Proposal"     "Cloud Proposal"
=== Section Table ===
id  name        order     proposalid
1   "Letter"    1         null
2   "Cloud"     2         null

Мне нужно, чтобы proposalid присутствовал внутри таблицы разделов, чтобы я мог с нетерпением найти его с помощью proposalRepository.findOneOrFail({ id , relations: ['sections'] }).

Что я делаю неправильно?

Если вы также можете поделиться функцией createProposal, это будет здорово. В настоящее время мы не видим, насколько актуально создание объекта proposal.

David Weinberg 21.02.2019 17:21

@DavidWeinberg Привет, Дэвид, пожалуйста, посмотрите второй снизу блок кода :)

Chris Talke 21.02.2019 21:05
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
2
4 023
2

Ответы 2

Попробуй добавить eager: true в Section->proposal

relations: {
    proposal: {
        target: "Proposal",
        type: "many-to-one",
        joinColumn: true,
        nullable: false,
        eager: true // This line
    }
}

что означает eager: true?

Asking 31.01.2021 10:33

Надеюсь, это может быть кому-то полезно. Недавно у меня возникли те же проблемы с отношениями one-to-many и many-to-one с использованием TypeORM с NodeJS (версия 0.2.18).

Это рабочие объекты с рабочими отношениями:

const { EntitySchema } = require('typeorm')

const FirstEntity = require('../model/FirstEntity')

module.exports = new EntitySchema({
  name: 'FirstEntity',
  target: FirstEntity,
  columns: {
    id: {
      primary: true,
      type: 'bigint',
      generated: true,
    },
    createdAt: {
      type: 'timestamp with time zone',
      default: () => 'NOW()',
    },
    updatedAt: {
      type: 'timestamp with time zone',
      default: () => 'NOW()',
    },
    ...........
  },
  relations: {
    secondentities: {
      target: 'SecondEntity',
      type: 'one-to-many',
      cascade: true,
      inverseSide: 'firstEntity',
      eager: true,
      nullable: false,
    },
  },
})

const { EntitySchema } = require('typeorm')

const SecondEntity = require('../model/SecondEntity')

module.exports = new EntitySchema({
  name: 'SecondEntity',
  target: SecondEntity,
  columns: {
    id: {
      primary: true,
      type: 'bigint',
      generated: true,
    },
    createdAt: {
      type: 'timestamp with time zone',
      default: () => 'NOW()',
    },
    updatedAt: {
      type: 'timestamp with time zone',
      default: () => 'NOW()',
    },
    ...........
  },
  relations: {
    firstEntity: {
      target: 'FirstEntity',
      type: 'many-to-one',
      inverseSide: 'secondentities',
      nullable: false,
    },
  },
})

Моя самая первая проблема заключалась в том, что .save() из firstEntity вообще не сохранял вложенный secondentities. Это было решено свойством cascade.

Моя вторая проблема после добавления cascade заключалась в том, что сохраненный firstEntityid отсутствовал в secondentities, сохраненном в базе данных. Решилось добавлением свойства inverseSide.

Обратите внимание, что свойства nullable вообще не работали, поэтому после .save() мне пришлось вручную .findOneOrFail сохраненный firstEntity и проверить наличие secondentities.

Другие вопросы по теме