diff --git a/bookstore/src/main/java/com/fjordtek/bookstore/BookstoreApplication.java b/bookstore/src/main/java/com/fjordtek/bookstore/BookstoreApplication.java index df083d2..15c4579 100644 --- a/bookstore/src/main/java/com/fjordtek/bookstore/BookstoreApplication.java +++ b/bookstore/src/main/java/com/fjordtek/bookstore/BookstoreApplication.java @@ -12,6 +12,8 @@ import org.springframework.context.annotation.Bean; import com.fjordtek.bookstore.model.Book; import com.fjordtek.bookstore.model.BookRepository; +import com.fjordtek.bookstore.model.Category; +import com.fjordtek.bookstore.model.CategoryRepository; @SpringBootApplication public class BookstoreApplication extends SpringBootServletInitializer { @@ -22,17 +24,29 @@ public class BookstoreApplication extends SpringBootServletInitializer { } @Bean - public CommandLineRunner bookDatabaseRunner(BookRepository repository) { + public CommandLineRunner bookDatabaseRunner(BookRepository bookRepository, CategoryRepository categoryRepository) { return (args) -> { + + commonLogger.info("Add new categories to database"); + + Category horror = new Category("Horror"); + Category fantasy = new Category("Fantasy"); + categoryRepository.save(horror); + categoryRepository.save(fantasy); + commonLogger.info("Add new sample books to database"); - repository.save(new Book("Book 1 title", "Book 1 author", 2020, "1231231-12", 40.00)); - repository.save(new Book("Book 2 title", "Book 2 author", 2005, "3213221-3", 20.17)); + bookRepository.save(new Book("Book 1 title", "Book 1 author", 2020, "1231231-12", 40.00, horror)); + bookRepository.save(new Book("Book 2 title", "Book 2 author", 2005, "3213221-3", 20.17, fantasy)); commonLogger.info("------------------------------"); + commonLogger.info("Sample categories in the database"); + for (Category category : categoryRepository.findAll()) { + commonLogger.info(category.toString()); + } commonLogger.info("Sample books in the database"); - for (Book book : repository.findAll()) { + for (Book book : bookRepository.findAll()) { commonLogger.info(book.toString()); } diff --git a/bookstore/src/main/java/com/fjordtek/bookstore/model/Book.java b/bookstore/src/main/java/com/fjordtek/bookstore/model/Book.java index 46a083f..f29adb8 100644 --- a/bookstore/src/main/java/com/fjordtek/bookstore/model/Book.java +++ b/bookstore/src/main/java/com/fjordtek/bookstore/model/Book.java @@ -2,6 +2,8 @@ package com.fjordtek.bookstore.model; +import javax.persistence.Column; + //import java.sql.Timestamp; //import javax.validation.constraints.PastOrPresent; @@ -9,6 +11,8 @@ import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; import javax.validation.constraints.DecimalMax; import javax.validation.constraints.DecimalMin; import javax.validation.constraints.Digits; @@ -110,6 +114,9 @@ public class Book { private int year; ////////// + @Column( + unique = true + ) @NotBlank( message = "Fill the ISBN code form" ) @@ -141,6 +148,16 @@ public class Book { // TODO: Use BigDecimal to keep exact precision? private double price; + @ManyToOne( + //fetch = FetchType.LAZY, + optional = false + ) + @JoinColumn( + name = "category_id", + nullable = false + ) + private Category category; + //////////////////// // Attribute setters @@ -171,6 +188,10 @@ public class Book { this.price = price; } + public void setCategory(Category category) { + this.category = category; + } + //////////////////// // Attribute getters @@ -200,6 +221,10 @@ public class Book { return price; } + public Category getCategory() { + return category; + } + //////////////////// // Class constructors @@ -207,11 +232,21 @@ public class Book { public Book(String title, String author, int year, String isbn, double price) { // super(); - this.title = title; - this.author = author; - this.year = year; - this.isbn = isbn; - this.price = price; + this.title = title; + this.author = author; + this.year = year; + this.isbn = isbn; + this.price = price; + } + + public Book(String title, String author, int year, String isbn, double price, Category category) { + // super(); + this.title = title; + this.author = author; + this.year = year; + this.isbn = isbn; + this.price = price; + this.category = category; } //////////////////// @@ -224,7 +259,8 @@ public class Book { "author: " + this.author + ", " + "year: " + this.year + ", " + "isbn: " + this.isbn + ", " + - "price: " + this.price + "]"; + "price: " + this.price + ", " + + "category: " + this.category + "]"; } } diff --git a/bookstore/src/main/java/com/fjordtek/bookstore/model/Category.java b/bookstore/src/main/java/com/fjordtek/bookstore/model/Category.java new file mode 100644 index 0000000..5817051 --- /dev/null +++ b/bookstore/src/main/java/com/fjordtek/bookstore/model/Category.java @@ -0,0 +1,84 @@ +//Pekka Helenius , Fjordtek 2020 + +package com.fjordtek.bookstore.model; + +import java.util.List; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.OneToMany; + +@Entity +public class Category { + + //////////////////// + // Primary key value in database + @Id + @GeneratedValue( + strategy = GenerationType.AUTO + ) + private long id; + + //////////////////// + // Attributes with hard-coded constraints + private String name; + + @OneToMany( + mappedBy = "category" + //fetch = FetchType.LAZY, + //cascade = CascadeType.ALL + ) + private List books; + + //////////////////// + // Attribute setters + + public void setId(long id) { + this.id = id; + } + + public void setName(String name) { + this.name = name; + } + + public void setBooks(List books) { + this.books = books; + } + + //////////////////// + // Attribute getters + + public long getId() { + return id; + } + + public String getName() { + return name; + } + + public List getBooks() { + return books; + } + + //////////////////// + // Class constructors + + public Category() { + } + + public Category(String name) { + this.name = name; + } + + //////////////////// + // Class overrides + + @Override + public String toString() { + return "[" + "id: " + this.id + + "name: " + this.name + "]"; + } + +} \ No newline at end of file diff --git a/bookstore/src/main/java/com/fjordtek/bookstore/model/CategoryRepository.java b/bookstore/src/main/java/com/fjordtek/bookstore/model/CategoryRepository.java new file mode 100644 index 0000000..fbf2364 --- /dev/null +++ b/bookstore/src/main/java/com/fjordtek/bookstore/model/CategoryRepository.java @@ -0,0 +1,14 @@ +//Pekka Helenius , Fjordtek 2020 + +package com.fjordtek.bookstore.model; + +import java.util.List; + +import org.springframework.data.repository.CrudRepository; + +public interface CategoryRepository extends CrudRepository { + + // Handles both INSERT and UPDATE queries + List findById(String name); + +} \ No newline at end of file diff --git a/bookstore/src/main/java/com/fjordtek/bookstore/web/BookController.java b/bookstore/src/main/java/com/fjordtek/bookstore/web/BookController.java index 22a7982..7afdc0b 100644 --- a/bookstore/src/main/java/com/fjordtek/bookstore/web/BookController.java +++ b/bookstore/src/main/java/com/fjordtek/bookstore/web/BookController.java @@ -21,6 +21,7 @@ import org.springframework.web.bind.annotation.ResponseStatus; import com.fjordtek.bookstore.model.Book; import com.fjordtek.bookstore.model.BookRepository; +import com.fjordtek.bookstore.model.CategoryRepository; @Controller public class BookController { @@ -37,6 +38,9 @@ public class BookController { @Autowired private BookRepository bookRepository; + @Autowired + private CategoryRepository categoryRepository; + ////////////////////////////// // LIST PAGE @RequestMapping( @@ -74,7 +78,9 @@ public class BookController { ); Book newBook = new Book(); + dataModel.addAttribute("book", newBook); + dataModel.addAttribute("categories", categoryRepository.findAll()); if (newBook.getYear() == 0) { newBook.setYear(Year.now().getValue()); @@ -150,6 +156,7 @@ public class BookController { Book book = bookRepository.findById(bookId).get(); dataModel.addAttribute("book", book); + dataModel.addAttribute("categories", categoryRepository.findAll()); return bookEditPageURL; } diff --git a/bookstore/src/main/resources/templates/bookadd.html b/bookstore/src/main/resources/templates/bookadd.html index a0209e4..d373b04 100644 --- a/bookstore/src/main/resources/templates/bookadd.html +++ b/bookstore/src/main/resources/templates/bookadd.html @@ -12,31 +12,31 @@
- + Set book author name
Invalid author name
- + Set book primary title
Invalid title
- + Set book ISBN code
Invalid ISBN code
- + Set book publication year
Invalid year
- +
@@ -46,6 +46,17 @@ Set book price
Invalid price
+
+ + + Select appropriate category +
diff --git a/bookstore/src/main/resources/templates/bookedit.html b/bookstore/src/main/resources/templates/bookedit.html index 67f7174..757b595 100644 --- a/bookstore/src/main/resources/templates/bookedit.html +++ b/bookstore/src/main/resources/templates/bookedit.html @@ -46,6 +46,18 @@ Set book price
Invalid price
+ +
+ + + Select appropriate category +
diff --git a/bookstore/src/main/resources/templates/booklist.html b/bookstore/src/main/resources/templates/booklist.html index 9bcad0d..1f66154 100644 --- a/bookstore/src/main/resources/templates/booklist.html +++ b/bookstore/src/main/resources/templates/booklist.html @@ -15,6 +15,7 @@ Title ISBN Year + Category Price Actions @@ -24,6 +25,7 @@ +