Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
target/
/.idea/
.env
6 changes: 6 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM eclipse-temurin:21-jdk

COPY src/main/java/org/example/App.java /App.java

ENTRYPOINT ["java", "/App.java"]

Comment on lines +1 to +6
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Source-file execution won't work with JPA dependencies.

Running java /App.java uses Java's single-file source execution, which doesn't support external dependencies. Since the application uses JPA/Hibernate, this approach will fail.

Consider building with Maven and running the compiled application:

-FROM eclipse-temurin:21-jdk
+FROM eclipse-temurin:21-jdk AS build
+WORKDIR /build
+COPY pom.xml .
+COPY src ./src
+RUN ./mvnw package -DskipTests

-COPY src/main/java/org/example/App.java /App.java
-
-ENTRYPOINT ["java", "/App.java"]
+FROM eclipse-temurin:21-jre
+WORKDIR /app
+COPY --from=build /build/target/*.jar app.jar
+ENTRYPOINT ["java", "-jar", "app.jar"]

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In Dockerfile lines 1-6, the current ENTRYPOINT uses Java's single-file source
execution which cannot load external JPA/Hibernate dependencies; replace this
with a build-and-run flow: use a multi-stage Dockerfile (or build artifact
externally) that runs Maven to compile/package the app into a fat/uber JAR (mvn
package or mvn -DskipTests package with a plugin like
maven-shade/spring-boot-maven-plugin), copy the resulting JAR into a slim JRE
base image, and change ENTRYPOINT to run java -jar /app.jar so the JVM can load
all JPA dependencies at runtime.

1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[![Review Assignment Due Date](https://classroom.github.com/assets/deadline-readme-button-22041afd0340ce965d47ae6ef1cefeee28c7c493a6346c4f15d667ab976d596c.svg)](https://classroom.github.com/a/_uV8Mn8f)
# 📘 Projektarbete: JPA + Hibernate med GitHub-flöde

Projektet genomförs som antingen en Java CLI-applikation eller med hjälp av JavaFX om ni vill ha ett grafiskt gränssnitt.
Expand Down
42 changes: 42 additions & 0 deletions dfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
commit 149e0caf9a2d36b0dfd9254b37c62c2bb73d2f0c (HEAD -> main, origin/main, origin/HEAD)
Author: github-classroom[bot] <66690702+github-classroom[bot]@users.noreply.github.com>
Date: Mon Dec 15 09:40:48 2025 +0000

add deadline

commit 879440803daa45b536e2ea5f3ec269d1be62bf04 (upstream/main, upstream/HEAD)
Author: Martin Blomberg <martin.blomberg@outlook.com>
Date: Sun Dec 14 16:07:37 2025 +0100

Setup for JPA application

commit 539e1a559ab7607b40651315e45ef50074c51b8c
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date: Sun Dec 14 12:52:36 2025 +0000

Bump org.mockito:mockito-junit-jupiter in the maven-deps group (#1)

Bumps the maven-deps group with 1 update: [org.mockito:mockito-junit-jupiter](https://github.com/mockito/mockito).


Updates `org.mockito:mockito-junit-jupiter` from 5.20.0 to 5.21.0
- [Release notes](https://github.com/mockito/mockito/releases)
- [Commits](https://github.com/mockito/mockito/compare/v5.20.0...v5.21.0)

---
updated-dependencies:
- dependency-name: org.mockito:mockito-junit-jupiter
dependency-version: 5.21.0
dependency-type: direct:development
update-type: version-update:semver-minor
dependency-group: maven-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

commit c9a2be0c3d4286e6322bb017f66aa77bbaaa5a00
Author: github-classroom[bot] <66690702+github-classroom[bot]@users.noreply.github.com>
Date: Sun Dec 14 12:51:33 2025 +0000

Initial commit
Comment on lines +1 to +42
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove this accidentally committed file.

This file appears to be git log output that was accidentally committed. The filename dfg suggests it may have been created during debugging. It contains ANSI escape codes and commit metadata that should not be part of the repository.

Remove this file from the PR:

git rm dfg
🤖 Prompt for AI Agents
In file dfg lines 1-42: this file is accidental git log output with ANSI escape
codes and commit metadata; remove it from the repository and the PR by deleting
the file and committing that change (run git rm dfg, commit with a clear message
like "remove accidental dfg log file", and push the branch), ensuring no other
valid code is removed and the commit only contains the removal.

18 changes: 18 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
services:
mysql:
image: mysql:9.5.0
container_name: mysql
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_ROOT_HOST: "%"
MYSQL_DATABASE: app_db
MYSQL_USER: grupp2
MYSQL_PASSWORD: ${PASSWORD}
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
volumes:
mysql_data:

Comment on lines +1 to +17
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Inconsistent docker-compose configurations and hardcoded credentials.

There are two docker-compose files with conflicting configurations:

  • Root docker-compose.yaml: database app_db, password via ${PASSWORD} env var
  • src/docker/docker-compose.yml: database test, hardcoded password morot7

Also, MYSQL_ROOT_PASSWORD is hardcoded on line 6. Consider using environment variables consistently for all sensitive values.

 services:
   mysql:
     image: mysql:9.5.0
     container_name: mysql
     environment:
-      MYSQL_ROOT_PASSWORD: rootpassword
+      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
       MYSQL_ROOT_HOST: "%"
       MYSQL_DATABASE: app_db
       MYSQL_USER: grupp2
       MYSQL_PASSWORD: ${PASSWORD}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
services:
mysql:
image: mysql:9.5.0
container_name: mysql
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_ROOT_HOST: "%"
MYSQL_DATABASE: app_db
MYSQL_USER: grupp2
MYSQL_PASSWORD: ${PASSWORD}
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
volumes:
mysql_data:
services:
mysql:
image: mysql:9.5.0
container_name: mysql
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_ROOT_HOST: "%"
MYSQL_DATABASE: app_db
MYSQL_USER: grupp2
MYSQL_PASSWORD: ${PASSWORD}
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
volumes:
mysql_data:
🤖 Prompt for AI Agents
In docker-compose.yaml around lines 1–17, the file hardcodes MYSQL_ROOT_PASSWORD
and uses an env var for MYSQL_PASSWORD while a different compose under
src/docker/docker-compose.yml hardcodes other DB settings, causing inconsistent
configuration and exposure of secrets; update this file to read
MYSQL_ROOT_PASSWORD, MYSQL_DATABASE and MYSQL_PASSWORD from environment
variables (e.g. ${MYSQL_ROOT_PASSWORD}, ${MYSQL_DATABASE}, ${MYSQL_PASSWORD})
instead of literals, then update src/docker/docker-compose.yml to use the same
env variable names (remove the hardcoded password "morot7" and hardcoded DB name
"test"), and add or document a single .env file (or CI secrets) that defines
these variables so both compose files stay consistent and no credentials are
hardcoded.


4 changes: 4 additions & 0 deletions src/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
FROM eclipse-temurin:25-jdk
COPY target/classes/org/example/App.class /app/Docker/App.class
ENTRYPOINT ["java", "-cp", "/app", "Docker.Demo"]

Comment on lines +1 to +4
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Class mismatch will cause runtime failure.

The Dockerfile copies App.class to /app/Docker/App.class but the entrypoint attempts to run Docker.Demo. This will fail with ClassNotFoundException since no Demo.class exists.

Either copy the correct class file or fix the entrypoint to match:

 FROM eclipse-temurin:25-jdk
-COPY target/classes/org/example/App.class /app/Docker/App.class
-ENTRYPOINT ["java", "-cp", "/app", "Docker.Demo"]
+COPY target/classes/org/example/App.class /app/org/example/App.class
+ENTRYPOINT ["java", "-cp", "/app", "org.example.App"]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
FROM eclipse-temurin:25-jdk
COPY target/classes/org/example/App.class /app/Docker/App.class
ENTRYPOINT ["java", "-cp", "/app", "Docker.Demo"]
FROM eclipse-temurin:25-jdk
COPY target/classes/org/example/App.class /app/org/example/App.class
ENTRYPOINT ["java", "-cp", "/app", "org.example.App"]
🤖 Prompt for AI Agents
In src/docker/Dockerfile lines 1-4: the Dockerfile copies App.class to
/app/Docker/App.class but ENTRYPOINT tries to run Docker.Demo, causing
ClassNotFoundException. Fix by making the copied class and the entrypoint match:
either copy the Demo.class (from the build output) into /app/Docker/Demo.class
if you intend to run Docker.Demo, or change the ENTRYPOINT to the actual class
you copied (e.g., the package-qualified org.example.App) and ensure the -cp
includes /app; update paths/names accordingly so the class on disk matches the
runtime class name.

17 changes: 17 additions & 0 deletions src/docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
services:
mysql:
image: mysql:9.5.0
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_ROOT_HOST: "%"
MYSQL_DATABASE: test
MYSQL_USER: grupp2
MYSQL_PASSWORD: morot7
Comment on lines +4 to +9
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Hardcoded database credentials committed to repository.

Sensitive credentials (root, morot7) are hardcoded and will be visible in version control history. Use environment variables or Docker secrets instead.

 services:
   mysql:
     image: mysql:9.5.0
     environment:
-      MYSQL_ROOT_PASSWORD: root
+      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
       MYSQL_ROOT_HOST: "%"
-      MYSQL_DATABASE: test
+      MYSQL_DATABASE: ${MYSQL_DATABASE:-app_db}
       MYSQL_USER: grupp2
-      MYSQL_PASSWORD: morot7
+      MYSQL_PASSWORD: ${MYSQL_PASSWORD}

Add a .env.example file to document required variables without exposing actual values.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/docker/docker-compose.yml around lines 4 to 9, the MySQL credentials are
hardcoded which exposes secrets in VCS; replace the literal values with
references to environment variables or Docker secrets (e.g., use
${MYSQL_ROOT_PASSWORD}, ${MYSQL_DATABASE}, ${MYSQL_USER}, ${MYSQL_PASSWORD} or
configure docker secrets) and update docker-compose to read from an env_file or
secrets block; add a .env.example committed to the repo that lists the required
variable names (with placeholder values) and update README or compose docs to
instruct developers to create a real .env (or secrets) with actual credentials
outside of version control.

ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql


volumes:
mysql_data:
78 changes: 78 additions & 0 deletions src/main/java/org/example/entities/OpeningHours.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package org.example.entities;

import jakarta.persistence.*;

import java.time.LocalTime;

@Entity
public class OpeningHours {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Enumerated(EnumType.STRING)
private Weekday weekday;

private LocalTime openingTime;
private LocalTime closingTime;
Comment on lines +8 to +18
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Missing @ManyToOne relationship to Restaurant entity.

The OpeningHours entity is missing a bidirectional relationship to Restaurant. Looking at Restaurant.java, it defines a @OneToMany relationship, but there's no corresponding @ManyToOne in this entity. This causes several issues:

  1. The foreign key column is not properly defined in the OpeningHours table
  2. The @JoinColumn(name = "openingHoursId") in Restaurant.java is incorrect for a @OneToMany relationship (it would try to place the FK in the wrong table)
  3. Navigation from OpeningHours back to its Restaurant is impossible
🔎 Apply this diff to add the bidirectional relationship:

Add a @ManyToOne field after the id field:

     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id;
 
+    @ManyToOne
+    @JoinColumn(name = "restaurant_id")
+    private Restaurant restaurant;
+
     @Enumerated(EnumType.STRING)
     private Weekday weekday;

Update the constructor to accept the Restaurant parameter:

-    public OpeningHours(Weekday weekday, LocalTime openingTime, LocalTime closingTime) {
+    public OpeningHours(Restaurant restaurant, Weekday weekday, LocalTime openingTime, LocalTime closingTime) {
+        this.restaurant = restaurant;
         this.weekday = weekday;

Add getter and setter for the restaurant field:

public Restaurant getRestaurant() {
    return restaurant;
}

public void setRestaurant(Restaurant restaurant) {
    this.restaurant = restaurant;
}

Additionally, fix the @JoinColumn in Restaurant.java:

// In Restaurant.java, change from:
@OneToMany
@JoinColumn(name = "openingHoursId")
private List<OpeningHours> openingHours = new ArrayList<>();

// To:
@OneToMany(mappedBy = "restaurant")
private List<OpeningHours> openingHours = new ArrayList<>();

Based on the relationship structure observed in Restaurant.java and standard JPA bidirectional OneToMany/ManyToOne patterns.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/main/java/org/example/entities/OpeningHours.java around lines 8 to 18,
add a bidirectional ManyToOne relationship to Restaurant so the foreign key is
on the OpeningHours table: declare a private Restaurant restaurant field
annotated with @ManyToOne and @JoinColumn(name = "restaurant_id") placed after
the id field, update the constructors to accept and set the Restaurant
parameter, and add corresponding getRestaurant and setRestaurant methods; then
update src/main/java/org/example/entities/Restaurant.java to change the
OneToMany mapping from using @JoinColumn(name = "openingHoursId") to
@OneToMany(mappedBy = "restaurant") so the relationship is properly mapped.


public OpeningHours(Long id, Weekday weekday, LocalTime openingTime, LocalTime closingTime) {
this.id = id;
this.weekday = weekday;
this.openingTime = openingTime;
this.closingTime = closingTime;
if(openingTime.isAfter(closingTime))
throw new RuntimeException("Opening time cannot be after closing time");
Comment on lines +25 to +26
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use IllegalArgumentException instead of generic RuntimeException.

The validation throws a generic RuntimeException, which makes it harder to handle specific validation failures. Use IllegalArgumentException for input validation errors as it's more semantically appropriate.

🔎 Apply this diff:
         if(openingTime.isAfter(closingTime))
-            throw new RuntimeException("Opening time cannot be after closing time");
+            throw new IllegalArgumentException("Opening time cannot be after closing time");
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if(openingTime.isAfter(closingTime))
throw new RuntimeException("Opening time cannot be after closing time");
if(openingTime.isAfter(closingTime))
throw new IllegalArgumentException("Opening time cannot be after closing time");
🤖 Prompt for AI Agents
In src/main/java/org/example/entities/OpeningHours.java around lines 25 to 26,
the code throws a generic RuntimeException when openingTime is after
closingTime; replace that with an IllegalArgumentException to more accurately
represent invalid input. Change the throw site to instantiate and throw an
IllegalArgumentException with the same or a slightly more descriptive message,
ensuring callers can catch validation failures specifically.

}

public OpeningHours(){}

public Long getId() {
return id;
}

public Weekday getWeekday() {
return weekday;
}

public void setWeekday(Weekday weekday) {
this.weekday = weekday;
}

public LocalTime getOpeningTime() {
return openingTime;
}

public void setOpeningTime(LocalTime opening_time) {
this.openingTime = opening_time;
}
Comment on lines +47 to +49
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add validation to setters to maintain time constraints.

The constructor validates that openingTime is not after closingTime (line 25), but the setters setOpeningTime and setClosingTime lack this validation. This allows the invariant to be violated after object construction:

OpeningHours hours = new OpeningHours(Weekday.MONDAY, LocalTime.of(9, 0), LocalTime.of(17, 0)); // Valid
hours.setOpeningTime(LocalTime.of(18, 0)); // Now opening > closing, but no validation!
🔎 Suggested fix - extract validation and apply in setters:

First, extract the validation to a private method:

private void validateTimes(LocalTime opening, LocalTime closing) {
    if (opening != null && closing != null && opening.isAfter(closing)) {
        throw new IllegalArgumentException("Opening time cannot be after closing time");
    }
}

Then update the constructor:

     public OpeningHours(Weekday weekday, LocalTime openingTime, LocalTime closingTime) {
         this.weekday = weekday;
         this.openingTime = openingTime;
         this.closingTime = closingTime;
-        if(openingTime.isAfter(closingTime))
-            throw new RuntimeException("Opening time cannot be after closing time");
+        validateTimes(openingTime, closingTime);
     }

And add validation to both setters:

     public void setOpeningTime(LocalTime opening_time) {
+        validateTimes(opening_time, this.closingTime);
         this.openingTime = opening_time;
     }
     public void setClosingTime(LocalTime closing_time) {
+        validateTimes(this.openingTime, closing_time);
         this.closingTime = closing_time;
     }

Also applies to: 55-57

🤖 Prompt for AI Agents
In src/main/java/org/example/entities/OpeningHours.java around lines 47-49 and
55-57, the setters lack the same time-consistency check used in the constructor,
allowing openingTime to become after closingTime; extract a private
validateTimes(LocalTime opening, LocalTime closing) method that throws
IllegalArgumentException when both times are non-null and
opening.isAfter(closing), call validateTimes from the constructor and from
setOpeningTime and setClosingTime before assigning the fields, and ensure the
setters accept nulls but still enforce the invariant when both times are
present.


public LocalTime getClosingTime() {
return closingTime;
}

public void setClosingTime(LocalTime closing_time) {
this.closingTime = closing_time;
}

@Override
public String toString() {
return "OpeningHours{" +
"id=" + id +
", weekday='" + weekday + '\'' +
", openingTime=" + openingTime +
", closingTime=" + closingTime +
'}';
}

enum Weekday{
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
}
}
92 changes: 92 additions & 0 deletions src/main/java/org/example/entities/Restaurant.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package org.example.entities;

import jakarta.persistence.*;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

@Entity
public class Restaurant {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@OneToMany
@JoinColumn(name = "openingHoursId")
private List<OpeningHours> openingHours = new ArrayList<>();
Comment on lines +16 to +18
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Fix the join column name to reflect the correct relationship.

The join column name "openingHoursId" is semantically incorrect. In a @OneToMany relationship from Restaurant to OpeningHours, the foreign key column in the OpeningHours table should reference the owning Restaurant, so it should be named "restaurantId" (or "restaurant_id" if using snake_case), not "openingHoursId".

🔎 Apply this diff to fix the join column name:
 @OneToMany
-@JoinColumn(name = "openingHoursId")
+@JoinColumn(name = "restaurantId")
 private List<OpeningHours> openingHours = new ArrayList<>();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@OneToMany
@JoinColumn(name = "openingHoursId")
private List<OpeningHours> openingHours = new ArrayList<>();
@OneToMany
@JoinColumn(name = "restaurantId")
private List<OpeningHours> openingHours = new ArrayList<>();
🤖 Prompt for AI Agents
In src/main/java/org/example/entities/Restaurant.java around lines 16 to 18, the
@JoinColumn is using the incorrect name "openingHoursId"; change it to the
foreign-key column that should live on the OpeningHours table referencing
Restaurant (e.g., "restaurantId" or "restaurant_id" following project naming
conventions). Update the @JoinColumn name value accordingly so the OneToMany
mapping uses the correct FK column on OpeningHours and verify database
schema/naming strategy consistency.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

find src/main/java -type f -name "*.java" | head -20

Repository: ithsjava25/ithsjava25-java-project-jpa-maven-java-template

Length of output: 240


🏁 Script executed:

cat -n src/main/java/org/example/entities/OpeningHours.java

Repository: ithsjava25/ithsjava25-java-project-jpa-maven-java-template

Length of output: 1975


🏁 Script executed:

cat -n src/main/java/org/example/entities/Restaurant.java

Repository: ithsjava25/ithsjava25-java-project-jpa-maven-java-template

Length of output: 2746


Fix the bidirectional relationship configuration between Restaurant and OpeningHours.

The relationship is incomplete and incorrectly configured:

  1. Incorrect @joincolumn name: The name "openingHoursId" is backwards. The foreign key should reference the Restaurant, typically named "restaurant_id".

  2. Missing @manytoone in OpeningHours: The OpeningHours entity lacks a @ManyToOne field referencing Restaurant, and the constructor parameter restaurant (line 18) is never assigned to any field—indicating an incomplete mapping.

  3. Proper bidirectional setup should be:

    • Restaurant: @OneToMany(mappedBy = "restaurant") (remove @joincolumn)
    • OpeningHours: Add @ManyToOne field with @JoinColumn(name = "restaurant_id") and update the constructor to assign it


private String name;
private String category;
private String address;
private BigDecimal priceRange;
private double rating;

public Restaurant(Long id, String name, String category, String address, BigDecimal priceRange, double rating) {
this.id = id;
this.name = name;
this.category = category;
this.address = address;
this.priceRange = priceRange;
this.rating = rating;
}

public Restaurant(){}

public Long getId() {
return id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getCategory() {
return category;
}

public void setCategory(String category) {
this.category = category;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

public BigDecimal getPriceRange() {
return priceRange;
}

public void setPriceRange(BigDecimal price_range) {
this.priceRange = price_range;
}

public double getRating() {
return rating;
}

public void setRating(double rating) {
this.rating = rating;
}

@Override
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add missing getters and setters for the openingHours field.

The openingHours collection field is missing its getter and setter methods, making it inaccessible to external code. This prevents adding, removing, or querying opening hours for a restaurant.

🔎 Add these methods before the toString:
+public List<OpeningHours> getOpeningHours() {
+    return openingHours;
+}
+
+public void setOpeningHours(List<OpeningHours> openingHours) {
+    this.openingHours = openingHours;
+}
+
 @Override
 public String toString() {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@Override
public List<OpeningHours> getOpeningHours() {
return openingHours;
}
public void setOpeningHours(List<OpeningHours> openingHours) {
this.openingHours = openingHours;
}
@Override
public String toString() {
🤖 Prompt for AI Agents
In src/main/java/org/example/entities/Restaurant.java around line 81, the
openingHours collection field lacks public getter and setter methods which
prevents external access and modification; add a public List<OpeningHour>
getOpeningHours() and a public void setOpeningHours(List<OpeningHour>
openingHours) (or appropriate collection type) directly above the toString
method, ensuring imports and null-safety if needed, and keep method visibility
and generics consistent with the field declaration.

public String toString() {
return "Restaurant{" +
"id=" + id +
", name='" + name + '\'' +
", category='" + category + '\'' +
", address='" + address + '\'' +
", priceRange=" + priceRange +
", rating=" + rating +
'}';
}
}
22 changes: 22 additions & 0 deletions src/main/resources/META-INF/persistence.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence version="3.2"
xmlns="https://jakarta.ee/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_2.xsd">
<persistence-unit name="jpa-hibernate-mysql">
<class>org.example.Product</class>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Missing entity class registrations.

The persistence unit references org.example.Product, but this PR introduces Restaurant and OpeningHours entities that are not registered. These entities won't be managed by JPA.

     <persistence-unit name="jpa-hibernate-mysql">
-        <class>org.example.Product</class>
+        <class>org.example.entities.Restaurant</class>
+        <class>org.example.entities.OpeningHours</class>
         <properties>

Alternatively, if Product is also needed, add all three classes.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<class>org.example.Product</class>
<persistence-unit name="jpa-hibernate-mysql">
<class>org.example.entities.Restaurant</class>
<class>org.example.entities.OpeningHours</class>
<properties>
🤖 Prompt for AI Agents
In src/main/resources/META-INF/persistence.xml around line 7 the
persistence-unit only registers org.example.Product but the PR also introduces
Restaurant and OpeningHours entities; update the <class> entries to include
org.example.Restaurant and org.example.OpeningHours (or include all three if
Product is still needed) so JPA will manage the new entities, and ensure
fully-qualified class names match the package declarations.

<properties>
<!-- Database connection settings -->
<property name="jakarta.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/test"/>
<property name="jakarta.persistence.jdbc.user" value="root"/>
<property name="jakarta.persistence.jdbc.password" value="root"/>
Comment on lines +10 to +12
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Hardcoded database credentials in persistence configuration.

Database username and password are hardcoded. For production, consider using environment variable substitution or a separate configuration mechanism.

For development, this is acceptable if credentials match the docker-compose setup. However, note that the database name test only matches src/docker/docker-compose.yml, not the root docker-compose.yaml which uses app_db.

<!-- Automatically export the schema -->
<property name="hibernate.archive.autodetection" value="class"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<!-- Echo all executed SQL to console -->
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.highlight_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>