typeorm / typeorm

ORM for TypeScript and JavaScript. Supports MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, SAP Hana, WebSQL databases. Works in NodeJS, Browser, Ionic, Cordova and Electron platforms.
http://typeorm.io
MIT License
34.19k stars 6.3k forks source link

OneToOne - ER_BAD_FIELD_ERROR: Unknown column in 'field list' on related entity #6256

Closed ZakRabe closed 4 years ago

ZakRabe commented 4 years ago

Issue type:

[x] question [ ] bug report [ ] feature request [ ] documentation issue

Database system/driver:

[ ] cordova [ ] mongodb [x] mssql [ ] mysql / mariadb [ ] oracle [ ] postgres [ ] cockroachdb [ ] sqlite [ ] sqljs [ ] react-native [ ] expo

TypeORM version:

[x] latest [ ] @next [ ] 0.x.x (or put your version here)

Steps to reproduce or a small repository showing the problem:

I have two models, with a OneToOne relationship. I have many other relationships in my code similar to this, even other relationships on this model, and they all seem to work fine, except this one. which makes me think I must be missing something small.

The models are Lobby and Game. A Game can be associated to a Lobby, but Game is nullable.

When I do a find query for an array of Lobbies, I get the error:

QueryFailedError: ER_BAD_FIELD_ERROR: Unknown column 'Lobby_game.color1' in 'field list'
    at new QueryFailedError (E:\sites\gtoons\server\src\error\QueryFailedError.ts:9:9)
    at Query.<anonymous> (E:\sites\gtoons\server\src\driver\mysql\MysqlQueryRunner.ts:167:37)
    at Query.<anonymous> (E:\sites\gtoons\server\node_modules\mysql\lib\Connection.js:526:10)
    at Query._callback (E:\sites\gtoons\server\node_modules\mysql\lib\Connection.js:488:16)
    at Query.Sequence.end (E:\sites\gtoons\server\node_modules\mysql\lib\protocol\sequences\Sequence.js:83:24)
    at Query.ErrorPacket (E:\sites\gtoons\server\node_modules\mysql\lib\protocol\sequences\Query.js:92:8)
    at Protocol._parsePacket (E:\sites\gtoons\server\node_modules\mysql\lib\protocol\Protocol.js:291:23)
    at Parser._parsePacket (E:\sites\gtoons\server\node_modules\mysql\lib\protocol\Parser.js:433:10)
    at Parser.write (E:\sites\gtoons\server\node_modules\mysql\lib\protocol\Parser.js:43:10)
    at Protocol.write (E:\sites\gtoons\server\node_modules\mysql\lib\protocol\Protocol.js:38:16)

If anyone could maybe point me in the right direction, I would greatly appreciate it.

controller code that does the query:

  async getOpenLobbies() {
    const openLobbies = await this.lobbyRepository.find({
      connectedCount: MoreThan(0),
    });
    this.socket.emit(
      'lobbyList',
      openLobbies.map((lobby) => lobby.toJson())
    );
  }

Lobby Entity

import {
  BaseEntity,
  Column,
  Entity,
  JoinColumn,
  ManyToOne,
  OneToOne,
  PrimaryGeneratedColumn,
} from 'typeorm';
import Deck from './Deck';
import Game from './Game';
import User from './User';

@Entity()
export default class Lobby extends BaseEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @Column()
  created: string;

  // for some reason eager here causes crashes in the find query?
  @OneToOne((type) => Game, { eager: true, nullable: true })
  @JoinColumn()
  game: Game | null;

  @Column()
  capacity: number;

  @Column()
  connectedCount: number;

  @OneToOne((type) => User, { eager: true })
  @JoinColumn()
  owner: User;

  @OneToOne((type) => User, { eager: true })
  @JoinColumn()
  seat1: User | null;

  @OneToOne((type) => User, { eager: true })
  @JoinColumn()
  seat2: User | null;

  @Column()
  seat1Ready: number;

  @Column()
  seat2Ready: number;
  @ManyToOne((type) => Deck, { eager: true })
  @JoinColumn()
  seat1Deck: Deck | null;

  @ManyToOne((type) => Deck, { eager: true })
  @JoinColumn()
  seat2Deck: Deck | null;

  @Column()
  seatRule: number;

  // TODO. how much do we care about security here?
  @Column()
  password: string;

  toJson = () => {
    const {
      id,
      name,
      created,
      game,
      capacity,
      owner,
      connectedCount,
      seat1,
      seat2,
      seatRule,
      seat1Ready,
      seat2Ready,
      seat1Deck,
      seat2Deck,
    } = this;

    console.log(game);

    return {
      id,
      name,
      created,
      capacity,
      connectedCount,
      seatRule,
      owner: owner.toJson(),
      game: game && game.toJson(),
      seat1: seat1 && seat1.toJson(),
      seat2: seat2 && seat2.toJson(),
      seat1Ready: !!seat1Ready,
      seat2Ready: !!seat2Ready,
      seat1Deck: seat1Deck && seat1Deck.toJson(),
      seat2Deck: seat2Deck && seat2Deck.toJson(),
    };
  };
}

Game Entity

import {
  BaseEntity,
  Column,
  Entity,
  JoinColumn,
  OneToOne,
  PrimaryGeneratedColumn,
} from 'typeorm';
import { roll } from '../../util';
import Card from './Card';
import Deck from './Deck';
import User from './User';

@Entity({ name: 'gamestate' })
export default class Game extends BaseEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @OneToOne((type) => User, { eager: true })
  @JoinColumn()
  player1: User;

  @OneToOne((type) => User, { eager: true })
  @JoinColumn()
  player2: User;

  @OneToOne((type) => Deck, { eager: true })
  @JoinColumn()
  player1Deck: Deck;

  @OneToOne((type) => Deck, { eager: true })
  @JoinColumn()
  player2Deck: Deck;

  @Column()
  color1: string;

  @Column()
  color2: string;

  @OneToOne((type) => User, { eager: true })
  @JoinColumn()
  winner: User;

  toJson = () => {
    const {
      id,
      player1,
      player2,
      player1Deck,
      player2Deck,
      winner,
      color1,
      color2,
    } = this;

    return {
      id,
      color1,
      color2,
      player1: player1 && player1.toJson(),
      player2: player2 && player2.toJson(),
      player1Deck: player1 && player1Deck.toJson(),
      player2Deck: player2Deck && player1Deck.toJson(),
      winner: winner && winner.toJson(),
    };
  };
}

Here is a screenshot of my lobby table that shows i have the gameId column for the relationship in my lobby table image

and also here is a screenshot of my game table that shows all the fields are on the table to match the entity code image

If anyone wanted to see other code surrounding the issue, here's a link to the repo and branch this bug is happening in. Please let me know if you have any questions that might illuminate the issue

https://github.com/ZakRabe/gtoons/tree/game-logic/server/src/common/entity

This one has really stumped me for a few days, thanks in advance for any help/advice.

ZakRabe commented 4 years ago

Im actually really dumb. lol.

i had the wrong table name in the entity declaration

@Entity({ name: 'gamestate' })

this is not the gamestate table >.<;;;;;;;