web-dev-qa-db-ja.com

TypeOrm-findOneが予期しない値を返す

メール列を持つユーザーエンティティがあります。 TypeORMのfindOne関数を使用して、データベースに存在しない電子メールを検索すると、findOneは何らかの理由で最初のエントリをユーザーエンティティに返します。この機能は、ドキュメントのようには機能しないようです。

findOne:

// returns the first User of database
const user = await this.userRepository.findOne({ email: '[email protected]' });

ser.Entity.ts:

import {
  Entity,
  Column,
  PrimaryGeneratedColumn,
} from 'typeorm';

@Entity()
export class User {
  @PrimaryGeneratedColumn({ name: 'id' })
  private _id: number;

  @Column({ name: 'password', length: 256, nullable: true })
  private _password?: string;

  @Column({ name: 'email', length: 300, nullable: true, unique: true })
  private _email?: string;

  @Column({ name: 'roles', length: 300, nullable: true })
  private _roles?: string = null;

  public get id(): number {
    return this._id;
  }

  public set id(id: number) {
    this._id = id;
  }

  public get email(): string {
    return this._email;
  }

  public set email(email: string) {
    this._email = email;
  }

  public get password(): string {
    return this._password;
  }

  public set password(password: string) {
    this._password = password;
  }

  public get roles(): string {
    return this._roles;
  }

  public set roles(roles: string) {
    this._roles = roles;
  }
}

これは公式ドキュメントからのものです:

const user = new User(); user.firstName = "木材"; user.lastName = "Saw"; user.age = 25; repository.save(user);を待つ

const allUsers = repository.find();を待つconst firstUser = repository.findOne(1);を待ちます。 // IDで検索consttimber = await repository.findOne({firstName: "Timber"、lastName: "Saw"});

リポジトリを待つ.remove(timber);

5
bonblow

User.emailプロパティは関数であり、文字列ではないため、findOneクエリは基本的に、email関数が'[email protected]'と等しいエンティティを見つけようとします。これは自然には機能しません。モデルの実際の電子メール列は_emailであり、これはプライベートプロパティとしてTypeORMクエリで参照できません。

ここにはいくつかのオプションがあります。

  1. あなたのゲッターとセッターを取り除きます。 TypeORM サポートしていません この形式のカプセル化。代わりに、カプセル化のためにTypeORMエンティティクラスを別のドメインモデルクラスでラップできます。または、db insert/selectの前にゲッター/セッターを使用して値を変換する場合は、代わりに TypeORMの値トランスフォーマー を使用できます。

  2. クエリには、QueryBuilder/find/etcメソッドの代わりにfindOneを使用します。 QueryBuilder任意の列を参照できます

1
Aleksi

私のために働く:

const user = await this.userRepository.findOne(
    { where:
        { email: '[email protected]' }
    }
);
0
chavy

これはアクティブな問題です。ディスカッションは次のリンクで入手できます: https://github.com/typeorm/typeorm/issues/25

この問題に関する私の回避策は次のとおりです。

const usersRepository = conn.getRepository(UserEntity);

const results = await usersRepository.find({
    relations: ['profile'],
        where: {
            email: username
        },
        take: 1 
    });
// ...

findは配列を返します。配列の長さをチェックして、実行されたWHERE句と行が一致することを確認する必要があります。

現在のfindOne実装で何が起こるかというと、必要な値を持つ行が見つからない場合、問題のテーブルの最初の行が返されます。

お役に立てれば!

0
Esteban Borai

タイプORMは私のために働きます:

let userData;
let userRepository = getRepository(User);
userData = await userRepository
                .findOne({
                    where: {"email":'[email protected]'}
                });
0
naval