質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.69%
Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

Q&A

2回答

5245閲覧

Spring Bootでデータベースのテーブルを自動生成したい

bunkyoTaro

総合スコア0

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

0グッド

0クリップ

投稿2021/09/06 07:36

前提・実現したいこと

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

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

また依頼した内容が修正された場合は、修正依頼を取り消すようにしましょう。

m.ts10806

2021/09/06 07:43

schema.sql マイグレーションするなら必須では? 何を参考に書かれたのでしょうか(「必要ない」の根拠も知りたい)
bunkyoTaro

2021/09/06 08:19

とある文献では@Entityを書くとテーブルを自動生成するように読み取れたのですがshema.sqlは必要なのですか・・・ Bookクラスを定義しているのでテーブルを自動生成する情報はそろっているような気もするのですが。
m.ts10806

2021/09/06 08:41

「とある」とかでは分かりませんので、名称、urlなど出典を明示してください。間違っていることを書いてたら執筆者に指摘する必要がありますし、質問者さんの理解や環境が合っていない可能性もあります(書いたとおりにしか動かないので)
bunkyoTaro

2021/09/07 00:37

「速習 Spring Boot」です。
m.ts10806

2021/09/07 00:52

こちらは質問への追記修正依頼のコメント欄なので追記は原則質問本文へ。

回答2

2

Spring Boot 2.5から、Spring Data JPAの初期化順序が、変更になりました。

Spring Boot 2.5は、SQL(schema.sql、data.sql) → Hibernate(@Entity)という順序で初期化します。このため、(schema.sqlが無い状態で)data.sqlでデータを入れようとすると、テーブルが無くてエラーになります。

初期化順序を逆(Spring Boot 2.4と同じ)にしたい場合は、以下を設定すると動作するようになります。

properties

1# 初期化順序を、Hibernate → SQLにします 2spring.jpa.defer-datasource-initialization=true

公式のドキュメントだと、こちら(基本的な SQL スクリプトを使用してデータベースを初期化する)が参考になります。

投稿2021/09/06 14:23

編集2021/09/06 14:25
KT001

総合スコア482

sooogle, m.ts10806👍を押しています

下記のような回答は推奨されていません。

  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

また依頼した内容が修正された場合は、修正依頼を取り消すようにしましょう。

1

Spring Data Jpaは使ったことが無いので試してはいませんが…
@Tableのアノテーションは必須の様です。

https://qiita.com/GodMountain/items/638724382b34c52b5ce1

投稿2021/09/06 07:53

Luice

総合スコア766

m.ts10806👍を押しています

下記のような回答は推奨されていません。

  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

また依頼した内容が修正された場合は、修正依頼を取り消すようにしましょう。

回答へのコメント

bunkyoTaro

2021/09/06 08:11

@Entity の直後に、 @Table(name="Book") を追記しても動きません。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.69%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

同じタグがついた質問を見る

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。