월 19,800원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결스프링 DB 2편 - 데이터 접근 활용 기술
Mybatis 학습을 위해 실행 도중 오류에 대한 해결방법이 궁금합니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]프로젝트를 따라 실행하며 학습하기위해itemservice-db 프로젝트를 받아 실행해봤지만앞서 학습내용을 건너 뛴 탓에 에러가 떴습니다.처음엔 H2가 실행되어있지 않는 오류로 떠서 해결하고보니 이런 오류가 뜹니다..테이블 ITEM 이 없다는 내용같은데앞에 강의내용을 건너뛰고 Mybatis 부분을 학습하고 싶은데 (지금 공부에 목표가 Mybatis 라서 해결 후에 완강을 해야겠다고 목표하고 있습니다.)영한님의 강의에서 Mybatis 부분을 문제없이 듣고 따라하기 위해선 어떤부분을 빠르게 수정해야 하는지 알려주시면 감사하겠습니다.
- 해결됨스프링 DB 2편 - 데이터 접근 활용 기술
실무에서의 @Column 명시
안녕하세요 좋은 강의 잘 듣고 있습니다. @Entity 에서 각 필드들을 정의할 때@Column 으로 컬럼 매핑을 하잖아요?그런데 사실 @Column 으로 하나하나 명세를 쓰지 않아도 동작을 하는 실무 프로젝트들을 해왔는데, 물론 회사, 팀마다 다 다르겠지만 흔히 말하는 빅테크 에서는 @Column 들을 다 명세해주는 경향인지 궁금합니다. 또는 플러그인으로 DB에서 자동으로 읽어와서 붙여주는 기능도 있다고 알고 있습니다. 감사합니다.
- 해결됨스프링 DB 2편 - 데이터 접근 활용 기술
jdbcTemplate, mybatis
안녕하세요 mybatis 대신 jdbcTemplate을 사용하는 이유가 궁금합니다. 밑의 질문 답변에서 Jpa의 @Query 사용하는 것 말고 Dto를 변환하는 과정에서 JdbcTemplate의 편리한 기능이 있다고 말씀하셨는데요.그런데 MyBatis 도 편리하게 Dto로 결과 반환을 할 수 있다는 점에서 마찬가지 아닌가요? MyBatis는 Mapper 매핑 등 여러가지 설정이 필요한 반면에, JdbcTemplate은 스프링 부트 기본 라이브러리에 포함되어 있고 간편해서 그런가요? 감사합니다.
- 해결됨스프링 DB 2편 - 데이터 접근 활용 기술
build.gradle 버전 명시
안녕하세요 질문이 있습니다. 스프링이 공식적으로 지원하는 라이브러리인지 아닌지는 어떻게 판단하나요?(버전 명시 유무)mybatis는 패키지 구조만 봤을 때 바로 스프링에 소속된 것이 아닌 것을 알 수 있는데(그래서 버전명시), h2랑 lombok 같은 경우도 org.springframework 하위에 속하지 않은 것으로 봤을 때는 스프링에서 공식 지원 라이브러리가 아닌 것처럼 보여서요. 감사합니다.
- 미해결스프링 DB 2편 - 데이터 접근 활용 기술
테스트에서 h2 인메모리 방식 위한 라이브러리 추가
안녕하세요. 2가지가 궁금합니다.테스트에서 자동으로 h2 인메모리 방식을 사용하고 싶다면test의 dataSource등록을 하지 않고(application.properties 에 datasource 설정도 X) && @Transactional 사용 하면 되는것이죠? (@Transactional 을 넣지 않으니 로그에 h2 인메모리로 생성되지 않더라구요) 1번방식으로 사용하기 위해서는(수업처럼) build.gradle(또는 pom.xml) 에 반드시 h2 라이브러리를 추가해야 하나요? 감사합니다.
- 미해결스프링 DB 2편 - 데이터 접근 활용 기술
인메모리 DB h2
안녕하세요 좋은 강의 감사합니다! 보통 h2 데이터베이스를 인메모리 DB라고 하잖아요?그 '인메모리' 방식이 이번 임베디드 모드 DB에서 jvm 안에 메모리 로 동작한다는 의미인가요? 그러면 이전 시간까지 ./h2.sh 로 실행을 해서 했던 방식은 서버(test.mv.db, testcase.mv.db)로 실행한 방식 맞을까요? 답변 미리 감사드립니다.
- 해결됨스프링 DB 2편 - 데이터 접근 활용 기술
트랜잭션 전파에 있어 트랜잭션 매니저
스프링 트랜잭션 전파에 있어서, 외부 트랜잭션이 수행중이고 아직 끝나지 않았는데 내부 트랜잭션이 수행 된다면, 트랜잭션 코드는 각각 트랜잭션 매니저를 통해서 신규 트랜잭션인지 확인을 하고 트랜잭션을 시작하는 과정을 거치는 것이라 이해했습니다.강의 자료 그림에서 본다면, 외부 트랜잭션코드와 내부 트랜잭션 코드가 서로 다른 트랜잭션 매니저로 부터 트랜잭션을 시작하는 것 처럼 표현되어 있는데, 이것은 같은 트랜잭션 매니저 아닌가요? definition이 다른 것일뿐.. 헷갈려서 질문 남겨 봅니다.또한, DB 1편부터 들었던 의문인데, service 레이어에서 트랜잭션을 시작하면 트랜잭션 동기화 매니저에 넣어두고, 레포지토리에서는 트랜잭션 동기화 매니저로 부터 해당 connection을 꺼내서 해결하는데, 트랜잭션 동기화 매니저는 spring bean으로, singleton으로 자동 등록되어 있는건가요?답변 부탁드립니다! 감사합니다.
- 미해결스프링 DB 2편 - 데이터 접근 활용 기술
src/test 의 application.properties 문제
https://www.inflearn.com/questions/667899 의 질문과 유사한 문제가 해결되지 않아 재질문 드립니다.현재 저의 개발환경은os : macide: vscodespringboot : 3.0.4를 사용하고 있습니다.개발환경과 테스트 환경을 분리하기 위해서, src/main/resource 와 src/test/resource 에 각각 application.properties 파일을 만들고, 내부에 spring.profiles.active=localspring.profiles.active=test 라고 작성한 상태입니다. (강의와 동일하게 수행)그런데, 실제 테스트 실행 시, 여전히 로그에는The following 1 profile is active: "local" 이 나옵니다.동일한 질문에 답글로 달려있는 @ActiveProfiles("test")를 class에 붙여 실행하게 되면, 로그는The following 1 profile is active: "test"라고 나오지만, 그 외의 다른 설정(데이터베이스 설정)은 여전히 src/main/resource 에 있는 application.properties를 사용합니다. 혹시 문제를 해결할 수 있는 방법이 있으면 알려주시면 좋겠습니다. 부탁드립니다.
- 미해결스프링 DB 2편 - 데이터 접근 활용 기술
우선 해야하는 테스트 방식이 궁금합니다.
안녕하세요 :)평소 영한님 강의를 통해 많은 가르침을 받고 있는 주니어 개발자입니다.만약 별도 Test DB 없이 Service 계층 테스트를 한다면,크게 다음과 같은 세가지 테스트 방식이 있는 것으로 이해하였습니다!Service 테스트에 @Transactional 추가하여, 테스트 수행 후 롤백실제 DB에 수행하므로, insert시 유니크한 컬럼에 대해 이미 동일 데이터가 존재한다면 테스트 실패Repository 의존성을 Mock 처리Mock을 통해 행위를 검증하게되므로 보다 깨지기 쉬운 테스트가됨임베디드 DB에 테스트 수행임베디드 DB와 운영환경 DB의 차이점이 있을 수 있음 세가지 방식 모두 각자의 트레이드오프가 있을 것 같은데요.권장되는 방식이나, 주로 사용하시는 테스트 방식이 궁금합니다.
- 해결됨스프링 DB 2편 - 데이터 접근 활용 기술
6:58초에서 log로 왜 proxy가 찍히는건지 잘 모르겠습니다..
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]잘 이해가 안되어 질문 남깁니다. test에 있는 itemRepository는 bean으로 Config 파일을 통해서 주입시킨 JpaRepository 객체가 autowired 통해서 들어왔는데, 왜 프록시 객체가 로그로 찍히나요?repository의 프록시는 서비스 레이어 넘기기 전, 예외 변경기능만 하는 것 아닌가요? itemRepository에 주입된 객체가 왜 repository의 프록시 객체인지가 궁금합니다.. save()같은 repository안의 메서드에서 예외가 발생하여 service로 넘어갈때 프록시 객체가 적용되어야 하는것 아닌가요?헷갈려서 질문남깁니다..감사합니다.
- 미해결스프링 DB 2편 - 데이터 접근 활용 기술
다중 데이터베이스 트랜잭션 설정
안녕하세요. 궁금한 부분이 있어 질문 올립니다.여러 개의 데이터베이스와 연동할 경우, 각각의 DataSource에 대한 트랜잭션 매니저를 만들어줘야 하나요 아니면 하나의 트랜잭션 매니저를 사용해야 하나요?사용하는 데이터 접근 기술은 마이바티스이며, 데이터베이스는 모두 SQL SERVER를 사용합니다
- 미해결스프링 DB 2편 - 데이터 접근 활용 기술
JdbcTemplate queryForMap 관련 질문이있습니다.
공부를 하다보니 궁금한게 있어서 질문 드립니다.만약JdbcTemplate를 사용해서sql = "select * from Table where id = :id";sql로 특정 id의 값을 사용해 테이블 값을 가져오고Map<String, Object> param = Map.of("id", id); 으로 정의하고Map<String, Obeject> result = template.queryForMap(sql, param);을 했을시에Object에는 sql문을 사용해서 검색한 데이터들이 들어가는 걸로 이해를 했는데그러면 String이라고 정해둔 key값에는 무엇이 들어가나요??
- 미해결스프링 DB 2편 - 데이터 접근 활용 기술
프로필 설정
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]ItemServiceApplication을 실행해야 TestDataInit이 빈으로 등록되어 초기 데이터가 저장되는 것 아닌가요?그렇다면 테스트 코드 실행시 TestDataInit이 빈으로 등록되지 않아서 초기 데이터가 저장되지 않을 것 같은데 TestDataInit의 프로필 설정을 따로 하는 이유가 뭔가요??잘못 알고 있는 부분이 있다면 피드백 부탁드립니다.
- 미해결스프링 DB 2편 - 데이터 접근 활용 기술
MyBatis 테스트 오류 질문입니다
MyBatis 적용2 - 설정과 실행 부분 테스트 오류 발생해서 질문 드립니다JdbcTemplateV3 까지 잘 되었는데 MyBatis 적용하면 오류 발생합니다.MyBatis 관련된 모든 Bean 들이 생성안된 것 같아요. 오류 로그가 너무 길어서 일부만 첨부드립니다 java.lang.IllegalStateException: Failed to load ApplicationContextCaused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'itemController' defined in fileCaused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'hello.itemservice.config.MyBatisConfig':Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'itemMapper'Caused by: java.lang.ClassNotFoundException: Cannot find class: Item =======ItemMapper.xml=========<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="hello.itemservice.repository.mybatis.ItemMapper"> <insert id="save" useGeneratedKeys="true" keyProperty="id"> insert into item (item_name, price, quantity) values (#{itemName}, #{price}, #{quantity}) </insert> <update id="update"> update item set item_name = #{updateParam.itemName}, price = #{updateParam.price}, quantity = #{updateParam.quantity} where id = #{id} </update> <select id="findById" resultType="Item"> select id, item_name, price, quantity from item where id = #{id} </select> <select id="findAll" resultType="Item"> select id, item_name, price, quantity from item <where> <if test="itemName != null and itemName != ''"> and item_name like concat('%',#{itemName},'%') </if> <if test="maxPrice != null"> and price <= #{maxPrice} </if> </where> </select> </mapper>
- 미해결스프링 DB 2편 - 데이터 접근 활용 기술
@TestConfiguration 유무 차이 질문
안녕하세요, 코드 실행중에 질문이 있어 문의 드립니다.package hello.springtx.propagation; import lombok.extern.slf4j.Slf4j; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.UnexpectedRollbackException; import org.springframework.transaction.interceptor.DefaultTransactionAttribute; import javax.sql.DataSource; import static org.assertj.core.api.Assertions.*; @SpringBootTest @Slf4j public class BasicTxTest { @Autowired PlatformTransactionManager txManager; @TestConfiguration static class Config{ @Bean public PlatformTransactionManager transactionManager(DataSource dataSource){ return new DataSourceTransactionManager(dataSource); } } @Test void commit(){ log.info("트랜잭션 시작"); TransactionStatus status = txManager.getTransaction(new DefaultTransactionAttribute()); log.info("트잭 커밋 시작"); txManager.commit(status); log.info("트잭 커밋 완료"); } @Test void rollback(){ log.info("트랜잭션 시작"); TransactionStatus status = txManager.getTransaction(new DefaultTransactionAttribute()); log.info("트잭 롤백 시작"); txManager.rollback(status); log.info("트잭 롤백 완료"); } @Test void double_commit(){ log.info("트랜(1) 시작"); TransactionStatus status1 = txManager.getTransaction(new DefaultTransactionAttribute()); log.info("트랜(1) 커밋"); txManager.commit(status1); log.info("트랜(2) 시작"); TransactionStatus status2 = txManager.getTransaction(new DefaultTransactionAttribute()); log.info("트랜(2) 커밋"); txManager.commit(status2); } @Test void double_commit_rollback() { log.info("트랜잭션1 시작"); TransactionStatus tx1 = txManager.getTransaction(new DefaultTransactionAttribute()); log.info("트랜잭션1 커밋"); txManager.commit(tx1); log.info("트랜잭션2 시작"); TransactionStatus tx2 = txManager.getTransaction(new DefaultTransactionAttribute()); log.info("트랜잭션2 롤백"); txManager.rollback(tx2); } @Test //논리 두개 정상 커밋 -> 물리 커밋 void inner_commit() { log.info("외부 트랜잭션 시작"); TransactionStatus outer = txManager.getTransaction(new DefaultTransactionAttribute()); log.info("outer.isNewTransaction()={}", outer.isNewTransaction()); /** * 외부 트랜잭션 이어받아서 실행 * 그래서 commit 해도 아무런 변화도 없음, 당연 트잭 생성도 없음 */ log.info("내부 트랜잭션 시작"); TransactionStatus inner = txManager.getTransaction(new DefaultTransactionAttribute()); log.info("inner.isNewTransaction()={}", inner.isNewTransaction()); log.info("내부 트랜잭션 커밋"); txManager.commit(inner);//변화가 없다고 볼수 있따 log.info("외부 트랜잭션 커밋"); txManager.commit(outer); } @Test//내부 commit 외부 rollback -> rollback void outer_rollback() { log.info("외부 트랜잭션 시작"); TransactionStatus outer = txManager.getTransaction(new DefaultTransactionAttribute()); log.info("내부 트랜잭션 시작"); TransactionStatus inner = txManager.getTransaction(new DefaultTransactionAttribute()); log.info("내부 트랜잭션 커밋"); txManager.commit(inner); //변화가 없다고 볼수 있따 log.info("외부 트랜잭션 롤백"); txManager.rollback(outer); } @Test //내부 : rollback , 외부 : commit : rollback void inner_rollback() { log.info("외부 트랜잭션 시작"); TransactionStatus outer = txManager.getTransaction(new DefaultTransactionAttribute()); log.info("내부 트랜잭션 시작"); TransactionStatus inner = txManager.getTransaction(new DefaultTransactionAttribute()); log.info("내부 트랜잭션 롤백"); txManager.rollback(inner); log.info("외부 트랜잭션 커밋"); assertThatThrownBy(() -> txManager.commit(outer)) .isInstanceOf(UnexpectedRollbackException.class); } @Test//외부 내부 별개의 커넥션으로 작동, 각각 따로 작동! PROPAGATION_REQUIRES_NEW! void inner_rollback_requires_new() { log.info("외부 트랜잭션 시작"); TransactionStatus outer = txManager.getTransaction(new DefaultTransactionAttribute()); log.info("outer.isNewTransaction()={}", outer.isNewTransaction()); log.info("내부 트랜잭션 시작"); DefaultTransactionAttribute definition = new DefaultTransactionAttribute(); definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); TransactionStatus inner = txManager.getTransaction(definition); log.info("inner.isNewTransaction()={}", inner.isNewTransaction()); log.info("내부 트랜잭션 롤백"); txManager.rollback(inner); //롤백 log.info("외부 트랜잭션 커밋"); txManager.commit(outer); //커밋 } } 해당 코드에서, @TestConfiguration static class Config{ @Bean public PlatformTransactionManager transactionManager(DataSource dataSource){ return new DataSourceTransactionManager(dataSource); } } 이부분은 boot에서 자동 으로 생성해주는 부분이니 빼도 문제없이 작동한다고 생각했습니다. 그래서 돌려보니, 모든 테스트가 통과는 됩니다.그러나, inner_rollback() 에서만 문제가 있어 문의 드립니다. 2023-03-05 18:03:46.478 INFO 11608 --- [ Test worker] hello.springtx.propagation.BasicTxTest : 외부 트랜잭션 시작2023-03-05 18:03:46.479 DEBUG 11608 --- [ Test worker] o.s.orm.jpa.JpaTransactionManager : Creating new transaction with name [null]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT2023-03-05 18:03:46.479 DEBUG 11608 --- [ Test worker] o.s.orm.jpa.JpaTransactionManager : Opened new EntityManager [SessionImpl(1559037239<open>)] for JPA transaction2023-03-05 18:03:46.479 DEBUG 11608 --- [ Test worker] o.s.orm.jpa.JpaTransactionManager : Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@6ee1ddcf]2023-03-05 18:03:46.479 INFO 11608 --- [ Test worker] hello.springtx.propagation.BasicTxTest : 내부 트랜잭션 시작2023-03-05 18:03:46.479 DEBUG 11608 --- [ Test worker] o.s.orm.jpa.JpaTransactionManager : Found thread-bound EntityManager [SessionImpl(1559037239<open>)] for JPA transaction2023-03-05 18:03:46.479 DEBUG 11608 --- [ Test worker] o.s.orm.jpa.JpaTransactionManager : Participating in existing transaction2023-03-05 18:03:46.479 INFO 11608 --- [ Test worker] hello.springtx.propagation.BasicTxTest : 내부 트랜잭션 롤백2023-03-05 18:03:46.479 DEBUG 11608 --- [ Test worker] o.s.orm.jpa.JpaTransactionManager : Participating transaction failed - marking existing transaction as rollback-only2023-03-05 18:03:46.479 DEBUG 11608 --- [ Test worker] o.s.orm.jpa.JpaTransactionManager : Setting JPA transaction on EntityManager [SessionImpl(1559037239<open>)] rollback-only2023-03-05 18:03:46.488 DEBUG 11608 --- [ Test worker] cResourceLocalTransactionCoordinatorImpl : JDBC transaction marked for rollback-only (exception provided for stack trace)java.lang.Exception: exception just for purpose of providing stack trace at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.markRollbackOnly(JdbcResourceLocalTransactionCoordinatorImpl.java:324) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final] at org.hibernate.engine.transaction.internal.TransactionImpl.markRollbackOnly(TransactionImpl.java:203) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final] at org.hibernate.engine.transaction.internal.TransactionImpl.setRollbackOnly(TransactionImpl.java:224) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final] at org.springframework.orm.jpa.JpaTransactionManager$JpaTransactionObject.setRollbackOnly(JpaTransactionManager.java:712) ~[spring-orm-5.3.17.jar:5.3.17] at org.springframework.orm.jpa.JpaTransactionManager.doSetRollbackOnly(JpaTransactionManager.java:611) ~[spring-orm-5.3.17.jar:5.3.17] at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:844) ~[spring-tx-5.3.17.jar:5.3.17] at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:809) ~[spring-tx-5.3.17.jar:5.3.17] at hello.springtx.propagation.BasicTxTest.inner_rollback(BasicTxTest.java:117) ~[test/:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na] at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725) ~[junit-platform-commons-1.8.2.jar:1.8.2] at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:214) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2] at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:210) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151) ~[junit-platform-engine-1.8.2.jar:1.8.2] at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) ~[junit-platform-engine-1.8.2.jar:1.8.2] at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) ~[junit-platform-engine-1.8.2.jar:1.8.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) ~[junit-platform-engine-1.8.2.jar:1.8.2] at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) ~[junit-platform-engine-1.8.2.jar:1.8.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) ~[junit-platform-engine-1.8.2.jar:1.8.2] at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) ~[na:na] at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) ~[junit-platform-engine-1.8.2.jar:1.8.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) ~[junit-platform-engine-1.8.2.jar:1.8.2] at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) ~[junit-platform-engine-1.8.2.jar:1.8.2] at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) ~[junit-platform-engine-1.8.2.jar:1.8.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) ~[junit-platform-engine-1.8.2.jar:1.8.2] at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) ~[junit-platform-engine-1.8.2.jar:1.8.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) ~[junit-platform-engine-1.8.2.jar:1.8.2] at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) ~[na:na] at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) ~[junit-platform-engine-1.8.2.jar:1.8.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) ~[junit-platform-engine-1.8.2.jar:1.8.2] at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) ~[junit-platform-engine-1.8.2.jar:1.8.2] at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) ~[junit-platform-engine-1.8.2.jar:1.8.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) ~[junit-platform-engine-1.8.2.jar:1.8.2] at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) ~[junit-platform-engine-1.8.2.jar:1.8.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) ~[junit-platform-engine-1.8.2.jar:1.8.2] at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35) ~[junit-platform-engine-1.8.2.jar:1.8.2] at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) ~[junit-platform-engine-1.8.2.jar:1.8.2] at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54) ~[junit-platform-engine-1.8.2.jar:1.8.2] at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107) ~[na:na] at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88) ~[na:na] at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54) ~[na:na] at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67) ~[na:na] at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52) ~[na:na] at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114) ~[na:na] at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86) ~[na:na] at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86) ~[na:na] at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53) ~[na:na] at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99) ~[na:na] at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79) ~[na:na] at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75) ~[na:na] at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na] at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36) ~[na:na] at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) ~[na:na] at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33) ~[na:na] at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94) ~[na:na] at jdk.proxy1/jdk.proxy1.$Proxy2.stop(Unknown Source) ~[na:na] at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193) ~[na:na] at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129) ~[na:na] at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100) ~[na:na] at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60) ~[na:na] at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56) ~[na:na] at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:133) ~[na:na] at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:71) ~[na:na] at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69) ~[gradle-worker.jar:na] at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74) ~[gradle-worker.jar:na]2023-03-05 18:03:46.490 INFO 11608 --- [ Test worker] hello.springtx.propagation.BasicTxTest : 외부 트랜잭션 커밋2023-03-05 18:03:46.526 DEBUG 11608 --- [ Test worker] o.s.orm.jpa.JpaTransactionManager : Initiating transaction commit2023-03-05 18:03:46.526 DEBUG 11608 --- [ Test worker] o.s.orm.jpa.JpaTransactionManager : Committing JPA transaction on EntityManager [SessionImpl(1559037239<open>)]2023-03-05 18:03:46.527 DEBUG 11608 --- [ Test worker] cResourceLocalTransactionCoordinatorImpl : On commit, transaction was marked for roll-back only, rolling back2023-03-05 18:03:46.527 DEBUG 11608 --- [ Test worker] o.s.orm.jpa.JpaTransactionManager : Closing JPA EntityManager [SessionImpl(1559037239<open>)] after transaction해당 로그가 뜨면서 테스트 통과는 됩니다.왜 이런 오류가 발생하는지 조금 이해가 안되서요, 그리고 내부에서 rollback을 했음에도 불구하고, Global transaction is marked as rollback-only but transactional code requested commit보이지 않습니다. 왜 이런 문제가 발생하는 걸까요??
- 미해결스프링 DB 2편 - 데이터 접근 활용 기술
트랜잭션 적용 내부 메서드를 다른 서비스로 분리시에 서비스간 순환 참조 문제 해결 방안
트랜잭션 AOP 주의 사항 - 프록시 내부 호출2 강의 관련 서비스 계층에서 서비스 계층을 주입 받는 부분 관련해서 문의 드립니다. 실무에서는 서비스간 순환 참조에 어떻게 대응하는지 문의 드립니다.실무 중에 서비스에서 서비스를 주입 받다보면 순환 참조가 발생하는 문제가 생길 수 있다고 알고 있습니다. 그런데 트랜잭션 적용 메서드 내부 호출(this.{트랜잭션 적용 메서드})일 경우에 트랜잭션이 안걸리는 문제를 해결하기 위해 트랜잭션 적용 메서드를 다른 서비스로 분리하고 분리된 서비스를 주입 받아서 프록시가 호출되도록 하셨습니다. 보통은 스프링이 순환 참조일 때 run 시점에 에러를 발생 시키기는 합니다. 그런데 이런 문제를 실무에서 실행 시점이 아닌 코드 작성 시점에 어떤식으로 해결 하나요? 개발팀간에 약속을 하고 분리된 서비스에 다른 서비스를 주입하지 못하게 하는지 아니면 다른 방법이 있는지 궁금합니다. 아래는 예시 코드와 실제 자바 run 시점에 발생한 에러 코드 입니다.Description: The dependencies of some of the beans in the application context form a cycle: ┌─────┐ | externalService defined in file [/Users/inor/Desktop/Projects/study/db2/springtx/build/classes/java/main/hello/springtx/service/ExternalService.class] ↑ ↓ | internalService defined in file [/Users/inor/Desktop/Projects/study/db2/springtx/build/classes/java/main/hello/springtx/service/InternalService.class] ↑ ↓ | otherService defined in file [/Users/inor/Desktop/Projects/study/db2/springtx/build/classes/java/main/hello/springtx/service/OtherService.class] └─────┘ class ExternalService { private final InternalService internalService ; public void external() { internalService.internalTx(); } }class InternalService { private final OtherService otherService; @Transactional public void internal() {...} }class OtherService { private final ExternalService externalService; }
- 미해결스프링 DB 2편 - 데이터 접근 활용 기술
데이터 정합성
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.회원은 저장되지만, 회원 이력 로그는 롤백된다. 따라서 데이터 정합성에 문제가 발생할 수 있다(트랜잭션 전파 활용2 - 커밋, 롤백 강의 中) 라고 하셨는데 지금 이 강의에서도 결국엔 회원은 저장되고 회원 이력 로그는 롤백되니까 데이터 정합성이 해결된게 아닌가요..?
- 해결됨스프링 DB 2편 - 데이터 접근 활용 기술
TxBasicTest 오류
"C:\Program Files\Java\jdk-18\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2022.3.2\lib\idea_rt.jar=12660:C:\Program Files\JetBrains\IntelliJ IDEA 2022.3.2\bin" -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath "C:\Users\Mathlife\.m2\repository\org\junit\platform\junit-platform-launcher\1.9.2\junit-platform-launcher-1.9.2.jar;C:\Users\Mathlife\.m2\repository\org\junit\platform\junit-platform-engine\1.9.2\junit-platform-engine-1.9.2.jar;C:\Users\Mathlife\.m2\repository\org\opentest4j\opentest4j\1.2.0\opentest4j-1.2.0.jar;C:\Users\Mathlife\.m2\repository\org\junit\platform\junit-platform-commons\1.9.2\junit-platform-commons-1.9.2.jar;C:\Users\Mathlife\.m2\repository\org\apiguardian\apiguardian-api\1.1.2\apiguardian-api-1.1.2.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2022.3.2\lib\idea_rt.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2022.3.2\plugins\junit\lib\junit5-rt.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2022.3.2\plugins\junit\lib\junit-rt.jar;C:\Users\Mathlife\Desktop\Backend\06. spring-db-2\source\springtx\out\test\classes;C:\Users\Mathlife\Desktop\Backend\06. spring-db-2\source\springtx\out\production\classes;C:\Users\Mathlife\Desktop\Backend\06. spring-db-2\source\springtx\out\production\resources;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter-data-jpa\3.0.3\d302964840ffeef5098ec7ae1384c97b590e6a50\spring-boot-starter-data-jpa-3.0.3.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.projectlombok\lombok\1.18.26\8f8cf0372abf564913e9796623aac4c8ea44025a\lombok-1.18.26.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter-test\3.0.3\41c1983addad955bf3d4b923ac7ed1775c6d26d6\spring-boot-starter-test-3.0.3.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter-aop\3.0.3\b7bfb96b95e60ebe8d345eb6f2c872557a682ace\spring-boot-starter-aop-3.0.3.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter-jdbc\3.0.3\d0629ac327da8bb19d7327230956150b8781fe94\spring-boot-starter-jdbc-3.0.3.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.hibernate.orm\hibernate-core\6.1.7.Final\343f47b34c96fe9c44bf9b219a7b3c5d6d2fc90e\hibernate-core-6.1.7.Final.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.springframework.data\spring-data-jpa\3.0.2\ffb79a3370ebf09a63ac5f7aa8d85f4e339a47e4\spring-data-jpa-3.0.2.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.springframework\spring-aspects\6.0.5\a758bb59124425df6614c4d335365c1a2bdbeafa\spring-aspects-6.0.5.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter\3.0.3\bf77d1a59e933f31b99acc437206ee3aabcc421e\spring-boot-starter-3.0.3.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-test-autoconfigure\3.0.3\d30f322cc3a4b653b9b0fb48ea24c4c59f6531a4\spring-boot-test-autoconfigure-3.0.3.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-test\3.0.3\96b00d9edd18b57a27089c3702f3fcc138817\spring-boot-test-3.0.3.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\com.jayway.jsonpath\json-path\2.7.0\f9d7d9659f2694e61142046ff8a216c047f263e8\json-path-2.7.0.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\jakarta.xml.bind\jakarta.xml.bind-api\4.0.0\bbb399208d288b15ec101fa4fcfc4bd77cedc97a\jakarta.xml.bind-api-4.0.0.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.assertj\assertj-core\3.23.1\d2bb60570f5b3d7ffa8f8000118c9c07b86eca93\assertj-core-3.23.1.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.hamcrest\hamcrest\2.2\1820c0968dba3a11a1b30669bb1f01978a91dedc\hamcrest-2.2.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.junit.jupiter\junit-jupiter\5.9.2\26c586fbe0ebd81b48c9f11f0d998124248697ae\junit-jupiter-5.9.2.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.mockito\mockito-junit-jupiter\4.8.1\e393aa62eca2244a535b03842843f2f199343d1f\mockito-junit-jupiter-4.8.1.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.mockito\mockito-core\4.8.1\d8eb9dec8747d08645347bb8c69088ac83197975\mockito-core-4.8.1.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.skyscreamer\jsonassert\1.5.1\6d842d0faf4cf6725c509a5e5347d319ee0431c3\jsonassert-1.5.1.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.springframework\spring-test\6.0.5\8be22c21ccbfdfc9651e205559ad11c4063373e9\spring-test-6.0.5.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.springframework\spring-core\6.0.5\257932031f676dae20989046630dd5deed6a80cb\spring-core-6.0.5.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.xmlunit\xmlunit-core\2.9.1\e5833662d9a1279a37da3ef6f62a1da29fcd68c4\xmlunit-core-2.9.1.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.springframework\spring-aop\6.0.5\ac13a58d1ccc0619709572a05f067cc81741d7d3\spring-aop-6.0.5.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.aspectj\aspectjweaver\1.9.19\afbffb1210239fbba5cad73093c5b216d515838f\aspectjweaver-1.9.19.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.springframework\spring-jdbc\6.0.5\7555dec3648ffb656fb36a902cf9a74c5db7c392\spring-jdbc-6.0.5.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\com.zaxxer\HikariCP\5.0.1\a74c7f0a37046846e88d54f7cb6ea6d565c65f9c\HikariCP-5.0.1.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\jakarta.persistence\jakarta.persistence-api\3.1.0\66901fa1c373c6aff65c13791cc11da72060a8d6\jakarta.persistence-api-3.1.0.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\jakarta.transaction\jakarta.transaction-api\2.0.1\51a520e3fae406abb84e2e1148e6746ce3f80a1a\jakarta.transaction-api-2.0.1.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.springframework\spring-context\6.0.5\468e6a8446072a9eea95ff17bf5f03c97414cdf3\spring-context-6.0.5.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.springframework\spring-orm\6.0.5\82e5d0afe235807b25e92c7bf5054bcd7206f34d\spring-orm-6.0.5.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.springframework.data\spring-data-commons\3.0.2\ef6fe3b62d6f5582d97d5eb402fc474def8e7d7b\spring-data-commons-3.0.2.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.springframework\spring-tx\6.0.5\92127c0a17c63f70320d20b05d56e21acd6ffbbf\spring-tx-6.0.5.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.springframework\spring-beans\6.0.5\2ab5549926db09a63786c8073a79d686ea15264c\spring-beans-6.0.5.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\jakarta.annotation\jakarta.annotation-api\2.1.1\48b9bda22b091b1f48b13af03fe36db3be6e1ae3\jakarta.annotation-api-2.1.1.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.slf4j\slf4j-api\2.0.6\88c40d8b4f33326f19a7d3c0aaf2c7e8721d4953\slf4j-api-2.0.6.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-autoconfigure\3.0.3\17a64795795ecf1f1f6f0cc1c2794e2bed23ceda\spring-boot-autoconfigure-3.0.3.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot\3.0.3\d781e7afbeb3d05ce361e9cc4fa7d38b15fb3862\spring-boot-3.0.3.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter-logging\3.0.3\df4efe00271856a50f2e65abce2ddf4e5a529a25\spring-boot-starter-logging-3.0.3.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.yaml\snakeyaml\1.33\2cd0a87ff7df953f810c344bdf2fe3340b954c69\snakeyaml-1.33.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\net.minidev\json-smart\2.4.8\7c62f5f72ab05eb54d40e2abf0360a2fe9ea477f\json-smart-2.4.8.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\jakarta.activation\jakarta.activation-api\2.1.1\88c774ab863a21fb2fc4219af95379fafe499a31\jakarta.activation-api-2.1.1.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\net.bytebuddy\byte-buddy\1.12.23\d470526e8c4566c04e9ae5d3ccb62d1a7aa58986\byte-buddy-1.12.23.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.junit.jupiter\junit-jupiter-params\5.9.2\bc2765afb7b85b583c710dd259a11c6b8c39e912\junit-jupiter-params-5.9.2.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.junit.jupiter\junit-jupiter-api\5.9.2\fed843581520eac594bc36bb4b0f55e7b947dda9\junit-jupiter-api-5.9.2.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\net.bytebuddy\byte-buddy-agent\1.12.23\1cba11fdb72c383edacb909f79ae6870efd275e4\byte-buddy-agent-1.12.23.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\com.vaadin.external.google\android-json\0.0.20131108.vaadin1\fa26d351fe62a6a17f5cda1287c1c6110dec413f\android-json-0.0.20131108.vaadin1.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.springframework\spring-jcl\6.0.5\69b78d3e84b8f66d679447225322fac3b8137ff0\spring-jcl-6.0.5.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.springframework\spring-expression\6.0.5\7fcdf1cc183667b43583dca92d9345d27e43f040\spring-expression-6.0.5.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\ch.qos.logback\logback-classic\1.4.5\28e7dc0b208d6c3f15beefd73976e064b4ecfa9b\logback-classic-1.4.5.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.apache.logging.log4j\log4j-to-slf4j\2.19.0\30f4812e43172ecca5041da2cb6b965cc4777c19\log4j-to-slf4j-2.19.0.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.slf4j\jul-to-slf4j\2.0.6\c4d348977a83a0bfcf42fd6fd1fee6e7904f1a0c\jul-to-slf4j-2.0.6.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\net.minidev\accessors-smart\2.4.8\6e1bee5a530caba91893604d6ab41d0edcecca9a\accessors-smart-2.4.8.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.apiguardian\apiguardian-api\1.1.2\a231e0d844d2721b0fa1b238006d15c6ded6842a\apiguardian-api-1.1.2.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.junit.platform\junit-platform-commons\1.9.2\6f9f8621d8230cd38aa42e58ccbc0c00569131ce\junit-platform-commons-1.9.2.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.opentest4j\opentest4j\1.2.0\28c11eb91f9b6d8e200631d46e20a7f407f2a046\opentest4j-1.2.0.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\ch.qos.logback\logback-core\1.4.5\e9bb2ea70f84401314da4300343b0a246c8954da\logback-core-1.4.5.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.apache.logging.log4j\log4j-api\2.19.0\ea1b37f38c327596b216542bc636cfdc0b8036fa\log4j-api-2.19.0.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.ow2.asm\asm\9.1\a99500cf6eea30535eeac6be73899d048f8d12a8\asm-9.1.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\com.h2database\h2\2.1.214\d5c2005c9e3279201e12d4776c948578b16bf8b2\h2-2.1.214.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.glassfish.jaxb\jaxb-runtime\4.0.2\e4e4e0c5b0d42054d00dc4023901572a60d368c7\jaxb-runtime-4.0.2.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.jboss.logging\jboss-logging\3.5.0.Final\c19307cc11f28f5e2679347e633a3294d865334d\jboss-logging-3.5.0.Final.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.hibernate.common\hibernate-commons-annotations\6.0.6.Final\77a5f94b56d49508e0ee334751db5b78e5ccd50c\hibernate-commons-annotations-6.0.6.Final.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.jboss\jandex\2.4.2.Final\1e1c385990b258ff1a24c801e84aebbacf70eb39\jandex-2.4.2.Final.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\com.fasterxml\classmate\1.5.1\3fe0bed568c62df5e89f4f174c101eab25345b6c\classmate-1.5.1.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\jakarta.inject\jakarta.inject-api\2.0.0\46fc8560b6fd17b78396d88f39c1a730457671f0\jakarta.inject-api-2.0.0.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.antlr\antlr4-runtime\4.10.1\10839f875928f59c622d675091d51a43ea0dc5f7\antlr4-runtime-4.10.1.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.junit.jupiter\junit-jupiter-engine\5.9.2\572f7a553b53f83ee59cc045ce1c3772864ab76c\junit-jupiter-engine-5.9.2.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.objenesis\objenesis\3.2\7fadf57620c8b8abdf7519533e5527367cb51f09\objenesis-3.2.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.glassfish.jaxb\jaxb-core\4.0.2\8c29249f6c10f4ee08967783831580b0f5c5360\jaxb-core-4.0.2.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.junit.platform\junit-platform-engine\1.9.2\40aeef2be7b04f96bb91e8b054affc28b7c7c935\junit-platform-engine-1.9.2.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.eclipse.angus\angus-activation\2.0.0\72369f4e2314d38de2dcbb277141ef0226f73151\angus-activation-2.0.0.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\org.glassfish.jaxb\txw2\4.0.2\24e167be69c29ebb7ee0a3b1f9b546f1dfd111fc\txw2-4.0.2.jar;C:\Users\Mathlife\.gradle\caches\modules-2\files-2.1\com.sun.istack\istack-commons-runtime\4.1.1\9b3769c76235bc283b060da4fae2318c6d53f07e\istack-commons-runtime-4.1.1.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit5 hello.springtx.apply.TxBasicTest 14:42:46.190 [main] DEBUG org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Neither @ContextConfiguration nor @ContextHierarchy found for test class [TxBasicTest]: using SpringBootContextLoader 14:42:46.192 [main] DEBUG org.springframework.test.context.support.AbstractContextLoader - Could not detect default resource locations for test class [hello.springtx.apply.TxBasicTest]: no resource found for suffixes {-context.xml, Context.groovy}. 14:42:46.210 [main] DEBUG org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Using ContextCustomizers for test class [TxBasicTest]: [DisableObservabilityContextCustomizer, PropertyMappingContextCustomizer, Customizer, ExcludeFilterContextCustomizer, DuplicateJsonObjectContextCustomizer, MockitoContextCustomizer, TestRestTemplateContextCustomizer] 14:42:46.300 [main] DEBUG org.springframework.test.context.util.TestContextSpringFactoriesUtils - Skipping candidate TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener] due to a missing dependency. Specify custom TestExecutionListener classes or make the default TestExecutionListener classes and their required dependencies available. Offending class: [jakarta/servlet/ServletContext] 14:42:46.309 [main] DEBUG org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Using TestExecutionListeners for test class [TxBasicTest]: [DirtiesContextBeforeModesTestExecutionListener, ApplicationEventsTestExecutionListener, MockitoTestExecutionListener, DependencyInjectionTestExecutionListener, DirtiesContextTestExecutionListener, TransactionalTestExecutionListener, SqlScriptsTestExecutionListener, EventPublishingTestExecutionListener, RestDocsTestExecutionListener, MockRestServiceServerResetTestExecutionListener, MockMvcPrintOnlyOnFailureTestExecutionListener, WebDriverTestExecutionListener, MockWebServiceServerTestExecutionListener, ResetMocksTestExecutionListener] 14:42:46.310 [main] DEBUG org.springframework.test.context.support.AbstractDirtiesContextTestExecutionListener - Before test class: class [TxBasicTest], class annotated with @DirtiesContext [false] with mode [null] 14:42:46.319 [main] DEBUG org.springframework.test.context.support.DependencyInjectionTestExecutionListener - Performing dependency injection for test class hello.springtx.apply.TxBasicTest . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v3.0.3) 2023-03-01T14:42:46.513+09:00 INFO 10348 --- [ main] hello.springtx.apply.TxBasicTest : Starting TxBasicTest using Java 18 with PID 10348 (started by Mathlife in C:\Users\Mathlife\Desktop\Backend\06. spring-db-2\source\springtx) 2023-03-01T14:42:46.514+09:00 INFO 10348 --- [ main] hello.springtx.apply.TxBasicTest : No active profile set, falling back to 1 default profile: "default" 2023-03-01T14:42:46.750+09:00 INFO 10348 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. 2023-03-01T14:42:46.763+09:00 INFO 10348 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 8 ms. Found 0 JPA repository interfaces. 2023-03-01T14:42:47.004+09:00 INFO 10348 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2023-03-01T14:42:47.143+09:00 INFO 10348 --- [ main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:a14918b4-a6d6-4daf-8c5f-4f7baf9d1b32 user=SA 2023-03-01T14:42:47.144+09:00 INFO 10348 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. 2023-03-01T14:42:47.176+09:00 INFO 10348 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] 2023-03-01T14:42:47.214+09:00 INFO 10348 --- [ main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.1.7.Final 2023-03-01T14:42:47.440+09:00 INFO 10348 --- [ main] SQL dialect : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect 2023-03-01T14:42:47.620+09:00 INFO 10348 --- [ main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform] 2023-03-01T14:42:47.628+09:00 INFO 10348 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' 2023-03-01T14:42:47.718+09:00 INFO 10348 --- [ main] hello.springtx.apply.TxBasicTest : Started TxBasicTest in 1.374 seconds (process running for 1.964) 2023-03-01T14:42:47.722+09:00 ERROR 10348 --- [ main] o.s.test.context.TestContextManager : Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener] to prepare test instance [hello.springtx.apply.TxBasicTest@615e83ac] org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'hello.springtx.apply.TxBasicTest': Unsatisfied dependency expressed through field 'basicService': No qualifying bean of type 'hello.springtx.apply.TxBasicTest$BasicService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:712) ~[spring-beans-6.0.5.jar:6.0.5] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:692) ~[spring-beans-6.0.5.jar:6.0.5] at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:133) ~[spring-beans-6.0.5.jar:6.0.5] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:481) ~[spring-beans-6.0.5.jar:6.0.5] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1398) ~[spring-beans-6.0.5.jar:6.0.5] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:398) ~[spring-beans-6.0.5.jar:6.0.5] at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:142) ~[spring-test-6.0.5.jar:6.0.5] at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:97) ~[spring-test-6.0.5.jar:6.0.5] at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:241) ~[spring-test-6.0.5.jar:6.0.5] at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:138) ~[spring-test-6.0.5.jar:6.0.5] at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$10(ClassBasedTestDescriptor.java:377) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:382) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$11(ClassBasedTestDescriptor.java:377) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) ~[na:na] at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179) ~[na:na] at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625) ~[na:na] at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) ~[na:na] at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[na:na] at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310) ~[na:na] at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735) ~[na:na] at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734) ~[na:na] at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762) ~[na:na] at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestInstancePostProcessors(ClassBasedTestDescriptor.java:376) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$instantiateAndPostProcessTestInstance$6(ClassBasedTestDescriptor.java:289) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:288) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$4(ClassBasedTestDescriptor.java:278) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at java.base/java.util.Optional.orElseGet(Optional.java:364) ~[na:na] at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$5(ClassBasedTestDescriptor.java:277) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:105) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:104) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:68) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$2(NodeTestTask.java:123) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:123) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:90) ~[junit-platform-engine-1.9.2.jar:1.9.2] at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) ~[na:na] at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) ~[junit-platform-engine-1.9.2.jar:1.9.2] at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) ~[na:na] at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:147) ~[junit-platform-launcher-1.9.2.jar:1.9.2] at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:127) ~[junit-platform-launcher-1.9.2.jar:1.9.2] at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:90) ~[junit-platform-launcher-1.9.2.jar:1.9.2] at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:55) ~[junit-platform-launcher-1.9.2.jar:1.9.2] at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:102) ~[junit-platform-launcher-1.9.2.jar:1.9.2] at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:54) ~[junit-platform-launcher-1.9.2.jar:1.9.2] at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114) ~[junit-platform-launcher-1.9.2.jar:1.9.2] at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86) ~[junit-platform-launcher-1.9.2.jar:1.9.2] at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86) ~[junit-platform-launcher-1.9.2.jar:1.9.2] at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53) ~[junit-platform-launcher-1.9.2.jar:1.9.2] at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:57) ~[junit5-rt.jar:na] at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38) ~[junit-rt.jar:na] at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11) ~[idea_rt.jar:na] at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35) ~[junit-rt.jar:na] at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235) ~[junit-rt.jar:na] at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54) ~[junit-rt.jar:na] Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'hello.springtx.apply.TxBasicTest$BasicService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1812) ~[spring-beans-6.0.5.jar:6.0.5] at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1371) ~[spring-beans-6.0.5.jar:6.0.5] at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1325) ~[spring-beans-6.0.5.jar:6.0.5] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:709) ~[spring-beans-6.0.5.jar:6.0.5] ... 76 common frames omitted org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'hello.springtx.apply.TxBasicTest': Unsatisfied dependency expressed through field 'basicService': No qualifying bean of type 'hello.springtx.apply.TxBasicTest$BasicService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:712) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:692) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:133) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:481) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1398) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:398) at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:142) at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:97) at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:241) at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:138) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$10(ClassBasedTestDescriptor.java:377) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:382) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$11(ClassBasedTestDescriptor.java:377) at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179) at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625) at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310) at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735) at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734) at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestInstancePostProcessors(ClassBasedTestDescriptor.java:376) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$instantiateAndPostProcessTestInstance$6(ClassBasedTestDescriptor.java:289) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:288) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$4(ClassBasedTestDescriptor.java:278) at java.base/java.util.Optional.orElseGet(Optional.java:364) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$5(ClassBasedTestDescriptor.java:277) at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:105) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:104) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:68) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$2(NodeTestTask.java:123) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:123) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:90) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:147) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:127) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:90) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:55) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:102) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:54) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86) at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86) at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53) at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:57) at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38) at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11) at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35) at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235) at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54) Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'hello.springtx.apply.TxBasicTest$BasicService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1812) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1371) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1325) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:709) ... 76 more 2023-03-01T14:42:47.739+09:00 INFO 10348 --- [ionShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default' 2023-03-01T14:42:47.741+09:00 INFO 10348 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... 2023-03-01T14:42:47.742+09:00 INFO 10348 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed. Process finished with exit code -1 TxBasicTest를 실행하면 위와 같은 에러가 발생합니다.스프링 부트 버전과 자바 버전을 제외한 다른 부분은 똑같이 설정한 것 같은데 뭐가 문제인지를 모르겠습니다. build.gradleplugins { id 'java' id 'org.springframework.boot' version '3.0.3' id 'io.spring.dependency-management' version '1.1.0' } group = 'hello' version = '0.0.1-SNAPSHOT' sourceCompatibility = '17' configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' //테스트에서 lombok 사용 testCompileOnly 'org.projectlombok:lombok' testAnnotationProcessor 'org.projectlombok:lombok' } tasks.named('test') { useJUnitPlatform() } 디렉토리 구조테스트 코드package hello.springtx.apply; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.springframework.aop.support.AopUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.TransactionSynchronizationManager; import static org.assertj.core.api.Assertions.*; @Slf4j @SpringBootTest public class TxBasicTest { @Autowired BasicService basicService; @Test void proxyCheck() { log.info("aop class={}", basicService.getClass()); assertThat(AopUtils.isAopProxy(basicService)).isTrue(); } @Test void txTest() { basicService.tx(); basicService.nonTx(); } @TestConfiguration static class TxApplyBasicConfig { @Bean BasicService basicService() { return new BasicService(); } } @Slf4j static class BasicService { @Transactional public void tx() { boolean txActive = TransactionSynchronizationManager.isActualTransactionActive(); log.info("call tx"); log.info("tx active={}", txActive); } public void nonTx() { boolean txActive = TransactionSynchronizationManager.isActualTransactionActive(); log.info("call non tx"); log.info("tx active={}", txActive); } } }
- 미해결스프링 DB 2편 - 데이터 접근 활용 기술
@Aspect 와 @Transactional
강의를 듣던중 궁금한 부분이 생겨 질문남깁니다@Transactional 어노테이션을 표기함으로써 해당 클래스의 프록시가 생성되고, AOP 또한 pointcut에 해당하는 클래스의 프록시를 생성해주는 것으로 알고 있습니다.여기서 궁금한 점이 있습니다.만약 @Transactional 과 aop 설정을 같은 메서드에 걸어준다면 어떤 형태로 프록시가 생성되는 걸까요?먼저 @Transactional 관련 프록시가 생성된다음, aop에서 앞서 만들어진 프록시를 대상으로 새로운 프록시를 또 만들어 컨테이너에 넣어주는 것 일까요?질문드린 것과 같이 생각하며 공부하던 중,@Transactional(readonly = true)를 적용하면 aop 코드에서 트랜잭션 관련 설정을 하지 않았음에도 해당 트랜잭션이 그대로 이어져 aop에서도 readonly 가 true 설정되어 있음을 확인하였고, 이러한 상황이 이해가 가지 않아 질문드리게 되었습니다.
- 미해결스프링 DB 2편 - 데이터 접근 활용 기술
EventListener, 프로필
EventListener가 붙어 있는 initData()가 스프링 컨테이너가 초기화를 다 끝내고 , 실행 준비가 되었을 때 발생하는 건 알겠습니다. 그런데 궁금한 건 , 프로필이 = local일 때만 initData()가 실행되는 건가요?프로필이 local이 아닐 때도 initData()가 실행되긴 하는데 testDataInit이 실행이 안되기 때문에 빈으로 등록이 안돼서 오류가 날 것 같은데, 오류는 안 나는 걸로 보아 자동으로 이 오류를 스프링이 처리하는 건지,, 궁금합니다.