Skip to main content
RapidDev - Software Development Agency
cursor-tutorial

Why Cursor ignores ORM naming conventions

Cursor generates TypeORM entities with camelCase column names that do not match your database's snake_case conventions because it ignores your NamingStrategy configuration. By referencing your ormconfig with @file, adding TypeORM rules to .cursorrules, and including your naming strategy in the entity generation prompt, you get entities that match your actual database schema.

What you'll learn

  • Why Cursor ignores TypeORM naming strategies
  • How to add ORM rules to .cursorrules
  • How to reference ormconfig when generating entities
  • How to audit existing entities for naming mismatches
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner6 min read10-15 minCursor Free+, NestJS + TypeORM projectsMarch 2026RapidDev Engineering Team
TL;DR

Cursor generates TypeORM entities with camelCase column names that do not match your database's snake_case conventions because it ignores your NamingStrategy configuration. By referencing your ormconfig with @file, adding TypeORM rules to .cursorrules, and including your naming strategy in the entity generation prompt, you get entities that match your actual database schema.

Why Cursor ignores ORM naming conventions

TypeORM naming strategies (like SnakeNamingStrategy) transform entity property names to database column names automatically. Cursor does not read your ormconfig or data source configuration, so it generates entities with default camelCase naming that fails at runtime. This tutorial fixes the disconnect.

Prerequisites

  • Cursor installed with a NestJS + TypeORM project
  • A naming strategy configured (e.g., typeorm-naming-strategies)
  • Existing database with established naming conventions
  • Familiarity with Cursor Chat (Cmd+L) and Cmd+K

Step-by-step guide

1

Add TypeORM rules to .cursor/rules

Create rules that specify your naming convention and TypeORM patterns. This ensures Cursor generates entities that match your database schema.

.cursor/rules/typeorm.mdc
1---
2description: TypeORM entity conventions
3globs: "src/**/*.entity.ts"
4alwaysApply: true
5---
6
7## TypeORM Naming Rules
8- Database uses snake_case column names
9- Entity properties use camelCase
10- SnakeNamingStrategy is configured in data source
11- Do NOT add explicit @Column({ name: 'snake_case' }) the strategy handles it
12- Use @CreateDateColumn() for created_at (auto-mapped to snake_case)
13- Use @UpdateDateColumn() for updated_at (auto-mapped to snake_case)
14- Use @PrimaryGeneratedColumn('uuid') for IDs
15- Join columns: @JoinColumn() without explicit name (strategy handles it)
16- Table names: @Entity('table_name') with explicit snake_case name
17
18## NestJS Patterns
19- Entities in src/modules/{module}/entities/
20- DTOs in src/modules/{module}/dto/
21- Repositories use @InjectRepository(Entity)

Expected result: Cursor generates TypeORM entities that work with your SnakeNamingStrategy.

2

Reference your data source config in prompts

When generating entities, reference your TypeORM data source configuration so Cursor sees the naming strategy and connection settings.

Cursor Chat prompt
1// Cursor Chat prompt (Cmd+L):
2// @src/config/data-source.ts @.cursor/rules/typeorm.mdc
3// Generate a Product entity for the 'products' table with:
4// - id (UUID primary key)
5// - name (string, not null)
6// - description (text, nullable)
7// - price (decimal 10,2)
8// - stockQuantity (integer, default 0)
9// - isActive (boolean, default true)
10// - categoryId (UUID foreign key to categories)
11// - createdAt, updatedAt timestamps
12//
13// Our SnakeNamingStrategy maps camelCase properties to
14// snake_case columns automatically.

Expected result: An entity with camelCase properties that the naming strategy maps correctly to snake_case columns.

3

Generate the entity with correct decorators

The generated entity should use camelCase properties without explicit column name overrides. The naming strategy handles the mapping.

src/modules/product/entities/product.entity.ts
1import { Entity, Column, PrimaryGeneratedColumn, CreateDateColumn, UpdateDateColumn, ManyToOne, JoinColumn } from 'typeorm';
2import { Category } from './category.entity';
3
4@Entity('products')
5export class Product {
6 @PrimaryGeneratedColumn('uuid')
7 id: string;
8
9 @Column({ type: 'varchar', length: 255 })
10 name: string;
11
12 @Column({ type: 'text', nullable: true })
13 description: string | null;
14
15 @Column({ type: 'decimal', precision: 10, scale: 2 })
16 price: number;
17
18 @Column({ type: 'int', default: 0 })
19 stockQuantity: number;
20
21 @Column({ type: 'boolean', default: true })
22 isActive: boolean;
23
24 @ManyToOne(() => Category)
25 @JoinColumn()
26 category: Category;
27
28 @Column({ type: 'uuid' })
29 categoryId: string;
30
31 @CreateDateColumn()
32 createdAt: Date;
33
34 @UpdateDateColumn()
35 updatedAt: Date;
36}

Pro tip: Do NOT add explicit column names like @Column({ name: 'stock_quantity' }). The SnakeNamingStrategy handles this automatically. Adding explicit names would double-transform the name.

Expected result: An entity with camelCase properties and no explicit column name overrides.

4

Audit existing entities for naming mismatches

Check your existing entities for naming issues that may have been introduced by Cursor without the rules in place.

Cursor Chat prompt
1// Cursor Chat prompt (Cmd+L, Ask mode):
2// @src/ Find all TypeORM entities and check for:
3// 1. Explicit @Column({ name: '...' }) that conflict with
4// the SnakeNamingStrategy (double transformation)
5// 2. Properties that don't follow camelCase convention
6// 3. @Entity() without explicit table name
7// 4. Missing @CreateDateColumn or @UpdateDateColumn
8// 5. @JoinColumn with explicit name that conflicts with strategy

Expected result: A report of naming mismatches and conflicts in existing entities.

5

Generate matching DTOs and migrations

Ask Cursor to generate DTOs and a migration for the entity, ensuring consistent naming throughout the module.

Cursor Chat prompt
1// Cursor Chat prompt (Cmd+L):
2// @src/modules/product/entities/product.entity.ts
3// Generate:
4// 1. CreateProductDto with class-validator decorators
5// 2. UpdateProductDto (Partial of Create)
6// 3. A TypeORM migration that creates the products table
7// with snake_case column names matching our entity
8// (stock_quantity, is_active, category_id, created_at, updated_at)

Expected result: DTOs and migration that are consistent with the entity and naming strategy.

Complete working example

src/modules/product/entities/product.entity.ts
1import {
2 Entity,
3 Column,
4 PrimaryGeneratedColumn,
5 CreateDateColumn,
6 UpdateDateColumn,
7 ManyToOne,
8 JoinColumn,
9 Index,
10} from 'typeorm';
11import { Category } from '../../category/entities/category.entity';
12
13@Entity('products')
14export class Product {
15 @PrimaryGeneratedColumn('uuid')
16 id: string;
17
18 @Column({ type: 'varchar', length: 255 })
19 @Index()
20 name: string;
21
22 @Column({ type: 'text', nullable: true })
23 description: string | null;
24
25 @Column({ type: 'decimal', precision: 10, scale: 2 })
26 price: number;
27
28 @Column({ type: 'int', default: 0 })
29 stockQuantity: number;
30
31 @Column({ type: 'boolean', default: true })
32 isActive: boolean;
33
34 @ManyToOne(() => Category, { onDelete: 'SET NULL', nullable: true })
35 @JoinColumn()
36 category: Category | null;
37
38 @Column({ type: 'uuid', nullable: true })
39 @Index()
40 categoryId: string | null;
41
42 @CreateDateColumn()
43 createdAt: Date;
44
45 @UpdateDateColumn()
46 updatedAt: Date;
47}
48
49// With SnakeNamingStrategy, columns in database:
50// id, name, description, price, stock_quantity,
51// is_active, category_id, created_at, updated_at

Common mistakes

Why it's a problem: Adding explicit @Column({ name: 'snake_case' }) with a naming strategy

How to avoid: Add 'Do NOT add explicit column names, the naming strategy handles it' to .cursorrules.

Why it's a problem: Cursor generating entities without @Entity('table_name')

How to avoid: Always specify the table name: @Entity('products'). Add this requirement to your TypeORM rules.

Why it's a problem: Using @Column() without type specification

How to avoid: Require explicit types: @Column({ type: 'varchar', length: 255 }). Add this to your .cursorrules.

Best practices

  • Reference your data source config with @file when generating entities
  • Add TypeORM rules specifying naming conventions to .cursor/rules
  • Use camelCase properties without explicit column names when using a naming strategy
  • Always specify @Entity('table_name') with explicit snake_case table name
  • Include explicit column types in @Column decorators
  • Generate DTOs and migrations alongside entities for consistency
  • Audit existing entities periodically for naming strategy conflicts

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

Create a TypeORM entity for a 'products' table in a NestJS project that uses SnakeNamingStrategy. Properties should be camelCase (stockQuantity, isActive, categoryId) without explicit column name overrides. Include: UUID primary key, varchar name, text description, decimal price, int stockQuantity, boolean isActive, UUID categoryId FK, timestamps. Add @Index where appropriate.

Cursor Prompt

In Cursor Chat (Cmd+L): @src/config/data-source.ts @.cursor/rules/typeorm.mdc Generate a Product entity for the products table. Use camelCase properties — our SnakeNamingStrategy maps to snake_case automatically. Do NOT add explicit column names. Include UUID id, name, description, price, stockQuantity, isActive, categoryId FK, timestamps.

Frequently asked questions

What is the SnakeNamingStrategy?

It is a TypeORM naming strategy from the typeorm-naming-strategies package that automatically converts camelCase entity properties to snake_case database columns. For example, stockQuantity becomes stock_quantity.

Can Cursor generate TypeORM migrations?

Yes. Reference the entity and ask Cursor to generate a migration. However, for production, always use TypeORM's CLI: npx typeorm migration:generate to ensure accuracy.

How do I handle custom column names that differ from the naming convention?

For exceptions, use @Column({ name: 'custom_name' }). Add a comment explaining why the override exists. This should be rare with a proper naming strategy.

Does this apply to Prisma or Drizzle?

Each ORM has its own naming conventions. Create separate .cursor/rules for your ORM. Prisma uses @map for column names, Drizzle uses explicit column definitions.

Will Cursor respect the naming strategy in query builder code?

Not automatically. When generating QueryBuilder code, Cursor should use camelCase property names, not snake_case column names. The naming strategy translates at the ORM level.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.