diff --git a/bookstore/src/main/java/com/fjordtek/bookstore/BookstoreApplication.java b/bookstore/src/main/java/com/fjordtek/bookstore/BookstoreApplication.java index 98099c9..b0f62cc 100644 --- a/bookstore/src/main/java/com/fjordtek/bookstore/BookstoreApplication.java +++ b/bookstore/src/main/java/com/fjordtek/bookstore/BookstoreApplication.java @@ -69,7 +69,7 @@ public class BookstoreApplication extends SpringBootServletInitializer { } @Bean - @Profile("dev") + @Profile({"dev", "prod"}) public CommandLineRunner userDatabaseRunner( UserRepository userRepository, RoleRepository roleRepository, @@ -153,7 +153,7 @@ public class BookstoreApplication extends SpringBootServletInitializer { } @Bean - @Profile("dev") + @Profile({"dev", "prod"}) public CommandLineRunner bookDatabaseRunner( BookRepository bookRepository, BookHashRepository bookHashRepository, diff --git a/bookstore/src/main/java/com/fjordtek/bookstore/model/auth/Role.java b/bookstore/src/main/java/com/fjordtek/bookstore/model/auth/Role.java index 2c09550..d45c4ee 100644 --- a/bookstore/src/main/java/com/fjordtek/bookstore/model/auth/Role.java +++ b/bookstore/src/main/java/com/fjordtek/bookstore/model/auth/Role.java @@ -13,6 +13,7 @@ import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.SequenceGenerator; +import javax.persistence.Table; import javax.persistence.Transient; /** @@ -26,6 +27,7 @@ import javax.persistence.Transient; */ @Entity +@Table(name = "ROLE") public class Role { //////////////////// diff --git a/bookstore/src/main/java/com/fjordtek/bookstore/model/auth/User.java b/bookstore/src/main/java/com/fjordtek/bookstore/model/auth/User.java index 31196b9..cfd1f0f 100644 --- a/bookstore/src/main/java/com/fjordtek/bookstore/model/auth/User.java +++ b/bookstore/src/main/java/com/fjordtek/bookstore/model/auth/User.java @@ -13,6 +13,7 @@ import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.SequenceGenerator; +import javax.persistence.Table; import javax.persistence.Transient; import javax.validation.constraints.Email; @@ -29,6 +30,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; */ @Entity +@Table(name = "USER") public class User { // TODO define universally in a single place diff --git a/bookstore/src/main/java/com/fjordtek/bookstore/model/auth/UserRole.java b/bookstore/src/main/java/com/fjordtek/bookstore/model/auth/UserRole.java index ecce5fe..a8af4fa 100644 --- a/bookstore/src/main/java/com/fjordtek/bookstore/model/auth/UserRole.java +++ b/bookstore/src/main/java/com/fjordtek/bookstore/model/auth/UserRole.java @@ -6,6 +6,7 @@ import javax.persistence.EmbeddedId; import javax.persistence.Entity; import javax.persistence.ManyToOne; import javax.persistence.MapsId; +import javax.persistence.Table; /** * This class implements UserRole entity which forms @@ -29,6 +30,7 @@ import javax.persistence.MapsId; */ @Entity +@Table(name = "USER_ROLE") public class UserRole { //////////////////// diff --git a/bookstore/src/main/java/com/fjordtek/bookstore/model/book/Author.java b/bookstore/src/main/java/com/fjordtek/bookstore/model/book/Author.java index 98a93f8..ed8873a 100644 --- a/bookstore/src/main/java/com/fjordtek/bookstore/model/book/Author.java +++ b/bookstore/src/main/java/com/fjordtek/bookstore/model/book/Author.java @@ -13,6 +13,7 @@ import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.SequenceGenerator; +import javax.persistence.Table; import javax.validation.constraints.Pattern; import javax.validation.constraints.Size; @@ -30,6 +31,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; */ @Entity +@Table(name = "AUTHOR") public class Author { private static final int strMax = 100; diff --git a/bookstore/src/main/java/com/fjordtek/bookstore/model/book/Book.java b/bookstore/src/main/java/com/fjordtek/bookstore/model/book/Book.java index c1ac1ca..7a7a18c 100644 --- a/bookstore/src/main/java/com/fjordtek/bookstore/model/book/Book.java +++ b/bookstore/src/main/java/com/fjordtek/bookstore/model/book/Book.java @@ -20,6 +20,7 @@ import javax.persistence.ManyToOne; import javax.persistence.OneToOne; import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.SequenceGenerator; +import javax.persistence.Table; import javax.validation.Valid; import javax.validation.constraints.DecimalMax; import javax.validation.constraints.DecimalMin; @@ -47,6 +48,7 @@ import com.fjordtek.bookstore.annotation.CurrentYear; */ @Entity +@Table(name = "BOOK") public class Book { private static final int strMin = 2; diff --git a/bookstore/src/main/java/com/fjordtek/bookstore/model/book/BookHash.java b/bookstore/src/main/java/com/fjordtek/bookstore/model/book/BookHash.java index 9f413fe..10bcfa3 100644 --- a/bookstore/src/main/java/com/fjordtek/bookstore/model/book/BookHash.java +++ b/bookstore/src/main/java/com/fjordtek/bookstore/model/book/BookHash.java @@ -13,6 +13,7 @@ import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToOne; import javax.persistence.PrimaryKeyJoinColumn; +import javax.persistence.Table; import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.Parameter; @@ -44,6 +45,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; */ @Entity +@Table(name = "BOOK_HASH") public class BookHash { @Id diff --git a/bookstore/src/main/java/com/fjordtek/bookstore/model/book/Category.java b/bookstore/src/main/java/com/fjordtek/bookstore/model/book/Category.java index 603d19e..26cc68f 100644 --- a/bookstore/src/main/java/com/fjordtek/bookstore/model/book/Category.java +++ b/bookstore/src/main/java/com/fjordtek/bookstore/model/book/Category.java @@ -13,6 +13,7 @@ import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.SequenceGenerator; +import javax.persistence.Table; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -27,6 +28,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; */ @Entity +@Table(name = "CATEGORY") public class Category { //////////////////// @@ -47,6 +49,7 @@ public class Category { // Attributes with hard-coded constraints @Column( nullable = false, + unique = true, columnDefinition = "NVARCHAR(50)" ) private String name; diff --git a/bookstore/src/main/resources/application-prod.properties b/bookstore/src/main/resources/application-prod.properties new file mode 100644 index 0000000..5ab21ed --- /dev/null +++ b/bookstore/src/main/resources/application-prod.properties @@ -0,0 +1,57 @@ +# Pekka Helenius , Fjordtek 2020 + +# Production configuration + + + +# Persistent database +spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver +spring.datasource.url = jdbc:mysql://127.0.0.1:3306/?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC +spring.datasource.username = +spring.datasource.password = +spring.datasource.initialization-mode = always + +spring.h2.console.enabled = false +spring.jpa.show-sql = false + +# Disable auto-IDs, let SQL server handle them +spring.jpa.hibernate.use-new-id-generator-mappings = false + + + +# Hibernate (& SQL server) table naming strategy + +# NOTE: SQL server // Unix environments +# +# Table names are case sensitive. +# For more information, see +# https://dev.mysql.com/doc/refman/8.0/en/identifier-case-sensitivity.html +# +# Most notable the following part: +# +# "...such (table) names are not case-sensitive in Windows, but are case-sensitive in +# most varieties of Unix. One notable exception is macOS, which is Unix-based +# but uses a default file system type (HFS+) that is not case-sensitive." +# +# If required, configure [mysqld] section in +# SQL server configuration file (Unix: usually /etc/mysql/my.cnf OR /etc/my.cnf), +# especially configuration entry 'lower_case_table_names' +# +# Please remember, when creating table schema (resources/schema.sql), +# and configuring @Table annotation naming scheme for tables, +# consider the following factors: +# +# 1) Target SQL server environment* +# - SQL server naming policy configuration +# - SQL server operating system environment (see reference link & quote above) +# +# 2) Defined letter case used in @Table annotation name parameters in this +# application context. Practically meaning any classes defined as Jakarta +# Persistence entities (classes with @Entity annotations). +# +# *If unsure, contact your SQL server administrator to get required assistance +# for your application configuration. +# +spring.jpa.hibernate.naming.physical-strategy = org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl + +#spring.jpa.hibernate.ddl-auto = validate diff --git a/bookstore/src/main/resources/schema.sql b/bookstore/src/main/resources/schema.sql new file mode 100644 index 0000000..da28f56 --- /dev/null +++ b/bookstore/src/main/resources/schema.sql @@ -0,0 +1,111 @@ +/* + MySQL SQL query script for Bookstore database + Designed for MariaDB RDBMS + + Author: + Pekka Helenius + Fjordtek, 2020 +*/ + +-- ----------------------------------------------------- +-- Used database is defined in resources/application-prod.properties + +-- USE ; + +-- ----------------------------------------------------- +-- Table AUTHOR +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS AUTHOR ( + id INT NOT NULL AUTO_INCREMENT, + firstname NVARCHAR(100) NOT NULL, + lastname NVARCHAR(100) NOT NULL, + PRIMARY KEY (id) +); + +-- ----------------------------------------------------- +-- Table CATEGORY +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS CATEGORY ( + id INT NOT NULL AUTO_INCREMENT, + name NVARCHAR(50) NOT NULL UNIQUE, + PRIMARY KEY (id) +); + +-- ----------------------------------------------------- +-- Table BOOK +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS BOOK ( + id INT NOT NULL AUTO_INCREMENT, + isbn VARCHAR(11) NOT NULL UNIQUE, + price DECIMAL(5,2) NOT NULL, + title NVARCHAR(100) NOT NULL, + year INT NOT NULL, + author_id INT NULL, + category_id INT NULL, + publish BIT NOT NULL, + PRIMARY KEY (id), + FOREIGN KEY (author_id) + REFERENCES AUTHOR (id), + FOREIGN KEY (category_id) + REFERENCES CATEGORY (id) +); + +-- ----------------------------------------------------- +-- Table BOOK_HASH +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS BOOK_HASH ( + book_id INT NOT NULL, + hash_id CHAR(32) NOT NULL UNIQUE, + PRIMARY KEY (book_id), + FOREIGN KEY (book_id) + REFERENCES BOOK (id) +); + +-- ----------------------------------------------------- +-- Table USER +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS USER ( + id INT NOT NULL AUTO_INCREMENT, + username NVARCHAR(100) NOT NULL UNIQUE, + password NVARCHAR(1024) NOT NULL, + email NVARCHAR(100) NOT NULL, + PRIMARY KEY (id) +); + + +-- ----------------------------------------------------- +-- Table ROLE +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS ROLE ( + id INT NOT NULL AUTO_INCREMENT, + name VARCHAR(20) NOT NULL UNIQUE, + PRIMARY KEY (id) +); + +-- ----------------------------------------------------- +-- Table USER_ROLE +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS USER_ROLE ( + user_id INT NOT NULL, + role_id INT NOT NULL, + PRIMARY KEY (user_id, role_id), + FOREIGN KEY (user_id) + REFERENCES USER (id), + FOREIGN KEY (role_id) + REFERENCES ROLE (id) +); + +/* + +Sequenced drop table rules: + +DROP table USER_ROLE; +DROP table ROLE; +DROP table USER; + +DROP table BOOK_HASH; +DROP table BOOK; +DROP table CATEGORY; +DROP table AUTHOR; + +*/