BackEnd/SpringBoot
-
[스프링부트] @DataJpaTest 멀티스레드에서 no value presentBackEnd/SpringBoot 2023. 12. 6. 18:16
비관적 락 테스트를 하기 위해서 멀티 스레드 코드를 테스트하였다. 문제 환경 0. 테스트용 메모리 디비를 사용한다. 1. EntityManger도 @PersistenceContext로 팩토리를 통해서 tread-safe하도록 생성했다. 2. @DataJpaTest 사용하여 테스트 테스트 시나리오 1. 테스트 전에 이미 더미 데이터를 넣고 시작한다. 2. entitymanager로 flush()와 clear()를 사용하여 커밋과 1차캐시를 삭제한다. 3. 멀티 스레드 테스트 코드를 실행 한다. 1. 문제의 테스트 코드 2. 스레드 내부 메서드 foundUser에서 no value present가 발생한다. 오류를 찾을수가 없어서 log를 확인했다. application-test.yaml에 로그를 확인 할..
-
[스프링부트] 이미지 업로드 테스트 postman + restdocsBackEnd/SpringBoot 2023. 12. 3. 19:44
1. RequestPart Content-Type이 multipart/form-data로 오는 요청에 대해 동작하며 MultipartResolver 를 통해서 multipartFile을 받을 수있고 동시에 HttpMessageConverter를 통해서 RequestBody도 수행함을 알 수있다. 공식문서 : https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestPart.html RequestPart (Spring Framework 6.1.1 API) Annotation that can be used to associate the part of a "multip..
-
[스프링부트] 테스트 시 Mysql관련 에러 Unique index or primary key violationBackEnd/SpringBoot 2023. 11. 24. 11:27
0. 결론 1. @SpringBootTest를 사용하였고 컴포넌트스캔 범위가 전역으로 지정되었다. 2. 따라서 기존에 CommandLineRunner로 만든 더미데이터 컴포넌트를 스캔해서 데이터를 읽어서 발생한 오류였다. 3. 디버깅을 해서 쿼리 확인을 해보는게 가장 빨리 해결하는 방법인것같다. 4. 또한 통합테스트가 아니고서는 테스트 속도가 현저하게 떨어질수있기때문에 각 테스트에 맞게 테스크 클래스를 선택해야 한다. 1. 발생 경위 테스트코드 런타임중 에러 발생 에러코드 : [23505-214] 설명 : Unique index or primary key violation: "PUBLIC.UK_GXRAOQ3YFQ2112DHX6K3I3QWO_INDEX_2 ON PUBLIC.USER_MS(USER_EMAIL..
-
[스프링부트] ./gradlew build시 에러 -> error: cannot find symbolBackEnd/SpringBoot 2023. 11. 16. 16:18
1. 문제 ./gradlew 빌드 시 cannot find symbol 문구가 출력되며 빌드에 실패하였다. 해당 오류가 발생한 지점은 코드 상 별다른 오류가 발생하지않았다. 이미 인텔리제이라는 에디터 상에서 관련 설정이 되어있었기 때문이다. 2. 해결 방안 컴파일 시점에서 인식을 하지 못하는 오류로 현재 롬복을 사용중이기 때문에 build.gradle을 확인하여 annotaionProcessor를 추가하였다. annotationProcessor("org.projectlombok:lombok:1.18.28") annotaionProcessor란? 컴파일 단계에서 어노테이션을 분석하고 처리하기 위해 자바 컴파일러에 동봉된 hook
-
토비의 스프링 - 1권 6장 AOPBackEnd/SpringBoot 2023. 10. 8. 00:54
1. 관심사의 분리 - upgradeLevels 메서드 기능 회원 등급 업그레이드 코드 public void upgradeLevels() { // 트랜잭션 경계 시작 TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition()); try { List users = userDao.getAll(); for (User user : users) { if (canUpgradeLevel(user)) { upgradeLevel(); } } } // 트랜잭션 경계 끝 this.transactionManager.commit(status); } catch (Exception e) { this.transaction..
-
토비의 스프링 - 1권 5장 서비스의 추상화BackEnd/SpringBoot 2023. 10. 5. 00:27
1. 추상화 : 하위 시스템의 공통을 뽑아내서 분리하는 것을 말한다 로우 레벨의 코드를 알지 못하게 하여 일관된 방법으로 접근이 가능하다. (쉽게 말해서 우리는 정해진 형태의 리모컨을 만들어서 필요할때 껍데기는 두고 내용물만 바꿔 기능을 수행하고자 한다는 것이다. 클라이언트는 리모컨의 버튼이 동작하는 세세한 정보를 정확히 알고 써야할 필요가 없기때문이다.) 자바 라이브러리 중에 목적이 유사한 기술들이 있고 이런 기술들은 환경과 상황에 영향을 받는다면 매번 바뀌어야하는 번거로움이있다. 이런 유사한 기술들을 일관된 방법으로 사용하도록 하도록 유도한다면 개발에 큰 이점으로 다가온다. 대표적으로 트랜잭션을 다루는 기술로 알 수있다. 2. 트랜잭션 서비스 추상화 : 예시 문제 : 전체 유저 레벨업 도중 에러 발생..
-
토비의 스프링 - 1권 4장 예외BackEnd/SpringBoot 2023. 9. 13. 00:45
catch문은 조치를 위한 자리다 try catch문에서 자주보는 예외처리에서 cath문은 예외가 발생했을때 적절한 조치가 필요한 자리다 적절하게 복구가 되던지 아니면 작업을 중단시키고 개발자에게 통보 되어야한다 단순히 catch문으로 에러를 잡은 후 에러문구 노출인 e.printStackTrace();는 예외를 처리한 것으로 판단하기 어렵다 오히려 어디서 예외가 발생했는지 알수없게하는 예외 블랙홀이 가능성이 될 확률이 높다. 또한 아무 생각 없이 반복적으로 throw Exeption을 붙이는 것 또한 좋지 못하다 해당 작업에서 어떤 예외가 발생 할지 최대한 범위를 좁히는 것이 좋다. 사실 예외중에 일부러 에러를 발생시키는 부분에 대해서는 개발자들 사이에서 이견이 많다고 한다. 예외를 바로 처리하지않고 ..
-
토비의 스프링 - 1권 3장 템플릿BackEnd/SpringBoot 2023. 8. 23. 23:13
1. 템플릿 메서드 패턴 적용 불변 로직을 부모 클래스에 두고 상속을 통해 변하는 부분만 자식클래스에 설정 단점 중 하나로 상속을 통해 구현시 중복 메서드가 발생한다. 2. 전략패턴을 통한 구현 인터페이스를 DI받도록 설정 후 인터페이스를 구현한다음 클래스를 넘김 구현하고자 하는 전략클래스를 생성 후 갈아 끼움 ( 원하는 클래스로 설정 ) 수정전 - DI 이전의 코드 public class TestUserDao { public void deleteAll() throws SQLException { ... try { c = dataSource.getConnection(); ps = makeStatement(c); ps.executeUpdate(); } catch (SQLException e){} ... } ..