We have this typeorm entities defined in our NestJS application:
#Entity()
export class Crawler {
#PrimaryColumn({ length: 50 })
id!: string;
...
#ManyToOne(() => CrawlerFamily, (crawlerFamily) => crawlerFamily.id, {
nullable: false,
eager: true,
})
#JoinColumn({ name: 'crawler_family_id' })
crawler_family!: CrawlerFamily;
}
#Entity()
export class CrawlerFamily {
#PrimaryGeneratedColumn()
id?: number;
#Column({ length: 255 })
name!: CrawlerFamilyName;
}
Now, when we try to search for this Crawler entity we need to use findBy instead of findOneBy when we want only one crawler, because when we try to use findOneBy this is the error message we get in response:
{"context":"RpcExceptionsHandler","level":"error","message":"Duplicate column name 'Crawler_crawler_family_id'","stack":["QueryFailedError: Duplicate column name 'Crawler_crawler_family_id'\n at Query.<anonymous> (/home/node/app/node_modules/typeorm/driver/mysql/MysqlQueryRunner.js:158:37)\n at /home/node/app/node_modules/newrelic/lib/shim/shim.js:1313:22\n at LegacyContextManager.runInContext (/home/node/app/node_modules/newrelic/lib/context-manager/legacy-context-manager.js:59:23)\n at DatastoreShim.applySegment (/home/node/app/node_modules/newrelic/lib/shim/shim.js:1303:25)\n at Query.wrappedCallback [as onResult] (/home/node/app/node_modules/newrelic/lib/shim/shim.js:1189:21)\n at Query.execute (/home/node/app/node_modules/mysql2/lib/commands/command.js:36:14)\n at PoolConnection.handlePacket (/home/node/app/node_modules/mysql2/lib/connection.js:456:32)\n at PacketParser.onPacket (/home/node/app/node_modules/mysql2/lib/connection.js:85:12)\n at PacketParser.executeStart (/home/node/app/node_modules/mysql2/lib/packet_parser.js:75:16)\n at TLSSocket.<anonymous> (/home/node/app/node_modules/mysql2/lib/connection.js:360:25)"],"timestamp":"2022-08-17T13:48:23.146Z"}
How to properly setup these entities? I've tried using #Column() decorator to change column name but it's not working.
You're using one to many/many to one wrong, see:
https://orkhan.gitbook.io/typeorm/docs/many-to-one-one-to-many-relations
Here's what you should have:
#Entity()
export class Crawler {
#PrimaryColumn({ length: 50 })
id!: string;
...
#ManyToOne(() => CrawlerFamily, (crawlerFamily) => crawlerFamily.crawler, {
nullable: false,
eager: true,
})
crawler_family!: CrawlerFamily;
}
#Entity()
export class CrawlerFamily {
#PrimaryGeneratedColumn()
id?: number;
#Column({ length: 255 })
name!: CrawlerFamilyName;
#OneToMany(() => Crawler, (crawler) => crawler.crawlerFamily)
crawler!: Crawler[];
}
Related
I wanted to create one to one relation in typeorm (NestJS). Just like in the picture below.
I wanted then to signup user with email and password and create row in custom_auth and user_profile table.
relations
I cant find solution to create that type of relation. I was only able to create typical relation using foreign key (solution in typeorm docs)
export class CustomAuth {
#PrimaryGeneratedColumn()
id: number
#Column({ unique: true })
email: string
#Column()
password: string
#OneToOne(() => UserProfile, (userProfile) => userProfile.customAuth, {
cascade: true,
})
userProfile: UserProfile
}
export class UserProfile {
#PrimaryGeneratedColumn()
userId: number
#Column()
name: string
#Column({ nullable: true })
address: string
#OneToOne(() => CustomAuth, (customAuth) => customAuth.userProfile, {})
#JoinColumn()
customAuth: CustomAuth
}
I am unable to understand relations basically I know the concept of relations but I am unable to us them in my project like m not getting what I want.
I don't know what is wrong here
import { ApiProperty } from '#nestjs/swagger';
import {
Entity,
Column,
PrimaryGeneratedColumn,
OneToOne,
JoinColumn,
} from 'typeorm';
import { Customer } from './Customer.entitye';
import { Sale } from './Sale.entity';
#Entity()
export class Mobile {
#PrimaryGeneratedColumn()
#ApiProperty()
id: number;
#Column()
#ApiProperty()
Mobile_name: string;
#Column()
#ApiProperty()
Mobile_Model: string;
#Column()
#ApiProperty()
Mobile_EMEI: String;
#Column()
#ApiProperty()
Mobile_Price: number;
#Column()
#ApiProperty()
Mobile_Color: string;
#OneToOne(() => Sale)
#JoinColumn()
Profile: Sale;
#OneToOne(() => Customer)
#JoinColumn()
customer: Customer;
}
and the second entity is
import { ApiProperty } from '#nestjs/swagger';
import { Entity, Column, PrimaryGeneratedColumn, OneToOne, JoinColumn } from 'typeorm';
import { Mobile } from './Mobile.entity';
#Entity()
export class Sale{
#PrimaryGeneratedColumn()
id:number
#Column()
#ApiProperty()
Sold_Mobile : String
#OneToOne(() => Mobile, (mobile) => mobile.Mobile_EMEI)
#JoinColumn()
mobile: Mobile
}
why this Mobileid is null
SS of DB
kindly give me the sol or just tell me the best source to learn thi thing
I have a relationship created between User and Groups, where a group can contain multiple users and a user can be present in more than one group. The relationship was built on the UserEntity and GroupsEntity entities. The problem occurs when the request is made in Postman. The User record is created, but the ids corresponding to the relationship between groups and user are not created in the new table (relationship of the two entities).
Help codes:
UserEntitity.ts
import { AssociateEntity } from 'src/associate/entities/associate.entity';
import { Associate } from 'src/associate/interfaces/associate.interface';
import { GroupsEntity } from 'src/groups/entities/group.entity';
import { Groups } from 'src/groups/interfaces/groups.interface';
import { SubsidiaryEntity } from 'src/subsidiary/entities/subsidiary.entity';
import { Subsidiary } from 'src/subsidiary/interfaces/subsidiary.interface';
import {
Column,
DeleteDateColumn,
Entity,
JoinTable,
ManyToMany,
ManyToOne,
OneToMany,
PrimaryGeneratedColumn,
} from 'typeorm';
#Entity()
export class UserEntity {
#PrimaryGeneratedColumn()
id: number;
#Column()
name: string;
#Column()
login: string;
#Column()
password: string;
#Column()
email: string;
#Column()
adm: boolean;
#Column()
passwordValidity: string;
#Column()
initials: string;
#Column()
system: string;
#ManyToOne(() => SubsidiaryEntity, (subsidiary) => subsidiary.id)
subsidiary: Subsidiary;
#ManyToMany(() => GroupsEntity, { cascade: true })
#JoinTable()
group: Groups[];
#Column({ default: true })
status: boolean;
#DeleteDateColumn()
deletedAt: Date;
#OneToMany(() => AssociateEntity, (associate) => associate.id)
associate: Associate[];
}
GroupsEntity.ts
import { UserEntity } from 'src/user/entities/user.entity';
import { User } from 'src/user/interfaces/user.interface';
import {
Column,
DeleteDateColumn,
Entity,
ManyToMany,
PrimaryGeneratedColumn,
} from 'typeorm';
#Entity()
export class GroupsEntity {
#PrimaryGeneratedColumn()
id: number;
#Column()
description: string;
#Column({ default: true })
status: boolean;
#DeleteDateColumn()
deletedAt: Date;
#ManyToMany(() => UserEntity, (user) => user.group)
user: User;
}
user.service.ts (method create)
async create(user: User) {
try {
const groups: Array<Groups> = await this.groupService.findByIds(
user.groups,
);
//#ts-ignore
user.groups = groups;
const newUser = await this.userRepository.save(user);
return newUser;
} catch (error) {
this.logger.error(`error: ${JSON.stringify(error.message)}`);
throw new RpcException(error.code + error.message);
}
}
The structure of the bank is given by:
Bank entity relationships
The code doesn't report errors, but it doesn't create the relationship with the ids either. I'm using microservices in nestJS, the language is TypeScript and the database used is MySQL.
Join table you have define the join Column and inverseJoinColumn Details. Example
#JoinTable({
name: 'cat_use_cloth',
joinColumn: { name: 'cat_id', referencedColumnName: 'id'},
inverseJoinColumn: { name: 'cloth_id', referencedColumnName: 'id'},
})
Ref: https://medium.com/#rodrigo.tornaciole/nest-js-many-to-many-relationship-using-typeorm-and-crud-ec6ed79274f0
I am trying to use a string as the primary key for one of my tables instead of id, but on create Sequelize always tries to set a default id.
import {
Model,
DataType,
Table,
Column,
PrimaryKey,
ForeignKey,
HasOne,
BelongsTo
} from "sequelize-typescript";
import { sequelize } from "../loaders/database";
import { Enterprise } from "./enterprise";
import { Welfare } from "./welfare";
import { Meal } from "./meal";
import { Qualification } from "./qualification";
#Table
export class Recruit extends Model {
#PrimaryKey
#Column({
type: DataType.STRING(30),
field: "recruit_id"
})
recruitId!: string;
#Column(DataType.CHAR(10))
reception!: string;
#Column(DataType.CHAR(10))
deadline!: string;
#Column({
type: DataType.TINYINT,
field: 'recruit_plan'
})
recruitPlan!: boolean;
#Column({
type: DataType.CHAR(5),
field: 'start_time'
})
startTime!: string;
#Column({
type: DataType.CHAR(5),
field: 'end_time'
})
endTime!: string;
#Column(DataType.INTEGER)
salary!: number;
#Column(DataType.INTEGER)
period!: number;
#Column({
type: DataType.TINYINT,
defaultValue: false
})
expired!: boolean;
#Column(DataType.INTEGER)
personnel!: number;
#Column(DataType.STRING)
detail!: string;
#Column({
type: DataType.TINYINT,
defaultValue: false
})
writing!: boolean;
#Column({
type: DataType.INTEGER,
allowNull: false,
defaultValue: 1
})
page!: number;
#ForeignKey(() => Enterprise)
#Column({
type: DataType.CHAR(12),
allowNull: false,
field: 'ent_no'
})
entNo!: string;
#HasOne(() => Welfare, "recruit_id")
welfare!: Welfare;
#HasOne(() => Meal, "recruit_id")
meal!: Meal;
#HasOne(() => Qualification, "recruit_id")
qualification!: Qualification;
#BelongsTo(() => Enterprise, "ent_no")
enterprise!: Enterprise;
}
Recruit.init({}, {
sequelize,
tableName: "recruit",
modelName: "recruit"
});
After initalizing the project, I defined Recruit Model with sequelize-typescript.
public async getRecruitInfoById(recruitId: string) {
return await Recruit.findOne({
attributes: [
'ent_no',
'deadline',
['detail', 'workContent'],
'salary',
'period',
'start_time',
'end_time',
'personnel',
'reception'
],
where: {
recruitId
},
include: [
{
model: Enterprise,
required: true,
attributes: ['name', 'phone']
}
]
});
And, execute this function.
I expect the record to get info.
But, Sequelize tries to set primary key a default id, which isn't present in the table.
2021-03-06 13:23:51 error: undefined: Unknown column 'recruit.id' in 'field list'
at new BelongsTo (C:\Users\user\Desktop\프로젝트\jobITs\jobITs_v2_Backend_Red\node_modules\sequelize\lib\associations\belongs-to.js:59:13)
at Function.<anonymous> (C:\Users\user\Desktop\프로젝트\jobITs\jobITs_v2_Backend_Red\node_modules\sequelize\lib\associations\mixin.js:105:25)
at Function.Model.<computed> [as belongsTo] (C:\Users\user\Desktop\프로젝트\jobITs\jobITs_v2_Backend_Red\node_modules\sequelize-typescript\dist\model\model\model.js:118:28)
at Object.<anonymous> (C:\Users\user\Desktop\프로젝트\jobITs\jobITs_v2_Backend_Red\src\entities\index.ts:54:9)
at Module._compile (internal/modules/cjs/loader.js:1137:30)
at Module.m._compile (C:\Users\user\Desktop\프로젝트\jobITs\jobITs_v2_Backend_Red\node_modules\ts-node\src\index.ts:1056:23)
at Module._extensions..js (internal/modules/cjs/loader.js:1157:10)
at Object.require.extensions.<computed> [as .ts] (C:\Users\user\Desktop\프로젝트\jobITs\jobITs_v2_Backend_Red\node_modules\ts-node\src\index.ts:1059:12)
at Module.load (internal/modules/cjs/loader.js:985:32)
at Function.Module._load (internal/modules/cjs/loader.js:878:14)
In this case, the store can have many owners, and the owners can have many store.
However, when i save the entity by using Repository and the problem happen:
Maximum call stack size exceeded
I think it need to use Nested Tree annotation? But i dont know how to correct it. Please help!
#Entity('store')
export class StoreEntity {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column()
name: string;
...
#ManyToMany(type => UserEntity, user => user.ownStores)
#JoinTable()
owners: UserEntity[];
}
#Entity('user')
export class UserEntity {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column({
type: 'varchar',
})
email: string;
...
#ManyToMany(type => StoreEntity, store => store.owners)
ownStores: StoreEntity[];