From 7079f8fa78ab6af0f73d4e27c0e074be3d4c48e8 Mon Sep 17 00:00:00 2001 From: Boutachrafine Date: Sun, 3 Aug 2025 14:03:14 +0100 Subject: [PATCH 1/9] Adding JPA Entities --- pom.xml | 5 ++ .../spring6webapp/domain/Author.java | 49 +++++++++++++++++ .../spring6webapp/domain/Book.java | 52 +++++++++++++++++++ web/WEB-INF/web.xml | 6 +++ 4 files changed, 112 insertions(+) create mode 100644 src/main/java/guru/springframework/spring6webapp/domain/Author.java create mode 100644 src/main/java/guru/springframework/spring6webapp/domain/Book.java create mode 100644 web/WEB-INF/web.xml diff --git a/pom.xml b/pom.xml index 922b9c237..a3ff74962 100644 --- a/pom.xml +++ b/pom.xml @@ -37,6 +37,11 @@ spring-boot-starter-test test + + jakarta.persistence + jakarta.persistence-api + 3.1.0 + diff --git a/src/main/java/guru/springframework/spring6webapp/domain/Author.java b/src/main/java/guru/springframework/spring6webapp/domain/Author.java new file mode 100644 index 000000000..dccb300e0 --- /dev/null +++ b/src/main/java/guru/springframework/spring6webapp/domain/Author.java @@ -0,0 +1,49 @@ +package guru.springframework.spring6webapp.domain; + +import jakarta.persistence.*; +import java.util.Set; + +@Entity // this annotation indicates that this class is a JPA entity +public class Author { + + @Id // This annotation indicates that this field is the primary key of the entity + @GeneratedValue (strategy = GenerationType.AUTO) // this annotation specifies that the primary key will be generated automatically + private Long idAuthor; + private String firstName; + private String lastName; + + @ManyToMany(mappedBy = "authors") // this annotation indicates a many-to-many relationship with the Book entity + private Set books; + + public Long getIdAuthor() { + return idAuthor; + } + + public void setIdAuthor(Long idAuthor) { + this.idAuthor = idAuthor; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public Set getBooks() { + return books; + } + + public void setBooks(Set books) { + this.books = books; + } +} diff --git a/src/main/java/guru/springframework/spring6webapp/domain/Book.java b/src/main/java/guru/springframework/spring6webapp/domain/Book.java new file mode 100644 index 000000000..a3834c2b4 --- /dev/null +++ b/src/main/java/guru/springframework/spring6webapp/domain/Book.java @@ -0,0 +1,52 @@ +package guru.springframework.spring6webapp.domain; + +import jakarta.persistence.*; + +import java.util.Set; + +@Entity +public class Book { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long idBook; + private String title; + private String isbn; + + @ManyToMany + @JoinTable(name ="author_book", joinColumns = @JoinColumn(name = "book_id"), + inverseJoinColumns = @JoinColumn(name = "author_id")) // This annotation defines the join table for the many-to-many relationship + private Set authors; + + public Long getIdBook() { + return idBook; + } + + public void setIdBook(Long idBook) { + this.idBook = idBook; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getIsbn() { + return isbn; + } + + public void setIsbn(String isbn) { + this.isbn = isbn; + } + + public Set getAuthors() { + return authors; + } + + public void setAuthors(Set authors) { + this.authors = authors; + } +} diff --git a/web/WEB-INF/web.xml b/web/WEB-INF/web.xml new file mode 100644 index 000000000..d80081d13 --- /dev/null +++ b/web/WEB-INF/web.xml @@ -0,0 +1,6 @@ + + + \ No newline at end of file From fe09d4ec2497f85f8a4063cc396e737c8ebadc74 Mon Sep 17 00:00:00 2001 From: Boutachrafine Date: Sun, 3 Aug 2025 14:10:29 +0100 Subject: [PATCH 2/9] Adding JPA entities --- pom.xml | 3 +++ .../java/guru/springframework/spring6webapp/domain/Author.java | 1 - .../java/guru/springframework/spring6webapp/domain/Book.java | 1 - 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index a3ff74962..3dc3f576b 100644 --- a/pom.xml +++ b/pom.xml @@ -23,10 +23,12 @@ org.springframework.boot spring-boot-starter-data-jpa + org.springframework.boot spring-boot-starter-web + com.h2database h2 @@ -37,6 +39,7 @@ spring-boot-starter-test test + jakarta.persistence jakarta.persistence-api diff --git a/src/main/java/guru/springframework/spring6webapp/domain/Author.java b/src/main/java/guru/springframework/spring6webapp/domain/Author.java index dccb300e0..f2d72db16 100644 --- a/src/main/java/guru/springframework/spring6webapp/domain/Author.java +++ b/src/main/java/guru/springframework/spring6webapp/domain/Author.java @@ -5,7 +5,6 @@ @Entity // this annotation indicates that this class is a JPA entity public class Author { - @Id // This annotation indicates that this field is the primary key of the entity @GeneratedValue (strategy = GenerationType.AUTO) // this annotation specifies that the primary key will be generated automatically private Long idAuthor; diff --git a/src/main/java/guru/springframework/spring6webapp/domain/Book.java b/src/main/java/guru/springframework/spring6webapp/domain/Book.java index a3834c2b4..294698c78 100644 --- a/src/main/java/guru/springframework/spring6webapp/domain/Book.java +++ b/src/main/java/guru/springframework/spring6webapp/domain/Book.java @@ -6,7 +6,6 @@ @Entity public class Book { - @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long idBook; From 4fab5e2d119bec051790e6ece9c76ccc6af1e77d Mon Sep 17 00:00:00 2001 From: Boutachrafine Date: Sun, 3 Aug 2025 14:33:53 +0100 Subject: [PATCH 3/9] Determine Equality in Hibernate --- pom.xml | 11 +++++-- .../spring6webapp/domain/Author.java | 29 +++++++++++++++++++ .../spring6webapp/domain/Book.java | 27 +++++++++++++++++ 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 3dc3f576b..3d2fab699 100644 --- a/pom.xml +++ b/pom.xml @@ -23,12 +23,10 @@ org.springframework.boot spring-boot-starter-data-jpa - org.springframework.boot spring-boot-starter-web - com.h2database h2 @@ -39,7 +37,6 @@ spring-boot-starter-test test - jakarta.persistence jakarta.persistence-api @@ -53,6 +50,14 @@ org.springframework.boot spring-boot-maven-plugin + + org.apache.maven.plugins + maven-compiler-plugin + + 16 + 16 + + diff --git a/src/main/java/guru/springframework/spring6webapp/domain/Author.java b/src/main/java/guru/springframework/spring6webapp/domain/Author.java index f2d72db16..66c9c0f45 100644 --- a/src/main/java/guru/springframework/spring6webapp/domain/Author.java +++ b/src/main/java/guru/springframework/spring6webapp/domain/Author.java @@ -1,6 +1,8 @@ package guru.springframework.spring6webapp.domain; import jakarta.persistence.*; + +import java.util.Objects; import java.util.Set; @Entity // this annotation indicates that this class is a JPA entity @@ -45,4 +47,31 @@ public Set getBooks() { public void setBooks(Set books) { this.books = books; } + + @Override + public String toString() { + return "Author{" + + "idAuthor=" + idAuthor + + ", firstName='" + firstName + '\'' + + ", lastName='" + lastName + '\'' + + '}'; + } + + @Override + public final boolean equals(Object o) { + if (!(o instanceof Author author)) return false; + + return Objects.equals(getIdAuthor(), author.getIdAuthor()); + } + + @Override + public int hashCode() { + return Objects.hashCode(getIdAuthor()); + } + } + + + + + diff --git a/src/main/java/guru/springframework/spring6webapp/domain/Book.java b/src/main/java/guru/springframework/spring6webapp/domain/Book.java index 294698c78..1508018ec 100644 --- a/src/main/java/guru/springframework/spring6webapp/domain/Book.java +++ b/src/main/java/guru/springframework/spring6webapp/domain/Book.java @@ -2,6 +2,7 @@ import jakarta.persistence.*; +import java.util.Objects; import java.util.Set; @Entity @@ -48,4 +49,30 @@ public Set getAuthors() { public void setAuthors(Set authors) { this.authors = authors; } + + @Override + public String toString() { + return "Book{" + + "idBook=" + idBook + + ", title='" + title + '\'' + + ", isbn='" + isbn + '\'' + + '}'; + } + + @Override + public final boolean equals(Object o) { + if (!(o instanceof Book book)) return false; + + return Objects.equals(getIdBook(), book.getIdBook()); + } + + @Override + public int hashCode() { + return Objects.hashCode(getIdBook()); + } + } + + + + From 4bd607eecc09f13df452b24e3a30f85b9c1b46ca Mon Sep 17 00:00:00 2001 From: Boutachrafine Date: Sun, 3 Aug 2025 14:43:34 +0100 Subject: [PATCH 4/9] Create Repositories --- .../spring6webapp/repositories/IAuthorRepositroy.java | 8 ++++++++ .../spring6webapp/repositories/IBookRepository.java | 7 +++++++ 2 files changed, 15 insertions(+) create mode 100644 src/main/java/guru/springframework/spring6webapp/repositories/IAuthorRepositroy.java create mode 100644 src/main/java/guru/springframework/spring6webapp/repositories/IBookRepository.java diff --git a/src/main/java/guru/springframework/spring6webapp/repositories/IAuthorRepositroy.java b/src/main/java/guru/springframework/spring6webapp/repositories/IAuthorRepositroy.java new file mode 100644 index 000000000..3b57b6ae6 --- /dev/null +++ b/src/main/java/guru/springframework/spring6webapp/repositories/IAuthorRepositroy.java @@ -0,0 +1,8 @@ +package guru.springframework.spring6webapp.repositories; + +import guru.springframework.spring6webapp.domain.Author; +import org.springframework.data.repository.CrudRepository; + +public interface IAuthorRepositroy extends CrudRepository { + +} diff --git a/src/main/java/guru/springframework/spring6webapp/repositories/IBookRepository.java b/src/main/java/guru/springframework/spring6webapp/repositories/IBookRepository.java new file mode 100644 index 000000000..c6c3e9a64 --- /dev/null +++ b/src/main/java/guru/springframework/spring6webapp/repositories/IBookRepository.java @@ -0,0 +1,7 @@ +package guru.springframework.spring6webapp.repositories; + +import guru.springframework.spring6webapp.domain.Book; +import org.springframework.data.repository.CrudRepository; + +public interface IBookRepository extends CrudRepository { +} From 85761ad8573d20d892304e54be0d4de79e6d7636 Mon Sep 17 00:00:00 2001 From: Boutachrafine Date: Sun, 3 Aug 2025 15:33:17 +0100 Subject: [PATCH 5/9] Initializing Data With Spring Boot --- .../bootstrap/BootstrapData.java | 62 +++++++++++++++++++ .../spring6webapp/domain/Author.java | 3 +- .../spring6webapp/domain/Book.java | 3 +- src/main/resources/application.properties | 3 +- 4 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 src/main/java/guru/springframework/spring6webapp/bootstrap/BootstrapData.java diff --git a/src/main/java/guru/springframework/spring6webapp/bootstrap/BootstrapData.java b/src/main/java/guru/springframework/spring6webapp/bootstrap/BootstrapData.java new file mode 100644 index 000000000..e68ed1dd5 --- /dev/null +++ b/src/main/java/guru/springframework/spring6webapp/bootstrap/BootstrapData.java @@ -0,0 +1,62 @@ +package guru.springframework.spring6webapp.bootstrap; + +import guru.springframework.spring6webapp.domain.Author; +import guru.springframework.spring6webapp.domain.Book; +import guru.springframework.spring6webapp.repositories.IAuthorRepositroy; +import guru.springframework.spring6webapp.repositories.IBookRepository; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; + +@Component // This annotation indicates that this class is a Spring component and will be automatically detected by Spring's component scanning +public class BootstrapData implements CommandLineRunner { + + private final IAuthorRepositroy iAuthorRepositroy; + private final IBookRepository iBookRepository; + + public BootstrapData(IAuthorRepositroy iAuthorRepositroy, IBookRepository iBookRepository) { + this.iAuthorRepositroy = iAuthorRepositroy; + this.iBookRepository = iBookRepository; + } + + + @Override + public void run(String... args) throws Exception { + Author author1 = new Author(); + author1.setFirstName("Nabil"); + author1.setLastName("Boutachrafine"); + + Book book1 = new Book(); + book1.setTitle("Spring Framework 6"); + book1.setIsbn("1234567890"); + + Author authorSaved1 = iAuthorRepositroy.save(author1); + Book bookSaved1 = iBookRepository.save(book1); + + Author author2 = new Author(); + author2.setFirstName("Tawfiq"); + author2.setLastName("Boutachrafine"); + + Book book2 = new Book(); + book2.setTitle("Spring Boot 3"); + book2.setIsbn("0987654321"); + + Author authorSaved2 = iAuthorRepositroy.save(author2); + Book bookSaved2 = iBookRepository.save(book2); + + authorSaved1.getBooks().add(bookSaved1); + authorSaved2.getBooks().add(bookSaved2); + + iAuthorRepositroy.save(authorSaved1); + iAuthorRepositroy.save(authorSaved2); + + System.out.println("Bootstrap Data Loaded"); + System.out.println("Number of Authors: " + iAuthorRepositroy.count()); + System.out.println("Number of Books: " + iBookRepository.count()); + } +} + + + + + + diff --git a/src/main/java/guru/springframework/spring6webapp/domain/Author.java b/src/main/java/guru/springframework/spring6webapp/domain/Author.java index 66c9c0f45..a60b50faf 100644 --- a/src/main/java/guru/springframework/spring6webapp/domain/Author.java +++ b/src/main/java/guru/springframework/spring6webapp/domain/Author.java @@ -2,6 +2,7 @@ import jakarta.persistence.*; +import java.util.HashSet; import java.util.Objects; import java.util.Set; @@ -14,7 +15,7 @@ public class Author { private String lastName; @ManyToMany(mappedBy = "authors") // this annotation indicates a many-to-many relationship with the Book entity - private Set books; + private Set books = new HashSet<>(); public Long getIdAuthor() { return idAuthor; diff --git a/src/main/java/guru/springframework/spring6webapp/domain/Book.java b/src/main/java/guru/springframework/spring6webapp/domain/Book.java index 1508018ec..34578ae42 100644 --- a/src/main/java/guru/springframework/spring6webapp/domain/Book.java +++ b/src/main/java/guru/springframework/spring6webapp/domain/Book.java @@ -2,6 +2,7 @@ import jakarta.persistence.*; +import java.util.HashSet; import java.util.Objects; import java.util.Set; @@ -16,7 +17,7 @@ public class Book { @ManyToMany @JoinTable(name ="author_book", joinColumns = @JoinColumn(name = "book_id"), inverseJoinColumns = @JoinColumn(name = "author_id")) // This annotation defines the join table for the many-to-many relationship - private Set authors; + private Set authors = new HashSet<>(); public Long getIdBook() { return idBook; diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 8b1378917..642fb429b 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,2 @@ - +server.port=9090 +//spring.jpa.open-in-view=false \ No newline at end of file From 59287c7eb388b3d15ccf9d58228c9769a63ff27c Mon Sep 17 00:00:00 2001 From: Boutachrafine Date: Sun, 10 Aug 2025 09:45:24 +0100 Subject: [PATCH 6/9] Add Publicher entity --- .../bootstrap/BootstrapData.java | 23 ++++- .../spring6webapp/domain/Publisher.java | 93 +++++++++++++++++++ .../repositories/IPublisher.java | 7 ++ 3 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 src/main/java/guru/springframework/spring6webapp/domain/Publisher.java create mode 100644 src/main/java/guru/springframework/spring6webapp/repositories/IPublisher.java diff --git a/src/main/java/guru/springframework/spring6webapp/bootstrap/BootstrapData.java b/src/main/java/guru/springframework/spring6webapp/bootstrap/BootstrapData.java index e68ed1dd5..f62d79c8c 100644 --- a/src/main/java/guru/springframework/spring6webapp/bootstrap/BootstrapData.java +++ b/src/main/java/guru/springframework/spring6webapp/bootstrap/BootstrapData.java @@ -2,8 +2,10 @@ import guru.springframework.spring6webapp.domain.Author; import guru.springframework.spring6webapp.domain.Book; +import guru.springframework.spring6webapp.domain.Publisher; import guru.springframework.spring6webapp.repositories.IAuthorRepositroy; import guru.springframework.spring6webapp.repositories.IBookRepository; +import guru.springframework.spring6webapp.repositories.IPublisher; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; @@ -12,10 +14,12 @@ public class BootstrapData implements CommandLineRunner { private final IAuthorRepositroy iAuthorRepositroy; private final IBookRepository iBookRepository; + private final IPublisher iPublisher; - public BootstrapData(IAuthorRepositroy iAuthorRepositroy, IBookRepository iBookRepository) { + public BootstrapData(IAuthorRepositroy iAuthorRepositroy, IBookRepository iBookRepository, IPublisher iPublisher) { this.iAuthorRepositroy = iAuthorRepositroy; this.iBookRepository = iBookRepository; + this.iPublisher = iPublisher; } @@ -29,8 +33,16 @@ public void run(String... args) throws Exception { book1.setTitle("Spring Framework 6"); book1.setIsbn("1234567890"); + Publisher publisher = new Publisher(); + publisher.setPublisherName("Spring Books Publishing"); + publisher.setPublisherAddress("123 Spring St"); + publisher.setPublisherCity("Springfield"); + publisher.setPublisherState("Spring State"); + publisher.setPublisherZip("12345"); + Author authorSaved1 = iAuthorRepositroy.save(author1); Book bookSaved1 = iBookRepository.save(book1); + Publisher publisherSaved = iPublisher.save(publisher); Author author2 = new Author(); author2.setFirstName("Tawfiq"); @@ -40,8 +52,16 @@ public void run(String... args) throws Exception { book2.setTitle("Spring Boot 3"); book2.setIsbn("0987654321"); + Publisher publisher2 = new Publisher(); + publisher2.setPublisherName("Spring Boot Books Publishing"); + publisher2.setPublisherAddress("456 Spring Boot St"); + publisher2.setPublisherCity("Spring Boot City"); + publisher2.setPublisherState("Spring Boot State"); + publisher2.setPublisherZip("54321"); + Author authorSaved2 = iAuthorRepositroy.save(author2); Book bookSaved2 = iBookRepository.save(book2); + Publisher publisherSaved2 = iPublisher.save(publisher2); authorSaved1.getBooks().add(bookSaved1); authorSaved2.getBooks().add(bookSaved2); @@ -52,6 +72,7 @@ public void run(String... args) throws Exception { System.out.println("Bootstrap Data Loaded"); System.out.println("Number of Authors: " + iAuthorRepositroy.count()); System.out.println("Number of Books: " + iBookRepository.count()); + System.out.println("Number of Publishers: " + iPublisher.count()); } } diff --git a/src/main/java/guru/springframework/spring6webapp/domain/Publisher.java b/src/main/java/guru/springframework/spring6webapp/domain/Publisher.java new file mode 100644 index 000000000..5fc3d4d09 --- /dev/null +++ b/src/main/java/guru/springframework/spring6webapp/domain/Publisher.java @@ -0,0 +1,93 @@ +package guru.springframework.spring6webapp.domain; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; + +import java.util.Objects; + +@Entity +public class Publisher { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long idPublisher; + private String publisherName; + private String publisherAddress; + private String publisherCity; + private String publisherState; + private String publisherZip; + + public Long getIdPublisher() { + return idPublisher; + } + + public void setIdPublisher(Long idPublisher) { + this.idPublisher = idPublisher; + } + + public String getPublisherName() { + return publisherName; + } + + public void setPublisherName(String publisherName) { + this.publisherName = publisherName; + } + + public String getPublisherAddress() { + return publisherAddress; + } + + public void setPublisherAddress(String publisherAddress) { + this.publisherAddress = publisherAddress; + } + + public String getPublisherCity() { + return publisherCity; + } + + public void setPublisherCity(String publisherCity) { + this.publisherCity = publisherCity; + } + + public String getPublisherState() { + return publisherState; + } + + public void setPublisherState(String publisherState) { + this.publisherState = publisherState; + } + + public String getPublisherZip() { + return publisherZip; + } + + public void setPublisherZip(String publisherZip) { + this.publisherZip = publisherZip; + } + + @Override + public String toString() { + return "Publisher{" + + "idPublisher=" + idPublisher + + ", publisherName='" + publisherName + '\'' + + ", publisherAddress='" + publisherAddress + '\'' + + ", publisherCity='" + publisherCity + '\'' + + ", publisherState='" + publisherState + '\'' + + ", publisherZip='" + publisherZip + '\'' + + '}'; + } + + @Override + public final boolean equals(Object o) { + if (!(o instanceof Publisher publisher)) return false; + + return Objects.equals(getIdPublisher(), publisher.getIdPublisher()); + } + + @Override + public int hashCode() { + return Objects.hashCode(getIdPublisher()); + } +} diff --git a/src/main/java/guru/springframework/spring6webapp/repositories/IPublisher.java b/src/main/java/guru/springframework/spring6webapp/repositories/IPublisher.java new file mode 100644 index 000000000..4ee30c48b --- /dev/null +++ b/src/main/java/guru/springframework/spring6webapp/repositories/IPublisher.java @@ -0,0 +1,7 @@ +package guru.springframework.spring6webapp.repositories; + +import guru.springframework.spring6webapp.domain.Publisher; +import org.springframework.data.repository.CrudRepository; + +public interface IPublisher extends CrudRepository { +} From 64f4accafc25b2b1d9de5e1d8e24ceb9659c44e3 Mon Sep 17 00:00:00 2001 From: Boutachrafine Date: Sun, 10 Aug 2025 10:53:39 +0100 Subject: [PATCH 7/9] Configuring Publisher relationships --- .../bootstrap/BootstrapData.java | 102 +++++++++--------- .../spring6webapp/domain/Book.java | 11 ++ .../spring6webapp/domain/Publisher.java | 9 +- ...blisher.java => IPublisherRepository.java} | 2 +- 4 files changed, 71 insertions(+), 53 deletions(-) rename src/main/java/guru/springframework/spring6webapp/repositories/{IPublisher.java => IPublisherRepository.java} (69%) diff --git a/src/main/java/guru/springframework/spring6webapp/bootstrap/BootstrapData.java b/src/main/java/guru/springframework/spring6webapp/bootstrap/BootstrapData.java index f62d79c8c..e8eb22a5e 100644 --- a/src/main/java/guru/springframework/spring6webapp/bootstrap/BootstrapData.java +++ b/src/main/java/guru/springframework/spring6webapp/bootstrap/BootstrapData.java @@ -5,7 +5,7 @@ import guru.springframework.spring6webapp.domain.Publisher; import guru.springframework.spring6webapp.repositories.IAuthorRepositroy; import guru.springframework.spring6webapp.repositories.IBookRepository; -import guru.springframework.spring6webapp.repositories.IPublisher; +import guru.springframework.spring6webapp.repositories.IPublisherRepository; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; @@ -14,65 +14,71 @@ public class BootstrapData implements CommandLineRunner { private final IAuthorRepositroy iAuthorRepositroy; private final IBookRepository iBookRepository; - private final IPublisher iPublisher; + private final IPublisherRepository iPublisherRepository; - public BootstrapData(IAuthorRepositroy iAuthorRepositroy, IBookRepository iBookRepository, IPublisher iPublisher) { + public BootstrapData(IAuthorRepositroy iAuthorRepositroy, IBookRepository iBookRepository, IPublisherRepository iPublisherRepository) { this.iAuthorRepositroy = iAuthorRepositroy; this.iBookRepository = iBookRepository; - this.iPublisher = iPublisher; + this.iPublisherRepository = iPublisherRepository; } @Override public void run(String... args) throws Exception { - Author author1 = new Author(); - author1.setFirstName("Nabil"); - author1.setLastName("Boutachrafine"); - - Book book1 = new Book(); - book1.setTitle("Spring Framework 6"); - book1.setIsbn("1234567890"); - - Publisher publisher = new Publisher(); - publisher.setPublisherName("Spring Books Publishing"); - publisher.setPublisherAddress("123 Spring St"); - publisher.setPublisherCity("Springfield"); - publisher.setPublisherState("Spring State"); - publisher.setPublisherZip("12345"); - - Author authorSaved1 = iAuthorRepositroy.save(author1); - Book bookSaved1 = iBookRepository.save(book1); - Publisher publisherSaved = iPublisher.save(publisher); - - Author author2 = new Author(); - author2.setFirstName("Tawfiq"); - author2.setLastName("Boutachrafine"); - - Book book2 = new Book(); - book2.setTitle("Spring Boot 3"); - book2.setIsbn("0987654321"); - - Publisher publisher2 = new Publisher(); - publisher2.setPublisherName("Spring Boot Books Publishing"); - publisher2.setPublisherAddress("456 Spring Boot St"); - publisher2.setPublisherCity("Spring Boot City"); - publisher2.setPublisherState("Spring Boot State"); - publisher2.setPublisherZip("54321"); - - Author authorSaved2 = iAuthorRepositroy.save(author2); - Book bookSaved2 = iBookRepository.save(book2); - Publisher publisherSaved2 = iPublisher.save(publisher2); - - authorSaved1.getBooks().add(bookSaved1); - authorSaved2.getBooks().add(bookSaved2); - - iAuthorRepositroy.save(authorSaved1); - iAuthorRepositroy.save(authorSaved2); + + Author nabil = new Author(); // Create a new Author object + nabil.setFirstName("Nabil"); + nabil.setLastName("Boutachrafine"); + + Book b_spring_f6 = new Book(); // Create a new Book object + b_spring_f6.setTitle("Spring Framework 6"); + b_spring_f6.setIsbn("1234567890"); + + Publisher springPublisher = new Publisher(); // Create a new Publisher object + springPublisher.setPublisherName("Spring Books"); + springPublisher.setPublisherAddress("123 Spring St"); + springPublisher.setPublisherCity("Springfield"); + springPublisher.setPublisherState("Spring State"); + springPublisher.setPublisherZip("12345"); + + Author savedNabil = iAuthorRepositroy.save(nabil); // Save the Author object to the repository + Book savedBookSpring6 = iBookRepository.save(b_spring_f6); // Save the Book object to the repository + Publisher savedSpringPublisher = iPublisherRepository.save(springPublisher); // Save the Publisher object to the repository + + Author tawfiq = new Author(); + tawfiq.setFirstName("Tawfiq"); + tawfiq.setLastName("Boutachrafine"); + + Book book_java = new Book(); + book_java.setTitle("Java Programming"); + book_java.setIsbn("0987654321"); + + Publisher javaPublisher = new Publisher(); + javaPublisher.setPublisherName("Java Books"); + javaPublisher.setPublisherAddress("456 Java Ave"); + javaPublisher.setPublisherCity("Java City"); + javaPublisher.setPublisherState("Java State"); + javaPublisher.setPublisherZip("67890"); + + Author savedTawfiq = iAuthorRepositroy.save(tawfiq); // Save the second Author object + Book savedBookJava = iBookRepository.save(book_java); // Save the second Book object + Publisher savedJavaPublisher = iPublisherRepository.save(javaPublisher); // Save the first Publisher object + + savedNabil.getBooks().add(savedBookSpring6); // Add the first book to the first author + savedTawfiq.getBooks().add(savedBookJava); // Add the second book to the second author + + savedBookSpring6.setPublisher(javaPublisher); // Set the publisher for the first book + savedBookJava.setPublisher(savedSpringPublisher); // Set the publisher for the second book + + iAuthorRepositroy.save(savedNabil); // Save the updated first author + iAuthorRepositroy.save(savedTawfiq); // Save the updated second author + iBookRepository.save(savedBookSpring6); // Save the updated first book + iBookRepository.save(savedBookJava); // Save the updated second book System.out.println("Bootstrap Data Loaded"); System.out.println("Number of Authors: " + iAuthorRepositroy.count()); System.out.println("Number of Books: " + iBookRepository.count()); - System.out.println("Number of Publishers: " + iPublisher.count()); + System.out.println("Number of Publishers: " + iPublisherRepository.count()); } } diff --git a/src/main/java/guru/springframework/spring6webapp/domain/Book.java b/src/main/java/guru/springframework/spring6webapp/domain/Book.java index 34578ae42..332d996a8 100644 --- a/src/main/java/guru/springframework/spring6webapp/domain/Book.java +++ b/src/main/java/guru/springframework/spring6webapp/domain/Book.java @@ -19,6 +19,17 @@ public class Book { inverseJoinColumns = @JoinColumn(name = "author_id")) // This annotation defines the join table for the many-to-many relationship private Set authors = new HashSet<>(); + @ManyToOne + private Publisher publisher; + + public Publisher getPublisher() { + return publisher; + } + + public void setPublisher(Publisher publisher) { + this.publisher = publisher; + } + public Long getIdBook() { return idBook; } diff --git a/src/main/java/guru/springframework/spring6webapp/domain/Publisher.java b/src/main/java/guru/springframework/spring6webapp/domain/Publisher.java index 5fc3d4d09..3d0469762 100644 --- a/src/main/java/guru/springframework/spring6webapp/domain/Publisher.java +++ b/src/main/java/guru/springframework/spring6webapp/domain/Publisher.java @@ -1,11 +1,9 @@ package guru.springframework.spring6webapp.domain; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; +import jakarta.persistence.*; import java.util.Objects; +import java.util.Set; @Entity public class Publisher { @@ -19,6 +17,9 @@ public class Publisher { private String publisherState; private String publisherZip; + @OneToMany(mappedBy = "publisher") + private Set books; + public Long getIdPublisher() { return idPublisher; } diff --git a/src/main/java/guru/springframework/spring6webapp/repositories/IPublisher.java b/src/main/java/guru/springframework/spring6webapp/repositories/IPublisherRepository.java similarity index 69% rename from src/main/java/guru/springframework/spring6webapp/repositories/IPublisher.java rename to src/main/java/guru/springframework/spring6webapp/repositories/IPublisherRepository.java index 4ee30c48b..42d8db727 100644 --- a/src/main/java/guru/springframework/spring6webapp/repositories/IPublisher.java +++ b/src/main/java/guru/springframework/spring6webapp/repositories/IPublisherRepository.java @@ -3,5 +3,5 @@ import guru.springframework.spring6webapp.domain.Publisher; import org.springframework.data.repository.CrudRepository; -public interface IPublisher extends CrudRepository { +public interface IPublisherRepository extends CrudRepository { } From 9ce7634410cdc8b3a807d3eb6b656dbabfca6905 Mon Sep 17 00:00:00 2001 From: Boutachrafine Date: Sun, 10 Aug 2025 11:34:38 +0100 Subject: [PATCH 8/9] test with h2 database console --- .../spring6webapp/bootstrap/BootstrapData.java | 6 ++++-- src/main/resources/application.properties | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/guru/springframework/spring6webapp/bootstrap/BootstrapData.java b/src/main/java/guru/springframework/spring6webapp/bootstrap/BootstrapData.java index e8eb22a5e..39606ac82 100644 --- a/src/main/java/guru/springframework/spring6webapp/bootstrap/BootstrapData.java +++ b/src/main/java/guru/springframework/spring6webapp/bootstrap/BootstrapData.java @@ -66,9 +66,11 @@ public void run(String... args) throws Exception { savedNabil.getBooks().add(savedBookSpring6); // Add the first book to the first author savedTawfiq.getBooks().add(savedBookJava); // Add the second book to the second author + savedBookSpring6.getAuthors().add(savedNabil); // Add the first author to the first book + savedBookJava.getAuthors().add(savedTawfiq); // Add the second author to the second book - savedBookSpring6.setPublisher(javaPublisher); // Set the publisher for the first book - savedBookJava.setPublisher(savedSpringPublisher); // Set the publisher for the second book + savedBookSpring6.setPublisher(savedSpringPublisher); // Set the publisher for the first book + savedBookJava.setPublisher(savedJavaPublisher); // Set the publisher for the second book iAuthorRepositroy.save(savedNabil); // Save the updated first author iAuthorRepositroy.save(savedTawfiq); // Save the updated second author diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 642fb429b..6fc169067 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,2 +1,4 @@ server.port=9090 -//spring.jpa.open-in-view=false \ No newline at end of file +//spring.jpa.open-in-view=false +spring.h2.console.enabled=true +spring.datasource.url=jdbc:h2:mem:testdb \ No newline at end of file From 90b16d603eb1cc42296b5e9401b95f2736fc3b31 Mon Sep 17 00:00:00 2001 From: Boutachrafine Date: Sun, 10 Aug 2025 12:10:48 +0100 Subject: [PATCH 9/9] Create Service Layer --- .../services/BookServiceImp.java | 20 +++++++++++++++++++ .../spring6webapp/services/IBookService.java | 7 +++++++ 2 files changed, 27 insertions(+) create mode 100644 src/main/java/guru/springframework/spring6webapp/services/BookServiceImp.java create mode 100644 src/main/java/guru/springframework/spring6webapp/services/IBookService.java diff --git a/src/main/java/guru/springframework/spring6webapp/services/BookServiceImp.java b/src/main/java/guru/springframework/spring6webapp/services/BookServiceImp.java new file mode 100644 index 000000000..fcf156124 --- /dev/null +++ b/src/main/java/guru/springframework/spring6webapp/services/BookServiceImp.java @@ -0,0 +1,20 @@ +package guru.springframework.spring6webapp.services; + +import guru.springframework.spring6webapp.domain.Book; +import guru.springframework.spring6webapp.repositories.IBookRepository; +import org.springframework.stereotype.Service; + +@Service +public class BookServiceImp implements IBookService{ + + private final IBookRepository iBookRepository; + + public BookServiceImp(IBookRepository bookRepository) { + this.iBookRepository = bookRepository; + } + + @Override + public Iterable findAllBooks() { // Implementation to retrieve all books from the database + return iBookRepository.findAll(); + } +} diff --git a/src/main/java/guru/springframework/spring6webapp/services/IBookService.java b/src/main/java/guru/springframework/spring6webapp/services/IBookService.java new file mode 100644 index 000000000..0234f095c --- /dev/null +++ b/src/main/java/guru/springframework/spring6webapp/services/IBookService.java @@ -0,0 +1,7 @@ +package guru.springframework.spring6webapp.services; + +import guru.springframework.spring6webapp.domain.Book; + +public interface IBookService { + public Iterable findAllBooks(); +}