TypeORMのハマり記録

2022年8月3日

TypeORMでException: Class constructor Test cannot be invoked without ‘new’というエラーが出た。

TypeScriptで作っているとハマる可能性がある問題。
createQueryBuilderでデータをSELECTしたタイミングで発生しました。
エラーの内容はこちら

[start:*func] [2022-08-03T08:30:52.697Z] Executed 'Functions.Test' (Failed, Id=bd6208e3-2092-41e9-9cd0-0dc9519d263e, Duration=324ms)
[start:*func] [2022-08-03T08:30:52.697Z] System.Private.CoreLib: Exception while executing function: Functions.Test. System.Private.CoreLib: Result: Failure
[start:*func] [2022-08-03T08:30:52.697Z] Exception: Class constructor Test cannot be invoked without 'new'
[start:*func] [2022-08-03T08:30:52.697Z] Stack: TypeError: Class constructor Test cannot be invoked without 'new'
[start:*func] [2022-08-03T08:30:52.697Z]     at SelectQueryBuilder.createFromAlias (/Users/takumi/Documents/src/work/azure/ts/functions/apis/node_modules/typeorm/query-builder/QueryBuilder.js:424:37)
[start:*func] [2022-08-03T08:30:52.697Z]     at SelectQueryBuilder.from (/Users/takumi/Documents/src/work/azure/ts/functions/apis/node_modules/typeorm/query-builder/SelectQueryBuilder.js:160:32)

こちらが参考になりました。

https://github.com/typeorm/typeorm/issues/4663

結論から言うと、DataSourceのconfigに問題がありました。
問題があったのは以下のentities部分。entitiesにTestを設定していなかった。

  const AppDataSource = new DataSource({
    type: "mysql",
    host: process.env.SQL_HOST,
    port: 3306,
    username: process.env.SQL_USER,
    password: process.env.SQL_PASSWORD,
    database: "test",
    synchronize: false,
    logging: false,
    entities: [],
    migrations: [],
    subscribers: [],
  });

SyntaxError: Cannot use import statement outside a module

このエラーでよく出る解答としてはts.configの設定がおかしいから修正しようというところ。
・moduleをcommonjsにする。
・targetをes6以降にしておく。

これで解決することが多そうです。

DataSourceで定義するentitiesは、実際のEntityをimportして使ったり、ファイルからロードしたりできます。今回はファイルからロードする方法で問題が発生しました。
以下のようにEntityディレクトリに格納しているので、ここから読み込みます。

そのために、以下のように設定しました。
entities: [“Entity/*”]

しかし、エラーとなります。

[start:*func] [2022-08-03T08:53:10.801Z] import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";
[start:*func] [2022-08-03T08:53:10.801Z] ^^^^^^
[start:*func] [2022-08-03T08:53:10.801Z] SyntaxError: Cannot use import statement outside a module
[start:*func] [2022-08-03T08:53:10.801Z]     at Object.compileFunction (node:vm:352:18)

色々探していると、buildで吐き出されるjsファイルをentitiesに指定する必要があるようでした。
以下のようにbuildで吐き出されるディレクトリに対して設定したらうまく動くようになりました。

entities: [“dist/Entity/*.js”]
ただ、最近もう一度やってみて
entities: [“Entity/*.ts”]で動きました。

もしかしたらAzure Functionsで動かす場合はjsで読み込まなければいけないのかもしれない。

Entity metadata for Photo#user was not found. Check if you specified a correct entity object and if it’s connected in the connection options.

Joinの実験をしようとしてでたエラー。
ほんとうにしょーーーもない理由だったのできつかった。
わかってからもスッキリというより、えーーーって気持ちの方がすごかった。

これなんですが、なんとimportしているファイル名が違ったのでだめだった。

なんで先頭小文字にやってもうたんだろう。。
ファイル名を合わせたらうまくいった。