前提・実現したいこと
Spring Tool Suite4を使用してデータベース(H2)操作がしたい。
起動時に自動でテーブル作成、データを挿入、Springアプリケーション実行でWEBページに表示させるプログラムを作りたい。
本来はaplication.propatiesとBook.javaの内容だけでデータベースと連携させたい。
以下のコードだけでは「テーブル "BOOK" が見つかりません」というエラーが出る。
ModelのBook.javaの@Entityや@Getter/Setterがうまく動作していない。
本来はschema.sqlは必要ないはずなのに、書かないと動作しない。
*schema.sqlなしの場合 ---------------------------------------------------------------------------------------------------------------------------------------------------------- org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scriptDataSourceInitializer' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceInitializationConfiguration$SharedCredentialsDataSourceInitializationConfiguration.class]: Invocation of init method failed; nested exception is org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement #1 of URL [file:/D:/pleiades/spring/QuickMaster/target/classes/data.sql]: INSERT INTO book(id, isbn, title, price, publisher, published, attach) VALUES(1, '978-4-7981-6364-2','独習Python', 3000, '翔泳社', '2020-06-22', 'dl'); nested exception is org.h2.jdbc.JdbcSQLSyntaxErrorException: テーブル "BOOK" が見つかりません Table "BOOK" not found; SQL statement: INSERT INTO book(id, isbn, title, price, publisher, published, attach) VALUES(1, '978-4-7981-6364-2','独習Python', 3000, '翔泳社', '2020-06-22', 'dl') [42102-200] Caused by: org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement #1 of URL [file:/D:/pleiades/spring/QuickMaster/target/classes/data.sql]: INSERT INTO book(id, isbn, title, price, publisher, published, attach) VALUES(1, '978-4-7981-6364-2','独習Python', 3000, '翔泳社', '2020-06-22', 'dl'); nested exception is org.h2.jdbc.JdbcSQLSyntaxErrorException: テーブル "BOOK" が見つかりません Table "BOOK" not found; SQL statement: INSERT INTO book(id, isbn, title, price, publisher, published, attach) VALUES(1, '978-4-7981-6364-2','独習Python', 3000, '翔泳社', '2020-06-22', 'dl') [42102-200] Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: テーブル "BOOK" が見つかりません Table "BOOK" not found; SQL statement: INSERT INTO book(id, isbn, title, price, publisher, published, attach) VALUES(1, '978-4-7981-6364-2','独習Python', 3000, '翔泳社', '2020-06-22', 'dl') [42102-200] ---------------------------------------------------------------------------------------------------------------------------------------------------------- *Book.javaにGetter/Setter記述なしの場合 ---------------------------------------------------------------------------------------------------------------------------------------------------------- org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates/list.html]") Caused by: org.attoparser.ParseException: Exception evaluating SpringEL expression: "b.isbn" (template: "list" - line 19, col 7) Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "b.isbn" (template: "list" - line 19, col 7) Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'isbn' cannot be found on object of type 'to.msn.wings.quickmaster.models.Book' - maybe not public or not valid? org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'isbn' cannot be found on object of type 'to.msn.wings.quickmaster.models.Book' - maybe not public or not valid?
AplicationPropaties
1spring.datasource.driver-class-name=org.h2.Driver 2spring.datasource.url=jdbc:h2:mem:quickmaster 3spring.datasource.username=quickusr 4spring.datasource.password=quickpass 5spring.datasource.sql-script-encoding=UTF-8 6spring.datasource.initialization-mode=always 7spring.datasource.schema=classpath:schema.sql 8spring.jpa.hibernate.ddl-auto=update 9spring.jpa.show-sql=true
//QuickMasterApplication.java package to.msn.wings.quickmaster; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class QuickMasterApplication { public static void main(String[] args) { SpringApplication.run(QuickMasterApplication.class, args); } }
//HelloController.java package to.msn.wings.quickmaster.controllers; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import to.msn.wings.quickmaster.models.BookRepository; // a. コントローラークラスを定義 @Controller public class HelloController { // リポジトリを格納するためのプライベートフィールド private BookRepository rep; // a. コンストラクターにリポジトリを注入 @Autowired public HelloController(BookRepository rep) { this.rep = rep; } //b. 書籍一覧を生成するためのHandlerメソッド @GetMapping("/list") public String list(Model model) { model.addAttribute("books", rep.findAll()); return "list"; } }
//Book.java package to.msn.wings.quickmaster.models; import java.time.LocalDate; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import lombok.Getter; import lombok.Setter; @Getter @Setter //a.エンティティの宣言 @Entity public class Book { //b.テーブルの列を列挙 //c.主キー @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; //ISBNコード @Column(name="isbn", nullable = false) private String isbn; //署名 @Column(name="title", nullable = true) private String title; //価格 @Column(name="price", nullable = false) private int price; //出版社 @Column(name="publisher", nullable = false) private String publisher; //刊行日 @Column(name="published", nullable = false) private LocalDate published; //付属品 @Column(name="attach", nullable = true) private String attach; }
//BookRepository.java package to.msn.wings.quickmaster.models; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface BookRepository extends JpaRepository<Book, Integer> { }
<!-- list.html !--> <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"> <title>title</title> </head> <body> <table class="table"> <thead> <tr> <th>ISBNコード</th><th>書名</th><th>価格</th><th>出版社</th><th>刊行日</th> </tr> </thead> <tbody> <tr th:each="b : ${books}"> <td>[[${b.isbn}]]</td> <td>[[${b.title}]]</td> <!--b. 数値を加工--> <td>[[${#numbers.formatInteger(b.price, 3, 'COMMA')}]]円</td> <td>[[${b.publisher}]]</td> <!--c. 日付を加工--> <td>[[${#temporals.format(b.published, 'yyyy年MM月dd日')}]]</td> </tr> </tbody> </table> </body> </html>
/* data.sql */ INSERT INTO book(id, isbn, title, price, publisher, published, attach) VALUES(1, '978-4-7981-6364-2','独習Python', 3000, '翔泳社', '2020-06-22', 'dl'); /* 以下略 */
試したこと
QuickMasterApplication.javaを実行
以下のようにすれば動く
・src/main/resourseフォルダにschema.sqlファイルを作成し、テーブル情報を設定 → テーブルが作成された
・Book.javaファイルにGetter/Setterの記述を追加 → データアクセスが成功、WEBページに表示された
本当はテーブルを自動生成したい
補足情報(FW/ツールのバージョンなど)
・Java SE 11
・Spring Boot 2.5.4
・Spring Tool Suite4 4.11.1
・Eclipse 4.18.0
・H2 database 1.4.20
・Thymeleaf 3.0.12
・Tomcat 9.0.52
・Lombok 1.18.20
・Spring Data JPA 2.5.4