Summary
This incident examines a common early‑career design mistake in Spring Boot: modeling hierarchical data incorrectly. The engineer attempted to represent categories and subcategories using either two separate models or a single model with a parent_id. The confusion led to inconsistent behavior, difficulty saving entities, and unclear domain boundaries.
Root Cause
The root cause was a misunderstanding of hierarchical relational modeling. Specifically:
- Treating “Category” and “SubCategory” as different entities when they are actually the same domain concept.
- Not recognizing that a self‑referential relationship (a row pointing to another row in the same table) is the correct pattern.
- Misinterpreting why some categories have no children and assuming this implies a need for a second model.
Why This Happens in Real Systems
Real systems frequently include hierarchical structures, and engineers often overcomplicate them. This happens because:
- Beginners assume different levels require different models, even when the domain does not justify it.
- ORMs hide relational complexity, making it unclear how to model parent–child relationships.
- Developers confuse optional relationships with separate entities, especially when some rows have no children.
Real-World Impact
Incorrect modeling of hierarchical data can cause:
- Inconsistent API behavior when fetching nested structures.
- Broken persistence logic because the ORM cannot map relationships properly.
- Unnecessary code duplication when two models represent the same concept.
- Hard‑to‑maintain business logic due to artificial separation of entities.
Example or Code (if necessary and relevant)
A correct Spring Boot JPA model uses a self‑referencing relationship:
@Entity
public class Category {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long categoryId;
private String name;
@ManyToOne
@JoinColumn(name = "parent_id")
private Category parent;
@OneToMany(mappedBy = "parent")
private List children = new ArrayList();
}
How Senior Engineers Fix It
Experienced engineers solve this by:
- Using one model to represent the entire hierarchy.
- Applying a self‑join to represent parent/child relationships.
- Ensuring the relationship is optional, allowing categories with no parent or no children.
- Designing service methods that recursively fetch children when needed.
- Keeping the domain model simple and expressive, avoiding unnecessary entities.
Why Juniors Miss It
Junior engineers often miss this pattern because:
- They assume “subcategory” is a different concept rather than a different instance of the same concept.
- They are unfamiliar with self‑referential database relationships.
- They expect the database to enforce hierarchical rules automatically.
- They overthink the schema instead of modeling the real‑world domain.