I have a User Entity with an Email Column. When I use TypeORM's findOne function to search for a Email which doesn't exist in the database, findOne returns the first entry to the User Entity for some reason. This function seems not to work like in the documentation.
findOne:
// returns the first User of database
const user = await this.userRepository.findOne({ email: '[email protected]' });
User.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;
}
}
This is from the official documentation:
const user = new User(); user.firstName = "Timber"; user.lastName = "Saw"; user.age = 25; await repository.save(user);
const allUsers = await repository.find(); const firstUser = await repository.findOne(1); // find by id const timber = await repository.findOne({ firstName: "Timber", lastName: "Saw" });
await repository.remove(timber);
find will return an array, you should check the length of the array to confirm the rows match the WHERE clause executed. What happens with the current findOne implementation is that when a row is not found with the required values, the first row of the table in question is being returned. Hope this helps!
TypeORM is a TypeScript ORM (object-relational mapper) library that makes it easy to link your TypeScript application up to a relational database database. TypeORM supports MySQL, SQlite, Postgres, MS SQL Server, and a host of other traditional options.
Works for me:
const user = await this.userRepository.findOne(
{ where:
{ email: '[email protected]' }
}
);
Since User.email
property is a function and not a string, your findOne
query essentially tries to find an entity whose email
function equals '[email protected]'
which naturally doesn't work. The actual email column in your model is _email
, which as a private property cannot be referenced to in a TypeORM query.
There's a couple of options here:
Get rid of your getters and setters. TypeORM does not support this form of encapsulation. Instead you can wrap your TypeORM Entity class with another domain model class for encapsulation, or if you're using getters/setters to transform values before db insert/select you could use TypeORM's value transformers instead.
Use QueryBuilder
for your queries instead of the find
/findOne
/etc methods. QueryBuilder
can refer to any arbitrary column.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With