묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
Spring boot로만 강의를 진행 하나요, 혹은 Spring 으로도 진행 하는걸까요?
안녕하세요~ 갑자기 궁금함이 생겨 질문 드립니다~영한님이 진행 해주시는 강의는 대부분 Spring boot로 진행 되는것으로 아는데, Spring으로 진행 하는 강의 가있나요?답변부탁드립니다.감사합니다.
-
해결됨Kevin의 알기 쉬운 Spring Reactive Web Applications: Reactor 1부
Backpressure Drop 전략에서 다시 버퍼가 채워지는 시점에 대한 질문입니다.
안녕하세요 강사님. 오늘 Backpressure Example 코드 강의 수강 후 Backpressure Drop 전략에 대해 궁금했던 부분은 다른 분의 질문을 통해서 해결을 할 수 있었습니다.(질문 글 Link) 해당 글에서 강사님의 답변을 보면Drop 전략의 경우, 버퍼 안의 데이터가 Subscriber에게 한개 전달되면, 버퍼 공간이 한개 비니까 한개의 데이터가 채워지는것이 아니라 전체 버퍼 중에 70-80 퍼센트 정도(정확한 비율은 나중에 확인 후 말씀드릴게요)가 한번에 비워진다고 보시면 될것 같습니다.즉, 데이터 한개가 버퍼에서 비워지는 것이 아니라 버퍼가 가득찬 상태에서 Downstream이 데이터를 처리할 수 있는 상태가 될 때까지 Upstream에서 emit된 데이터는 Drop이 된다고 생각하시면 될것 같습니다.이런 부분이 있는데 혹시 어떤 파일의 어떤 메서드를 보면 해당 내용을 알 수 있을까요 ? ※제가 혼자서 디버그를 통해서 찾아보려고 했는데 잘 찾아지지가 않아서 여쭤봅니다. 😢
-
해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
db sql 트랜잭션
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용] 트랜잭션 때문에 이렇게 복잡하고, 긴 여정을 떠나왔는데, 그냥 String sql = 에다가 트랜잭션 문장을 넣으면 안되나요? 그렇게 해서, 그냥 repository에 송금 트랜잭션 메소드를 넣으면 더 간편하지 않나요? SRP를 위반해서 그렇게 하지 않는 것 인가요?
-
미해결스프링 DB 2편 - 데이터 접근 활용 기술
[해결방법] Could not autowire. No beans of 'ItemMapper' type found. 오류
아래 코드 추가@MapperScan("hello.itemservice.repository.mybatis") @Configuration @RequiredArgsConstructor @MapperScan("hello.itemservice.repository.mybatis") public class MyBatisConfig { private final ItemMapper itemMapper; @Bean public ItemService itemService() { return new ItemServiceV1(itemRepository()); } @Bean public ItemRepository itemRepository() { return new MyBatisItemRepository(itemMapper); } }
-
미해결스프링 DB 2편 - 데이터 접근 활용 기술
[해결방법] Invalid bound statement 오류
resources 폴더에서 폴더를 하나씩 생성해야합니다.한번에 폴더를 생성하면 오류가 발생합니다. (예: hello.iteamservice.repository.mybatis)강사님 만들어두신 프로젝트의 폴더를 복사 붙여넣기해도 오류가 발생합니다. 올바른 예시)hello 폴더 생성itemservice 폴더 생성repository 폴더 생성mybatis 폴더 생성ItemMapper.xml 파일 생성
-
미해결실전! 스프링 데이터 JPA
17:00 분 경에 적으시는 @Bean은 꼭 main메서드가 있는 곳에서 작성해야 하나요>?
=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]혹시 config클래스를 따로 파서 거기에 만들어도 적용이 되는 건가여? 만약에 된다고 하면 둘중 어떤 식으로 많이 사용하나요?
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
p6spy와 r2dbc 관련 질문
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]여기에 질문 내용을 남겨주세요. 안녕하세요. 지금 엔티티 클래스 개발2 강의 수강 중입니다.해당 강의 7분 20초 즈음 JpashopApplication 클래스 실행시키는 부분에서 런타임 에러가 발생하여 질문을 올리게 됐습니다. 처음 뜬 오류는 Caused by: java.lang.IllegalStateException: Could not evaluate condition on com.github.gavlyukovskiy.boot.jdbc.decorator.flexypool.FlexyPoolConfiguration$PropertyFlexyConfiguration due to com/vladmihalcea/flexypool/util/ClassLoaderUtils not found. Make sure your own configuration does not rely on that class. This can also happen if you are @ComponentScanning a springframework package (e.g. if you put a @ComponentScan in the default package by mistake) 이었습니다. 구글링과 chatgpt를 사용해 해결방법을 모색하였고 p6spy를 사용하려면 flexypool이 필요없다는 사실을 확인 했지만 오류 메세지에 맞추어implementation 'com.github.gavlyukovskiy:flexy-pool-spring-boot-starter:1.9.0' 을 build.gradle에 추가해 해결하려고 했습니다. 하지만 이번에는 'Caused by: java.lang.IllegalStateException: Could not evaluate condition on org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryConfigurations$PoolConfiguration due to io/r2dbc/spi/ValidationDepth not found. Make sure your own configuration does not rely on that class. This can also happen if you are @ComponentScanning a springframework package (e.g. if you put a @ComponentScan in the default package by mistake)' 오류가 발생하는 걸 확인할 수 있었습니다. 이번에도 구글링 및 chatgpt를 통해 해결방법을 찾아보려 했는데, JPA를 사용하면 R2DBC 관련한 모듈을 추가할 필요가 없다는 걸 확인할 수 있었고 아예 잘못된 방향으로 해결방법을 모색하고 있다는 걸 확인했습니다. 3. 현재 작성중인 코드에 flexy-pool을 사용하는 코드가 있나 점검해보았습니다. ./gradlew clean build .application.yml 점검build.gradle 점검./gradlew dependencies 를 통해서 의존관계 확인하지만 문제가 되는 부분을 찾을 수는 없었습니다. 어디서부터 잘못된건지, 해결 방법은 무엇인지 알려주시면 감사하겠습니다. 파일 링크 : https://drive.google.com/file/d/1kWHwYUf8akxBlG1Wdn6D_1WQbnRw8uzR/view?usp=sharing감사합니다.
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
ExceptionResolver 내에서 sendError 호출
안녕하세요! 제가 질문의 의도를 명확히 드러내지 못한 것 같아 내용을 추가하여 재 질문 드립니다. https://www.inflearn.com/community/questions/1369485/exceptionresolver-%EC%97%90%EB%9F%AC-%ED%95%B4%EA%B2%B0%EC%97%90-%EA%B4%80%ED%95%98%EC%97%AC-%EC%A7%88%EB%AC%B8%EC%9D%B4-%EC%9E%88%EC%8A%B5%EB%8B%88%EB%8B%A4 <제가 생각한 json 결과> { "timestamp": "2024-09-07T16:52:16.664+00:00", "status": 400, "error": "Bad Request", "path": "/api/members/bad" } resolver에서 IllegalArgumentException을 해결을 하였고 sendError로 흐름을 바꾸었으니 순수 sendError(400)의 결과인 위 json과 같이 나와야 한다고 생각하였습니다.<흐름도>Controller 에서 IllegalArgumentException 발생 -> ExceptionResolver 실행 -> IllegalArgumentException 해결 후 sendError로 변경 -> BasicController 호출 후 sendError의 결과인 위의 json 반환 따라서 에러를 해결하였기 때문에 IllegalArgumentException 정보는 없고 sendError 정보만 있다고 생각합니다. 실제 출력에는 어찌 IllegalArgumentException 정보가 json에 출력되는지 궁금합니다. 에러를 해결 했더라도 그 정보를 다른 객체로 가지고 있고 나중에 활용하는 것 일까요?? 좋은 강의 만들어 주셔서 감사합니다.
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
update 로직 질문
멤버 업데이트 시memberService.update(id, request.getName());으로 작성해 주셨는데memberService.update(id, request);와 같이 객체를 통째로 넘기지 않는 이유가 있는 것인가요? 위와 같이 객체를 통째로 넘기는 경우 UpdateMemberRequest 클래스를 이너 클래스가 아닌 별도의 클래스로 분리해 줘야 하는 게 맞나요?
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
JdbcMemberRepository 문제
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.어떤 점이 문제인지 모르겠습니다 ㅜ jdbcMemberRepositorypackage hello.hello_spring.repository; import hello.hello_spring.domain.Member; import org.springframework.jdbc.datasource.DataSourceUtils; import javax.sql.DataSource; import java.sql.*; import java.util.ArrayList; import java.util.List; import java.util.Optional; public class JdbcMemberRepository implements MemberRepository{ private final DataSource dataSource; public JdbcMemberRepository(DataSource dataSource) { this.dataSource = dataSource; } @Override public Member save(Member member) { String sql = "insert into member(name) values(?)"; Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { conn = getConnection(); pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); pstmt.setString(1, member.getName()); pstmt.executeUpdate(); rs = pstmt.getGeneratedKeys(); if (rs.next()) { member.setId(rs.getLong(1)); } else { throw new SQLException("id 조회 실패"); } return member; } catch (Exception e) { throw new IllegalStateException(e); } finally { close(conn, pstmt, rs); } } @Override public Optional<Member> findById(Long id) { String sql = "select * from member where id = ?"; Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { conn = getConnection(); pstmt = conn.prepareStatement(sql); pstmt.setLong(1, id); rs = pstmt.executeQuery(); if(rs.next()) { Member member = new Member(); member.setId(rs.getLong("id")); member.setName(rs.getString("name")); return Optional.of(member); } else { return Optional.empty(); } } catch (Exception e) { throw new IllegalStateException(e); } finally { close(conn, pstmt, rs); } } @Override public List<Member> findAll() { String sql = "select * from member"; Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { conn = getConnection(); pstmt = conn.prepareStatement(sql); rs = pstmt.executeQuery(); List<Member> members = new ArrayList<>(); while(rs.next()) { Member member = new Member(); member.setId(rs.getLong("id")); member.setName(rs.getString("name")); members.add(member); } return members; } catch (Exception e) { throw new IllegalStateException(e); } finally { close(conn, pstmt, rs); } } @Override public Optional<Member> findByName(String name) { String sql = "select * from member where name = ?"; Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { conn = getConnection(); pstmt = conn.prepareStatement(sql); pstmt.setString(1, name); rs = pstmt.executeQuery(); if(rs.next()) { Member member = new Member(); member.setId(rs.getLong("id")); member.setName(rs.getString("name")); return Optional.of(member); } return Optional.empty(); } catch (Exception e) { throw new IllegalStateException(e); } finally { close(conn, pstmt, rs); } } private Connection getConnection() { return DataSourceUtils.getConnection(dataSource); } private void close(Connection conn, PreparedStatement pstmt, ResultSet rs) { try { if (rs != null) { rs.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (pstmt != null) { pstmt.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (conn != null) { close(conn); } } catch (SQLException e) { e.printStackTrace(); } } private void close(Connection conn) throws SQLException { DataSourceUtils.releaseConnection(conn, dataSource); } } MemberRepositorypackage hello.hello_spring.repository; import hello.hello_spring.domain.Member; import java.util.List; import java.util.Optional; public interface MemberRepository { Member save(Member member); void finById(Long id); Optional<Member> findById(Long id); Optional<Member> findByName(String name); List<Member> findAll(); void cleatStore(); }MemoryMemberRepositorypackage hello.hello_spring.repository; import hello.hello_spring.domain.Member; import java.util.Map; import java.util.Optional; import java.util.*; public class MemoryMemberRepository implements MemberRepository { public static Map<Long, Member> store = new HashMap<>(); private static long sequence = 0L; @Override public Member save(Member member) { member.setId((++sequence)); store.put(member.getId(), member); return member; } @Override public void finById(Long id) { } @Override public Optional<Member> findById(Long id) { return Optional.ofNullable((Member) store.get(id)); } @Override public Optional<Member> findByName(String name) { return store.values().stream() .filter(member -> member.getName().equals(name)) .findAny(); } @Override public List<Member> findAll() { return new ArrayList<>(store.values()); } @Override public void cleatStore() { } void clearStore() { store.clear(); } }errorerror: JdbcMemberRepository is not abstract and does not override abstract method cleatStore() in MemberRepository public class JdbcMemberRepository implements MemberRepository{
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
JdbcMemberRepository 문제
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.이런 오류가 뜨는데 대체 어떻게 해결해야 할까요? ㅠㅠpackage hello.hello_spring.repository; import hello.hello_spring.domain.Member; import org.springframework.jdbc.datasource.DataSourceUtils; import javax.sql.DataSource; import java.sql.*; import java.util.ArrayList; import java.util.List; import java.util.Optional; public class JdbcMemberRepository implements MemberRepository{ private final DataSource dataSource; public JdbcMemberRepository(DataSource dataSource) { this.dataSource = dataSource; } @Override public Member save(Member member) { String sql = "insert into member(name) values(?)"; Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { conn = getConnection(); pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); pstmt.setString(1, member.getName()); pstmt.executeUpdate(); rs = pstmt.getGeneratedKeys(); if (rs.next()) { member.setId(rs.getLong(1)); } else { throw new SQLException("id 조회 실패"); } return member; } catch (Exception e) { throw new IllegalStateException(e); } finally { close(conn, pstmt, rs); } } @Override public Optional<Member> findById(Long id) { String sql = "select * from member where id = ?"; Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { conn = getConnection(); pstmt = conn.prepareStatement(sql); pstmt.setLong(1, id); rs = pstmt.executeQuery(); if(rs.next()) { Member member = new Member(); member.setId(rs.getLong("id")); member.setName(rs.getString("name")); return Optional.of(member); } else { return Optional.empty(); } } catch (Exception e) { throw new IllegalStateException(e); } finally { close(conn, pstmt, rs); } } @Override public List<Member> findAll() { String sql = "select * from member"; Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { conn = getConnection(); pstmt = conn.prepareStatement(sql); rs = pstmt.executeQuery(); List<Member> members = new ArrayList<>(); while(rs.next()) { Member member = new Member(); member.setId(rs.getLong("id")); member.setName(rs.getString("name")); members.add(member); } return members; } catch (Exception e) { throw new IllegalStateException(e); } finally { close(conn, pstmt, rs); } } @Override public Optional<Member> findByName(String name) { String sql = "select * from member where name = ?"; Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { conn = getConnection(); pstmt = conn.prepareStatement(sql); pstmt.setString(1, name); rs = pstmt.executeQuery(); if(rs.next()) { Member member = new Member(); member.setId(rs.getLong("id")); member.setName(rs.getString("name")); return Optional.of(member); } return Optional.empty(); } catch (Exception e) { throw new IllegalStateException(e); } finally { close(conn, pstmt, rs); } } private Connection getConnection() { return DataSourceUtils.getConnection(dataSource); } private void close(Connection conn, PreparedStatement pstmt, ResultSet rs) { try { if (rs != null) { rs.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (pstmt != null) { pstmt.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (conn != null) { close(conn); } } catch (SQLException e) { e.printStackTrace(); } } private void close(Connection conn) throws SQLException { DataSourceUtils.releaseConnection(conn, dataSource); } } error: JdbcMemberRepository is not abstract and does not override abstract method cleatStore() in MemberRepository public class JdbcMemberRepository implements MemberRepository{
-
해결됨Kevin의 알기 쉬운 Spring Reactive Web Applications: Reactor 1부
Reactor 3부의 오픈 일정에 관해서 문의드립니다!
안녕하세요 최근에 Spring MVC 말고도 Spring WebFlux에 대해서도 관심을 가지게 되어 Reactor 공부를 막 시작한 주니어입니다. 해당 강의가 3부까지 기획되어 있는 것으로 강의소개를 봤었습니다. 강사님께서도 무척이나 바쁘시겠지만, 혹시 3부는 언제쯤 오픈할 예정이신지 여쭤봐도 될까요? 강의 잘 보고 있습니다! 감사합니다
-
해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
response.sendError의 역할
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]섹션 8에서 컨트롤러에서 response.sendError()을 사용해서 WAS까지 오류 정보를 전달 하는 것으로 생각했습니다.그런데 섹션 9를 공부하면서 ExceptionResolver 코드를 확인해보면 결국 내부적으로 response.sendError() 를 호출한 다는 것을 알게 되었습니다.이는 response.sendError()를 사용하는 것이 WAS까지 오류 정보를 전달하는 역할을 하는 것이 아니라고 이해하면 될까요? 그렇다면 어떻게 위 그림의 sendError흐름이 만들어지는 걸까요
-
해결됨토비의 스프링 6 - 이해와 원리
멀티 스레드를 사용하는 테스트에서 트랜잭션 사용에 대해서..
멀티 스레드를 사용하는 테스트에서는 @Transactional 을 어떻게 사용해야 할까요..? 동시성 이슈를 확인하는 테스트에서는 주로 ExecutorService 를 통해 스레드 풀을 생성해서 동시에 서비스 로직을 호출하는 식으로 테스트를 진행하면서 여러 문제를 겪었는데 어떻게 해결하면 좋을지 고민을 하다가 토비님에게 질문드려봅니다 ㅠㅠ다른 스레드에서 save() 한 오브젝트를 조회할 수 없는 문제.테스트 코드에 @Transactional 를 사용하게 되면 테스트 코드가 하나의 트랜잭션으로 묶이게 되는데, 다른 스레드에서 서비스를 호출 하기 전에 테스트를 위한 데이터를 save() 하고 다른 스레드가 서비스에서 save 한 데이터를 가져오려고 할 때 아직 DB에 commit 되지 않은 상태여서 가져오지 못하는 이슈가 있더라구요. -> db isolation level이 read uncommited 보다 높기 때문에 발생하는 것 같음. @Test @DisplayName("밖에서 저장한 데이터는 스레드 내부에서 가져올 수 없음") @Transactional void outsideTransaction() throws InterruptedException { Member member = new Member(1L, "테스트유저"); memberRepository.saveAndFlush(member); entityManager.clear(); TimeUnit.SECONDS.sleep(2); // 일정 시간 대기. try (ExecutorService executorService = Executors.newFixedThreadPool(32)) { executorService.submit(() -> { long count = memberRepository.count(); Optional<Member> optionalMember = memberRepository.findById(1L); System.out.println("member count: " + count); System.out.println("optionalMember.isEmpty: " + optionalMember.isEmpty()); }); } System.out.println("================================="); long count = memberRepository.count(); Optional<Member> optionalMember = memberRepository.findById(1L); System.out.println("member count: " + count); System.out.println("optionalMember.isEmpty: " + optionalMember.isEmpty()); }member count: 0 optionalMember.isEmpty: true ================================= member count: 1 optionalMember.isEmpty: false테스트 코드에 @Transactional 을 선언해도 테스트 코드 내부에서 생성한 스레드에서는 트랜잭션이 존재하지 않는 문제. @Test @DisplayName("내부 스레드는 트랜잭션이 존재하지 않음.") @Transactional void activeTransaction() { System.out.println("쓰레드 밖에서 트랜잭션 상태: " + TransactionSynchronizationManager.isActualTransactionActive()); try (ExecutorService executorService = Executors.newFixedThreadPool(32)) { executorService.submit(() -> { System.out.println("쓰레드 안에서 트랜잭션 상태: " + TransactionSynchronizationManager.isActualTransactionActive()); }); } } 위와 같은 테스트를 실행 했을 때, 출력되는 결과는 다음과 같았습니다.쓰레드 밖에서 트랜잭션 상태: true 쓰레드 안에서 트랜잭션 상태: false멀티 스레드를 사용하는 테스트에서 @Transactional 를 사용 했을 때 이런 문제점이 있었는데요.. 여러가지 시도해보다가 해결을 하지 못해서 결국 @Transactional 을 사용하지 않고.. 테스트가 끝날 때 마다 @AfterEach 통해서 DB를 직접 제거하는 방식으로 하고 있습니다... 이렇게 테스트는 @Transactional 을 사용하지 않고 서비스 로직에는 @Transactional 사용하고 있다보니, 실제 애플리케이션을 띄워서 api 부하 테스트를 해보면 원하는 결과가 나오지 않았습니다. 테스트 코드가 테스트 코드의 역할을 수행하고 있지 않네요이런 경우에는 어떻게 해결하는 것이 좋을까요? 감사합니다.
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
jsp 페이지 인식 안되는 문제
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]여기에 질문 내용을 남겨주세요.jsp 페이지가 인식되지 않습니다./jsp/members/new-form.jspgradle gradle 적용후 새로 적용했고 했고 서버도 재시작 했는데 jsp 페이지 접근이 안됩니다.index.html 정상 접근됩니다.
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
Spring web bean validation 에러핸들링
Bean validation핸들링이 보통 어떤 설계가 일반적인지 알고싶어서 질문드립니다폼post 송신시, Bean validation으로 에러감지 후 입력화면html로 리턴할텐데요이때, 브라우저 url은 post송신용이 남아있어서유저가 브라우저 주소창 엔터로Get으로 송신이 되어 서버에선postmapping만 지원한다고 시스템에러가 나는데 일반적으로 이런건 유저가 개발자 의도와는 다르게 이용한 케이스겠지만 흔히 있을 수 있는 일 같거든요. 이런거 방지하기 위해서는 get도 받을 수 있게 따로 구현을 하나요?아니면 실무에서는 어떤 방법이 있을까요
-
미해결토비의 스프링 6 - 이해와 원리
인터페이스는 사용하는 클래스에 가장 가까이 두는 걸로 이해했습니다. 하지만 그 인터페이스를 사용하는 클라이언트가 많다면 어떻게 해야할까요?
강의 재밌게 잘 보고 있습니다.궁금한 게 있어 질문드립니다.인터페이스는 구현체와 같은 모듈에 두는 게 아닌, 사용하는 클래스에 가장 가까이 두는 걸로 이해했습니다. 하지만 그 인터페이스를 사용하는 클라이언트가 많다면 어떻게 해야할까요?예를 들어 Payment 패키지의 PaymentService 도 ExRateProvider 를 쓰고,XXX 패키지의 XXXService 도 ExRateProvider 를 쓴다면ExRateProvider 의 모듈 위치는 어디에 존재를 해야할까요? 아니면 다른 방법이 있을 듯 한데, 그 방법은 무엇일까요?ExRateProvider 의 모듈 위치가 클라이언트와 분리되어 있다면, DIP 적용 이전 그러니까 WebApiExRateProvider 와 ExRateProvider 가 한 모듈에 같이 위치한 그림과 별반 다를 것이 없다(모듈 의존성에 따른 변경 가능성) 생각이 들어서요
-
미해결스프링 핵심 원리 - 기본편
이상한 에러가 발생했습니다
jdk 22를 사용중입니다.증상은 위의 에러가 뜨는데 테스트 코드들은 정상적으로 초록 채크표시가 뜹니다. 이거 무슨 에러인가요?
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
ItemController
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]1. ItemController에서 downloadImage함수에서 @ResponseBody를 사용하였는데, 사용하지않게 되면, 예외가 발생합니다. 왜그런가요?ItemController에서 downloadAttach에서는 ResponseEntity<Resource>를 사용하셨는데, 이게 @ResponseBody와 같은거라고 하셨는데,( 다만, header에 추가할 부분이 있어서 ResponseEntity를 사용하셨다고 하는데) 어떤 부분이 같은 건가요?
-
미해결스프링 시큐리티 OAuth2
OAuth 2.0 Grant Flows 관련 질문
안녕하세요. OAuth 2.0을 배우고 싶어 학습 신청했습니다.유익한 강의 준비해주셔서 감사합니다.막연하게 알고 있는 Spring Security 에 대해 강의를 통해 명확하게 알아가고 있습니다. 강의를 들으며 몇가지 궁금한 점이 있어 질문드립니다. 우선은 자체 로그인만 구현할 예정이라면,소셜 로그인 기능이 없는 경우에는 OAuth 2.0을 도입할 필요가 없는 건가요?Resource Owner Password Credentials Grant Flow 는 Deprecated 된다고 하는데 그럼 어떻게 구현해야하나요? 답변주시면 성장하는데 큰 도움이 될 것 같습니다!감사합니다!