Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/NicolasMPP/restorante-springboot/llms.txt

Use this file to discover all available pages before exploring further.

Every item served in Restorante — from a main course to a glass of water — is represented as an Alimento entity. Rather than maintaining four separate tables, Restorante uses JPA’s SINGLE_TABLE inheritance strategy: all food items occupy the alimentos table, and a tipo_alimento discriminator column records the concrete type of each row. This approach makes menu queries fast (one table scan, no joins) and lets the application handle typed food management through a clean Java class hierarchy.

The Alimento Base Class

Alimento is annotated with @Entity, @Table(name = "alimentos"), @Inheritance(strategy = InheritanceType.SINGLE_TABLE), and @DiscriminatorColumn(name = "tipo_alimento"). Its own discriminator value is GENERAL, covering any row that does not belong to a named subtype.
@Entity
@Table(name = "alimentos")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "tipo_alimento", discriminatorType = DiscriminatorType.STRING)
@DiscriminatorValue("GENERAL")
public class Alimento implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    protected Integer id;

    @Column(name = "nombre", nullable = false, length = 100)
    protected String nombre;

    @Column(name = "precio", nullable = false, precision = 10, scale = 2)
    protected BigDecimal precio;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "receta_id", nullable = true)
    protected Receta receta;

    @JsonIgnore
    @ManyToMany(mappedBy = "alimentos")
    protected List<Menu> menus = new ArrayList<>();
}
FieldTypeConstraints
idIntegerAuto-generated primary key
nombreStringNot null, max 100 characters
precioBigDecimalNot null, precision 10 / scale 2
recetaRecetaManyToOne, nullable (receta_id FK)
menusList<Menu>ManyToMany inverse side; @JsonIgnore to avoid cycles
Foods with a null receta are fully valid. Desserts, drinks, and simple sides in the seed data are created without a recipe — the receta_id FK column is intentionally nullable in the schema.

Food Subtypes

Each concrete food subtype is a plain Java class that extends Alimento and provides only a @DiscriminatorValue annotation. No subtype adds extra database columns; the tipo_alimento value is the sole differentiator stored in the alimentos table.

PlatoFuerte

Discriminator: PLATO_FUERTEMain-course dishes. In the seed data, platos fuertes are the only food type that always carry a linked Receta, reflecting the expectation that main courses have documented preparation steps.Seed examples:
NamePrice
Pasta Carbonara Premium$18.50
Bistec Angus 300g$25.00
Pollo al Horno con Hierbas$22.00
@Entity
@DiscriminatorValue("PLATO_FUERTE")
public class PlatoFuerte extends Alimento { ... }

Postres

Discriminator: POSTREDessert items. In the seed data, postres are created without a linked recipe (receta = null), demonstrating that the null-recipe path is a first-class usage pattern.Seed examples:
NamePrice
Tiramisú Casero$8.50
Helado de Chocolate$6.00
@Entity
@DiscriminatorValue("POSTRE")
public class Postres extends Alimento { ... }

Bebida

Discriminator: BEBIDADrink items. Like desserts, drinks in the seed data carry a null receta_id, since beverages are not expected to have a documented preparation process in the current model.Seed examples:
NamePrice
Coca-Cola$3.50
Agua Mineral$2.50
Jugo Natural de Naranja$4.50
@Entity
@DiscriminatorValue("BEBIDA")
public class Bebida extends Alimento { ... }

Adicionales

Discriminator: ADICIONALExtra or side items. Some adicionales in the seed data do carry a recipe (e.g., Ensalada Caprese uses the “Ensalada Caprese” recipe), while simpler ones like Pan de Ajo do not.Seed examples:
NamePrice
Ensalada Caprese$12.00
Pan de Ajo$4.00
@Entity
@DiscriminatorValue("ADICIONAL")
public class Adicionales extends Alimento { ... }

Type Strings for the API

When creating or updating a food item through the REST API, you specify the food type with one of the following string values. These values correspond directly to the JPA discriminator values written into the tipo_alimento column.
Type StringJava ClassDescription
PLATO_FUERTEPlatoFuerteMain course
POSTREPostresDessert
BEBIDABebidaDrink
ADICIONALAdicionalesSide or extra
GENERALAlimentoBase type (no specific category)

Creating a Food Item: Request Body

The AlimentoCompletoRequest body is used for POST and PUT endpoints. It bundles the food properties together with the recipe details and the chef assignment in a single payload.
{
  "nombreAlimento": "Pasta Carbonara",
  "precio": 18.50,
  "tipo": "PLATO_FUERTE",
  "nombreReceta": "Pasta Carbonara Clásica",
  "descripcionProceso": "Cocinar pasta al dente, mezclar con huevos y queso parmesano.",
  "chefCedula": "3456789012",
  "ingredientesDescripciones": ["Pasta", "Queso Parmesano", "Huevos", "Tocino"]
}
chefCedula is the cédula of the Chef (or Empleado) who will be assigned to the recipe. It is used to look up the employee record before persisting the Receta. If the food has no recipe, nombreReceta, descripcionProceso, chefCedula, and ingredientesDescripciones can be omitted or set to null.

Changing a Food’s Type

Changing an existing food’s tipo_alimento discriminator (for example, re-categorizing an item from BEBIDA to PLATO_FUERTE) is supported via the update endpoint. Because JPA does not allow updating a discriminator column through standard entity operations, the implementation uses a native SQL update to write the new discriminator value directly:
-- Example of the native update used internally
UPDATE alimentos
SET tipo_alimento = 'PLATO_FUERTE'
WHERE id = ?;
After the native update, the entity is re-fetched so the in-memory state matches the new discriminator value. This is handled transparently by the service layer — callers simply provide the new tipo in the request body.
Changing a food’s type does not add or remove columns in the database (since all types share the alimentos table). However, the application will from that point on treat the row as the new subtype, including any type-specific business logic or query filters that depend on the discriminator value.

Build docs developers (and LLMs) love