Tengo un esquema de base de datos que incluye 3 tablas: usuarios, clientes y vendedores. La tabla de usuarios es una tabla común para Clientes y Vendedores. Me gustaría mapear una relación OneToOne en TypeORM donde el FK de Clientes y Vendedores es la clave principal propia. Por lo tanto, sus identificaciones deben ser las mismas identificaciones de la identificación de usuario correspondiente.
Algo equivalente a @MapsId en JAVA JPA Hibernate.
@Edward gracias por tu contribución..
¡¡Resolví eso!!
TypeOrm tiene una propiedad en la anotación OneToOne, llamada principal, y si la establecemos en verdadero, mapeará la relación a través de la clave principal, exactamente como usamos @MapsId en JPA Hibernate.
Ej. (En la clase Vendedor o Clientes):
@OneToOne(() => Usuario, { primary: true, cascade: true }) @JoinColumn({ name: 'OPD_id' }) usuario: Usuario;Es suficiente para crear una relación de generalización entre clases (por ejemplo, Usuario/Vendedor), unidas por sus claves de identificación.
Algo como @MapsId en JPA Hibernate no existe en TypeOrm. Hibernate es un ORM mucho más maduro.
En TypeOrm puede lograr el mismo resultado de la siguiente manera:
Use @PrimaryColumn en lugar de @PrimaryGeneratedColumn en las tablas relacionadas (vendedores y clientes en su caso)
Después de @PrimaryColumn, agregue la relación @OneToOne a la tabla principal (usuarios en su caso), y en @JoinColumn haga que el nombre de la columna sea el mismo que el nombre de @PrimaryColumn. Esto le dará una sola columna para la clave principal y la relación de clave externa
Agregue @BeforeInsert en cada una de las tablas relacionadas para copiar la identificación de la tabla principal (usuarios) a la clave principal/foránea de la otra tabla (vendedores y clientes)
Use { "cascade": true } en @OneToOne, por lo que solo necesita guardar la tabla relacionada, la tabla principal se guardará automáticamente primero dentro de la misma transacción, luego @BeforeInsert copiará la nueva clave a la tabla relacionada, luego la tabla relacionada se guardará
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; }Código principal, para guardar Usuario + Vendedor:
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"