묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨토비의 스프링 부트 - 이해와 원리
DataSourceConfig에서 @EnableTransactionManagement를 사용하면 DataSourceTest가 안 되는것에 대한 질문이 있습니다.
안녕하세요 토비님. 강의 정말 잘 듣고있습니다! JdbcTemplate과 트랜잭션 매니저 구성 강의를 듣다가 @EnableTransactionManagement으로 트랜잭션(tx) 관리 기능을 열어주고 기존 DataSourceTest.java 예제를 실행하니 java.lang.IllegalStateException: Failed to unwrap proxied object 에러가 계속 발생합니다.DataSourceConfig.java에서 @EnableTransactionManagement 애노테이션을 제외를 하면 DataSourceTest.java 테스트가 정상적으로 잘 돌아가더라고요...음 java와 spring 버전, 라이브러리는 모두 동일하게 설정을 했습니다. 제 소스 코드는 하단에 있습니다! 버전 문제로 해당 예제가 안 돌아가는 것인지? 왜 안 되는지 궁금합니다.. 바쁘실텐데 이유나 원인을 아시면 알려주시면 감사하겠습니다. 에러코드java.lang.IllegalStateException: Failed to unwrap proxied object at org.springframework.test.util.AopTestUtils.getUltimateTargetObject(AopTestUtils.java:105) at org.springframework.boot.test.mock.mockito.SpringBootMockResolver.resolve(SpringBootMockResolver.java:35) at org.mockito.internal.util.MockUtil.resolve(MockUtil.java:118) at org.mockito.internal.util.MockUtil.isMock(MockUtil.java:108) at org.mockito.internal.util.DefaultMockingDetails.isMock(DefaultMockingDetails.java:32) at org.springframework.boot.test.mock.mockito.MockReset.get(MockReset.java:106) at org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener.resetMocks(ResetMocksTestExecutionListener.java:82) at org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener.resetMocks(ResetMocksTestExecutionListener.java:70) at org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener.beforeTestMethod(ResetMocksTestExecutionListener.java:57) at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:293) build.gradleplugins { id 'java' id 'org.springframework.boot' version '2.7.6' id 'io.spring.dependency-management' version '1.0.15.RELEASE' } group = 'tobyspring' version = '0.0.1-SNAPSHOT' java { sourceCompatibility = '11' } repositories { mavenCentral() maven { url 'https://repo.clojars.org' name 'Clojars' } } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework:spring-jdbc' implementation 'hikari-cp:hikari-cp:3.0.1' runtimeOnly('com.h2database:h2:2.1.214') // spring-boot-starter-undertow // implementation 'org.springframework.boot:spring-boot-starter-jetty' testImplementation 'org.springframework.boot:spring-boot-starter-test' } tasks.named('test') { useJUnitPlatform() } DataSourceTest package tobyspring.helloboot; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import javax.sql.DataSource; import java.sql.Connection; import java.sql.SQLException; @HellobootTest public class DataSourceTest { @Autowired DataSource dataSource; @Test public void connect() throws SQLException { Connection connection = dataSource.getConnection(); connection.close(); } } HelloBootTestpackage tobyspring.helloboot; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.transaction.annotation.Transactional; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = HellobootApplication.class) @TestPropertySource("classpath:/application.properties") @Transactional public @interface HellobootTest { } DataSourceConfig.javapackage tobyspring.config.autoconfig.datasource; import com.zaxxer.hikari.HikariDataSource; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; import org.springframework.context.annotation.Bean; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.SimpleDriverDataSource; import org.springframework.jdbc.support.JdbcTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import tobyspring.config.ConditionalMyOnClass; import tobyspring.config.MyAutoConfiguration; import tobyspring.config.autoconfig.EnableMyConfigurationProperties; import javax.sql.DataSource; import java.sql.Driver; @MyAutoConfiguration @ConditionalMyOnClass("org.springframework.jdbc.core.JdbcOperations") @EnableMyConfigurationProperties(MyDataSourceProperties.class) @EnableTransactionManagement public class DataSourceConfig { @Bean @ConditionalMyOnClass("com.zaxxer.hikari.HikariDataSource") @ConditionalOnMissingBean DataSource hikariDataSource(MyDataSourceProperties properties) { HikariDataSource dataSource = new HikariDataSource(); dataSource.setDriverClassName(properties.getDriverClassName()); dataSource.setJdbcUrl(properties.getUrl()); dataSource.setUsername(properties.getUsername()); dataSource.setPassword(properties.getPassword()); return dataSource; } @Bean @ConditionalOnMissingBean DataSource dataSource(MyDataSourceProperties properties) throws ClassNotFoundException { SimpleDriverDataSource dataSource = new SimpleDriverDataSource(); dataSource.setDriverClass((Class<? extends Driver>) Class.forName(properties.getDriverClassName())); dataSource.setUrl(properties.getUrl()); dataSource.setUsername(properties.getUsername()); dataSource.setPassword(properties.getPassword()); return dataSource; } @Bean @ConditionalOnSingleCandidate(DataSource.class) @ConditionalOnMissingBean JdbcTemplate jdbcTemplate(DataSource dataSource) { return new JdbcTemplate(dataSource); } @Bean @ConditionalOnSingleCandidate(DataSource.class) @ConditionalOnMissingBean JdbcTransactionManager jdbcTransactionManager(DataSource dataSource) { return new JdbcTransactionManager(dataSource); } }
-
미해결
데이터베이스 커넥션을 한 번 래핑해서 SQL statement 가 만들어진다고 하셨는데
영한쌤 강의 듣고 있었는데데이터베이스 커넥션을 한 번 래핑해서 SQL statement 가 만들어진 걸 잘 이해해서 log 로 출력해주는 라이브러리??라고 말씀해주셨는데이게 무슨 소린지 알 수 있을까요?