Reputation: 71
I have a Database Schema that includes 3 Tables - Users, Clients and Sellers. The users table is a common table for both Clients & Sellers. I Would like to Map a OneToOne Relation on TypeORM where the FK of Clients and Sellers is the own primary key. So their ids should be the same id of the corresponding User id.
Something equivalents to @MapsId on JAVA JPA Hibernate.
Upvotes: 7
Views: 30871
Reputation: 149
@Edward thanks for your contriubution..
I Resolved that!!
TypeOrm has a property on the OneToOne annotation, called primary, and if we set it to true, it will map the relation throught the primary key, exactly we get on use @MapsId on JPA Hibernate.
Ex (On Seller or Clients class):
@OneToOne(() => Usuario, { primary: true, cascade: true })
@JoinColumn({ name: 'OPD_id' })
usuario: Usuario;
Its enough to create a generalization relation between classes (e.g User/Seller), joined by their id keys.
Upvotes: 14
Reputation: 8596
Something like @MapsId on JPA Hibernate does not exist in TypeOrm. Hibernate is a much more mature ORM.
In TypeOrm you can achieve the same result as follows:
Use @PrimaryColumn instead of @PrimaryGeneratedColumn on the related tables (sellers & clients in your case)
After @PrimaryColumn add @OneToOne relation to the main table (users in your case), and on @JoinColumn make the column name the same as the @PrimaryColumn name. This will give you a single column for the Primary Key and the Foreign Key relation
Add @BeforeInsert in each of the related table to copy the id from the main table (users) to the primary/foreign key of the other table (sellers & clients)
Use { "cascade": true } on the @OneToOne, so you only need to save the related table, the main table will be saved automatically first within the same transaction, then @BeforeInsert will copy the new key to the related table, then the related table will be saved
import { Entity, PrimaryGeneratedColumn, Column,
OneToOne, JoinColumn, PrimaryColumn, BeforeInsert } from "typeorm";
@Entity()
export class users {
@PrimaryGeneratedColumn()
id: number;
@Column()
username: string;
}
@Entity()
export class clients {
@PrimaryColumn()
clientid: number;
@OneToOne(() => users, { "cascade": true })
@JoinColumn({ name: "clientid" } ) // This matches @PrimaryColumn name
user: users;
@BeforeInsert()
newid() { this.clientid = this.user.id; }
@Column()
clientname: string;
}
@Entity()
export class sellers {
@PrimaryColumn()
sellerid: number;
@OneToOne(() => users, { "cascade": true })
@JoinColumn({ name: "sellerid" } ) // This matches @PrimaryColumn name
user: users;
@BeforeInsert()
newid() { this.sellerid = this.user.id; }
@Column()
sellername: string;
}
Main code, to save User + Seller:
const connection = await createConnection();
const entityManager = connection.createEntityManager();
const user = new users();
const seller = new sellers();
seller.user = user;
user.username = "Giordano User";
seller.sellername = 'Giordano Seller';
await entityManager.save(seller); // "user" saves automatically because of "cascade"
Upvotes: 2