0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Spring Boot で @sql の executionPhase にハマった

Last updated at Posted at 2025-02-08

はじめに

Spring Boot でUnitテストを書いていた際に、executionPhase を使ってハマったことを残します。

バージョン

Spring Boot 3.4.2

ハマったこと

@Sql(executionPhase = ExecutionPhase.BEFORE_TEST_CLASS)

を付けたらトランザクションがコミットされることに気づかなかった。

経緯

クラスに@Sqlを書けば1回だけデータ投入され、各UTケース(メソッド)で利用できるかな、と思っていました。

動かしてみると、各ケースごとに@Sqlのデータ投入が動いていることに気づきました。

org.springframework.jdbc.datasource.init のログレベルをDEBUGにして実行結果を確認。

logging:
  level:
    '[org.springframework.jdbc.datasource.init]': DEBUG
@SpringBootTest
@Transactional
@Sql
public class DemoTest {

	@Test
	void test1() {
		System.out.println("test1");
	}

	@Test
	void test2() {
		System.out.println("test2");
	}

}

2回、@SqlのSQL(DemoTest.sql)が実行されています。

2025-02-02T12:50:30.509+09:00 DEBUG 3664 --- [spring-boot-ut] [           main] o.s.jdbc.datasource.init.ScriptUtils     : Executing SQL script from class path resource [com/example/demo/DemoTest.sql]
2025-02-02T12:50:30.540+09:00 DEBUG 3664 --- [spring-boot-ut] [           main] o.s.jdbc.datasource.init.ScriptUtils     : 0 returned as update count for SQL: CREATE TABLE IF NOT EXISTS m_class ( id INT auto_increment PRIMARY KEY, name VARCHAR(50) )
2025-02-02T12:50:30.549+09:00 DEBUG 3664 --- [spring-boot-ut] [           main] o.s.jdbc.datasource.init.ScriptUtils     : 1 returned as update count for SQL: INSERT INTO m_class(name) VALUES('DemoTest')
2025-02-02T12:50:30.551+09:00 DEBUG 3664 --- [spring-boot-ut] [           main] o.s.jdbc.datasource.init.ScriptUtils     : Executed SQL script from class path resource [com/example/demo/DemoTest.sql] in 40 ms.

~~ 中略 ~~

2025-02-02T12:50:31.354+09:00 DEBUG 3664 --- [spring-boot-ut] [           main] o.s.jdbc.datasource.init.ScriptUtils     : Executing SQL script from class path resource [com/example/demo/DemoTest.sql]
2025-02-02T12:50:31.354+09:00 DEBUG 3664 --- [spring-boot-ut] [           main] o.s.jdbc.datasource.init.ScriptUtils     : 0 returned as update count for SQL: CREATE TABLE IF NOT EXISTS m_class ( id INT auto_increment PRIMARY KEY, name VARCHAR(50) )
2025-02-02T12:50:31.355+09:00 DEBUG 3664 --- [spring-boot-ut] [           main] o.s.jdbc.datasource.init.ScriptUtils     : 1 returned as update count for SQL: INSERT INTO m_class(name) VALUES('DemoTest')
2025-02-02T12:50:31.355+09:00 DEBUG 3664 --- [spring-boot-ut] [           main] o.s.jdbc.datasource.init.ScriptUtils     : Executed SQL script from class path resource [com/example/demo/DemoTest.sql] in 1 ms.

どうせなら1回だけいいかな?と思い、以下を発見。付与してみたら1回だけに変わりました。

@Sql(executionPhase = ExecutionPhase.BEFORE_TEST_CLASS)

が!トランザクションがコミットされるようになってしまいました。

org.springframework.jdbc.support.JdbcTransactionManager のログレベルをDEBUGにして確認。

logging:
  level:
    '[org.springframework.jdbc.datasource.init]': DEBUG
    '[org.springframework.jdbc.support.JdbcTransactionManager]': DEBUG
2025-02-02T13:01:33.027+09:00 DEBUG 16396 --- [spring-boot-ut] [           main] o.s.jdbc.support.JdbcTransactionManager  : Initiating transaction commit

UTが複数クラスあると、1個目のUTクラスの@Sqlのデータが残り、2個目のUTクラスの実行時に意図しない動きをしてしまいました。

加えてUTクラス単位でデータが繋がってしまうのはよくない。と。

結果

ExecutionPhase.BEFORE_TEST_CLASS をやめて、ケース(メソッド)毎実行する方法に戻しました。

サンプルソース

0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?