Skip to content

Feat/Query Builder in Entity Listeners #12558

@Ahmad-RW

Description

@Ahmad-RW

Feature Description

Entity listeners like @BeforeInsert and @BeforeUpdate are a natural place to enforce business rules, but many real-world rules require a quick db lookup (e.g., "does this user already have an active order?"). Right now there is no way to do this cleanly.

The Solution

Inject a QueryBuilder (or EntityManager) into entity listener methods, so hooks can run lookups against the same connection/transaction as the operation that triggered them:


@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id!: number;

  @Column()
  @IsNotEmpty({ message: "name is required" })
  name!: string;

  @BeforeInsert()
  async ensureNoActiveOrder(qb: QueryBuilder<Order>) {
    const existing = await qb
      .select()
      .from(Order, "o")
      .where("o.userId = :userId", { userId: this.id })
      .andWhere("o.status = 'active'")
      .getOne();

    if (existing) {
      throw new Error(`User ${this.id} has an active order`);
    }
  }
}

Considered Alternatives

Entity subscriber is an alternative but they live outside the entity class, less traceable.

Additional Context

No response

Are you willing to resolve this issue by submitting a Pull Request?

Yes, I have the time, but I don't know how to start

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions