An ORM Can Guess a Type. It Can't Guess a Cardinality.
Why cardinality is a business decision an ORM can never infer on its own, a sharp counterexample proving a class's shape only ever tells you half the story, and BookMyShow's own relationships walked through.
Every class is marked as an entity. Every primitive attribute becomes a column automatically, a string, an integer, whatever it is, the ORM figures that part out on its own. The errors are gone. The problem isn't.
What's Left Once the Primitive Attributes Are Handled
A class diagram is full of a second kind of attribute: a reference to another entity, a relationship. Seat relates to SeatType. Movie relates to Language. City relates to Theatre.
Before any of those can turn into an actual column or a foreign key, something has to already be known about that relationship: its cardinality. And that's exactly the piece an ORM has no way to work out by itself.
Why an ORM Can't Guess a Cardinality
Cardinality isn't a structural fact hiding somewhere in the code, waiting to be discovered. It's a business decision, and the exact same pair of classes can carry a different cardinality at two different companies.
The relationship between an instructor and a student is a clean example. At one company, one instructor might teach exactly one student. At another, one instructor teaches many students at once. Nothing about the classes "Instructor" and "Student" settles that question — only the actual business does, and an ORM has no access to that.
A List on One Side Doesn't Even Settle the Question
Here's a sharper version of the same idea. A Batch class holds a list of Student objects. That alone proves there's a "many" on one side, a batch clearly has more than one student, but it says nothing about what's on the other side.
If Student holds no reference back to Batch at all, the natural guess is one-to-many: one batch, many students, each student belonging to exactly one batch. If Student also holds a list of Batch objects, it's many-to-many instead, since a student can now belong to more than one batch.
The surprising part: the relationship can still be many-to-many even when Student has no reference back to Batch at all, purely because of what the real data looks like. Picture two Batch objects: one holding students 1, 3, 7, and 11, the other holding 2, 4, 7, and 9. Student 7 shows up in both.
One student genuinely belonging to more than one batch is a many-to-many relationship, whether or not any class ever wrote that fact down. A class's shape only ever tells you part of the answer. The real cardinality is a fact about the business, not something a list of objects can settle on its own.
Skip the Cardinality, and the Build Fails Outright
This isn't a theoretical gap. Generate a schema from a class diagram without specifying cardinality anywhere, and the build fails, with an error saying it cannot figure out how to represent that field.
That failure comes from the exact same missing piece. The ORM knows a field exists. It has no idea what kind of relationship that field is supposed to represent, so it has nothing to generate.
Walking the Cardinality Through BookMyShow's Own Relationships
With the reasoning settled, the easy relationships in this design go quickly:
AuditoriumtoSeat. One auditorium holds many seats, and a single seat belongs to exactly one auditorium. One-to-many.CitytoTheatre. One city holds many theatres, and a single theatre belongs to exactly one city. One-to-many.
Seat to SeatType looks like the same shape on the surface, and it isn't quite. A single seat can only ever be one seat type. VIP, Gold, and Balcony aren't things one seat can be at the same time. But plenty of different seats across the same auditorium share that exact same type, so this one is many-to-one: many seats, one shared type.
Keep reading