Restaurants Table

INSERT INTO restaurants (creation_date, updated_on, address, city, description, name) VALUES
('2024-05-01', '2024-05-01 11:00:00', '123 FC Road', 'Pune', 'Traditional Maharashtrian meals', 'Shree Misal House'),
('2024-05-02', '2024-05-02 14:00:00', '88 JM Road', 'Pune', 'Popular North Indian and tandoor dishes', 'Tandoor Junction'),
('2024-05-03', '2024-05-03 17:30:00', '42 Baner Road', 'Pune', 'Modern vegetarian café with fusion food', 'Green Leaf Café');

Food Items Table

INSERT INTO food_items (creation_date, updated_on, is_veg, item_description, item_name, price, restaurant_id) VALUES
('2024-05-01', '2024-05-01 11:10:00', b'1', 'Spicy misal topped with farsan and onions', 'Puneri Misal', 70, 1),
('2024-05-01', '2024-05-01 11:15:00', b'1', 'Sabudana khichdi with peanuts and lemon', 'Sabudana Khichdi', 60, 1),
('2024-05-02', '2024-05-02 14:15:00', b'0', 'Char-grilled chicken with Indian spices', 'Tandoori Chicken', 180, 2),
('2024-05-02', '2024-05-02 14:30:00', b'1', 'Soft naan stuffed with spiced potatoes', 'Aloo Kulcha', 90, 2),
('2024-05-03', '2024-05-03 17:45:00', b'1', 'Millet-based pizza with paneer topping', 'Desi Paneer Pizza', 150, 3),
('2024-05-03', '2024-05-03 18:00:00', b'1', 'Chilled kokum-based beverage', 'Kokum Cooler', 50, 3);


Context and Entity Mapping

Database Schema

Based on the SQL, the database schema is:

Entity Classes

These align with the Restaurant and FoodItem entities from previous queries, extending BaseEntity for common fields (id, createdAt, updatedAt, version).

BaseEntity

import jakarta.persistence.Id;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.Version;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import java.time.LocalDateTime;

@MappedSuperclass
public abstract class BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @CreationTimestamp
    private LocalDateTime createdAt;

    @UpdateTimestamp
    private LocalDateTime updatedAt;

    @Version
    private int version;

    // Getters and Setters (or use Lombok)
}

Restaurant Entity

import jakarta.persistence.Entity;
import jakarta.persistence.OneToMany;
import jakarta.persistence.CascadeType;
import lombok.Getter;
import lombok.Setter;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.ToString;
import java.util.ArrayList;
import java.util.List;

@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString(exclude = {"foodItems"}, callSuper = true)
public class Restaurant extends BaseEntity {
    private String name;
    private String address;
    private String city;
    private String description;

    @OneToMany(mappedBy = "chosenRestaurant", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<FoodItem> foodItems = new ArrayList<>();

    // Helper methods (per Gavin King)
    public void addFoodItem(FoodItem item) {
        foodItems.add(item);
        item.setChosenRestaurant(this);
    }

    public void removeFoodItem(FoodItem item) {
        foodItems.remove(item);
        item.setChosenRestaurant(null);
    }
}

FoodItem Entity

import jakarta.persistence.Entity;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.JoinColumn;
import lombok.Getter;
import lombok.Setter;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.ToString;

@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString(callSuper = true)
public class FoodItem extends BaseEntity {
    private String itemName;
    private String itemDescription;
    private boolean isVeg;
    private int price;

    @ManyToOne
    @JoinColumn(name = "restaurant_id", nullable = false)
    private Restaurant chosenRestaurant;
}

Mapping to SQL