Search code examples
typescripttypeorm

TypeORM: One-To-One relation doesn't create foreign key for subtable


I have two entities

Users:

@Entity()
export class Users {
  @PrimaryGeneratedColumn()
  user_id: number;

  @OneToOne(_ => UserContacts, contact => contact.user_id)
  @JoinColumn({ name: 'contact_id' })
  contacts: UserContacts
}
@Entity()
export class UserContacts {
  @PrimaryGeneratedColumn()
  contact_id: number;

  @OneToOne(_ => Users, users => users.contacts)
  user_id: Users;
}

But in PostgreSQL after saving I have:

user_contacts table:

 contact_id | user_id
------------+---------
          6 |

users table:

 user_id | contact_id
---------+------------
       7 |          6

I suppose in user_contacts table in user_id column should be 7

I just learn TypeORM so I don't create any architecture

I have two functions for creating contacts and users

My save flow:

export function createUser(contacts?: UserContacts): Users {
  const user = new Users();
  user.firstName = faker.name.firstName();
  user.lastName = faker.name.lastName();
  user.age = faker.datatype.number({ min: 1, max: 99 });

  if (contacts) { user.contacts = contacts }

  return user
}

export function createContacts(): UserContacts {
  const contact = new UserContacts()
  contact.email = faker.internet.email();
  contact.phone = faker.phone.phoneNumber('##########');
  contact.address = faker.address.city();

  return contact;
}

async function bootstrap() {
  try {
    const connection = await createConnection();
    const userRepository = connection.getRepository(Users);
    const contactRepository = connection.getRepository(UserContacts);

    const contacts = createContacts();
    const user = createUser(contacts);

    contactRepository.save(contacts);
    userRepository.save(user);

    console.info('Done!');

  } catch (e) {
    console.error(e.message);
  }
}

bootstrap();

What did I do wrong?


Solution

  • OneToOne decorator without JoinColumn used by TypeORM as metadata for bi-directional relationship

    @Entity()
    export class UserContacts {
      @PrimaryGeneratedColumn()
      contact_id: number;
    
      // This property is metadata. It's not column for DB
      @OneToOne(_ => Users, users => users.contacts)
      user: Users;
    }