[SpringBoot]JPA rollbackは使用できません


ケース

  • MySQLに関連付けられた簡単なメンバーRepositoryを作成し、ユニットテストを行います.

  • save methodをテストしました->テストは成功しましたが、データベースにデータが残っています-->ロールバックできません.

  • データベースに@Transactionalはありません(サービスグループ用)

  • でもTest classに@Transactionalコメントしたので、ロールバックが楽しみです.
  • Spring Bootを使用中
  • if we're using a Spring Boot project and have a spring-data-* or spring-tx dependencies on the classpath, then transaction management will be enabled by default.
  • 転送なし
    @Repository
    @RequiredArgsConstructor
    public class MemberRepositoryDB implements MemberRepository {
        // final -> 선언과 동시 초기화 or Constructor에서 초기화 필요
        // @RequiredArgsConstructor 를 통해 해결
        // Service 계층에서 @Transactional을 할 것임
        private final EntityManager em ;
    
        @Override
        public void save(Member member) {
            em.persist(member);
        }
    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest
    @Transactional
    class MemberRepositoryDBTest {
    
        @Autowired EntityManager em; // test method 내에서 assert로 확인하려고
        @Autowired MemberRepository memberRepository; // @Repository 로 인해 Component scan되어 bean으로 등록되어있는 MemberRepostiroy를 가 주입
    
    
        @Test
        void save() {
    原因:MyISAMストレージエンジン+方言問題
  • MySQLでは、通常、MySAMおよびInnoDBストレージエンジンが使用されます.
  • この記事では,MyISAMとInnoDB Engineの違いを簡単に理解した.
    MyISAMエンジンInnoDBエンジン?tableのストレージエンジンの変更
  • 現在の問題は、MYISAMがTractionをサポートしていないようだ.
  • しかし、問題は、SpringBootで生成されたテーブル自体がMyISAM Engineで生成されていることです.
    Hibernate:Mysql MyISAMテーブルの作成
    HibernateはどのようにMyISAM Engine Tableを作成しますか?
    application.属性の変更
    spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/rest
    spring.datasource.username=user_name
    spring.datasource.password=password
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    spring.jpa.database=mysql
    spring.jpa.hibernate.ddl-auto=create
    spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
    spring.jpa.show-sql: true
    ここで方言の部分を変更します
    hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
    110 InnoDBエンジンテーブルが生成されました
  • テストに合格し、ロールバックし、データベースに残りのデータがないことを確認します.
  • 生成されたテーブルがInnoDBエンジンを使用していることも確認できます.
    Hibernate: create table members (member_id bigint not null auto_increment, email varchar(255), name varchar(255), primary key (member_id)) engine=InnoDB
    その他:MySQL 5 InnoDBdialectは破棄されました
    The MySQL Dialect refactoringを見ると2017年の記事ですが、MySQL 5 InnoDDialectが廃止されたとの声がありました.
    そこで、私はこのようにすることを提案する文章を見ました.
    spring.jpa.properties.hibernate.dialect.storage_engine=innodb
    spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
    ❌そうするとMYISAM tableも生成されます.
    したがって
    spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL55Dialect
    に変更
    110 InnoDBエンジンテーブルが生成されました
    Hibernate: create table members (member_id bigint not null auto_increment, email varchar(255), name varchar(255), primary key (member_id)) engine=InnoDB
    
    現在のDBバージョンに適した方言を見つけます.
  • 方言は通常db name+バージョンです.現在のバージョンに最も近い
  • を選択
  • MySQLはこれらの要求に詳しいと言われています.
  • mysqldialect->過去バージョン5.x前
  • mysql5dialect -> 5.xバージョン
  • 最新DBには、次のものがあります.
    MySQL 55 Dialect 5.5版
    MySQL 57 Dialect 5.7版
    選択すればいいです.