LoginSignup
3
0

More than 1 year has passed since last update.

Spring Boot 2.5でdata.sqlを使ってデータ初期化を行う際の注意点

Posted at

前提

先日、以下を使って簡単なアプリを作ろうとしました。

  • Spring Boot 2.5
  • JPA
  • H2 Database
  • data.sql
Item.java
package com.example.domain;

import java.io.Serializable;

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.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name="items")
public class Item implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private Integer price;
}

data.sql
INSERT INTO items(name, price) VALUES('りんご', 100);
INSERT INTO items(name, price) VALUES('ばなな', 50);
INSERT INTO items(name, price) VALUES('ぶどう', 200);

起こった事象

Item.javaからJPAで自動生成された「items」というテーブルにただただデータを突っ込んでいくだけのDMLなのですが、以下のエラーが発生しました。

Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: テーブル "items" が見つかりません
Table "items" not found; SQL statement:
INSERT INTO items(name, price) VALUES('りんご', 100) [42102-200]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:453) ~[h2-1.4.200.jar:1.4.200]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:429) ~[h2-1.4.200.jar:1.4.200]
    at org.h2.message.DbException.get(DbException.java:205) ~[h2-1.4.200.jar:1.4.200]
    at org.h2.message.DbException.get(DbException.java:181) ~[h2-1.4.200.jar:1.4.200]
    at org.h2.command.Parser.readTableOrView(Parser.java:7628) ~[h2-1.4.200.jar:1.4.200]
    at org.h2.command.Parser.readTableOrView(Parser.java:7599) ~[h2-1.4.200.jar:1.4.200]
    at org.h2.command.Parser.parseInsert(Parser.java:1747) ~[h2-1.4.200.jar:1.4.200]
    at org.h2.command.Parser.parsePrepared(Parser.java:954) ~[h2-1.4.200.jar:1.4.200]
    at org.h2.command.Parser.parse(Parser.java:843) ~[h2-1.4.200.jar:1.4.200]
    at org.h2.command.Parser.parse(Parser.java:815) ~[h2-1.4.200.jar:1.4.200]
    at org.h2.command.Parser.prepareCommand(Parser.java:738) ~[h2-1.4.200.jar:1.4.200]
    at org.h2.engine.Session.prepareLocal(Session.java:657) ~[h2-1.4.200.jar:1.4.200]
    at org.h2.engine.Session.prepareCommand(Session.java:595) ~[h2-1.4.200.jar:1.4.200]
    at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1235) ~[h2-1.4.200.jar:1.4.200]
    at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:212) ~[h2-1.4.200.jar:1.4.200]
    at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:201) ~[h2-1.4.200.jar:1.4.200]
    at net.sf.log4jdbc.StatementSpy.execute(StatementSpy.java:839) ~[log4jdbc-remix-0.2.7.jar:na]
    at com.zaxxer.hikari.pool.ProxyStatement.execute(ProxyStatement.java:94) ~[HikariCP-4.0.3.jar:na]
    at com.zaxxer.hikari.pool.HikariProxyStatement.execute(HikariProxyStatement.java) ~[HikariCP-4.0.3.jar:na]
    at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java:261) ~[spring-jdbc-5.3.10.jar:5.3.10]
    ... 28 common frames omitted

INSERTするにも、「items」テーブルがないから無理よとのことだったのですが、JPAで自動生成してくれるはずなのに!と途方に暮れていたらどうやらSpring Boot 2.5からdata.sqlが読み込まれるタイミングが変わったようです。

By default, data.sql scripts are now run before Hibernate is initialized. This aligns the behavior of basic script-based initialization with that of Flyway and Liquibase. If you want to use data.sql to populate a schema created by Hibernate, set spring.jpa.defer-datasource-initialization to true. While mixing database initialization technologies is not recommended, this will also allow you to use a schema.sql script to build upon a Hibernate-created schema before it’s populated via data.sql.

Spring Boot 2.5 Release Notes

リリースノートには「Hibernateの初期化される前にdata.sql実行されるから気をつけや〜!」と書かれております。

解決方法

Hibernateの初期化前に実行されるように変更するには、application.propertiesspring.jpa.defer-datasource-initialization=trueを追加するといいみたいです。

application.properties
spring.jpa.defer-datasource-initialization=true

よかったよかった〜!

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0