spring boot 버전을 올리면서 3.4.x 버전을 사용하게 됐고, 동작을 확인하던 도중 기존 코드에서 에러가 발생했다.Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)해당 로우가 다른 트랜잭션에서 업데이트되거나 삭제되었다는 메시지인데, 버전을 올리지 않으면 해당 에러는 발생하지 않았다. 해당 문제가 발생할 수 있는 상황은 이렇다.// 엔티티 정의@Entity@Table(name = "person")@AllArgsConstructor@NoArgsConstructor(access = AccessLevel.PROTECTED)public class Person { @Id @Generated..
spring 은 전통적으로 http client 로 RestTemplate 을 제공해왔다. 그러다가 webflux 의 등장과 함께 비동기로 동작하는 http client 인 WebClient 라는 모던 http client 를 제공하기 시작했는데, 초기엔 mvc 에서도 이 WebClient 를 이용하는걸 권장했다. 하지만 WebClient 를 이용하기 위해선 webflux 전체에 의존해야하고, reactive 라이브러리인 proejct reactor API 를 사용해야하는 불편함이 있었다. 불편함이라고 썼지만 개인적으론 최악의 경험이었다. 그러다가 spring boot 3.2 에 신규 동기 http client 가 들어왔으니 그게 RestClient 이다. 오늘은 RestClient 를 잘 사용하기 위한..
github 의 Pull Request 를 이용해서 코드리뷰를 하고 있다. 코드리뷰라고 하면 참 좋은데 하다보면 다양한 어려움도 있기 마련이다. PR이 너무 커서 보기 힘든 경우도 있고, 내가 얼른 리뷰받아서 배포해야하는데 리뷰가 늦어져서 답답한 경우도 있다. 좋은 PR과 코드리뷰를 하려면 무엇을 고려해야할까 고민해보다가 나름의 고민결과를 적어본다. # 작은 PR리뷰를 요청하는 개발자는 본인의 변경이니 코드가 눈에 잘 들어오지만, 타인이 작성한 코드를 봐야하는 리뷰어 입장에서는 큰 PR은 검토하기가 쉽지 않다. 그리고 결과적으로 큰 PR은 리뷰어들이 리뷰를 진행하는데 시간을 오래 걸리게 만든다. 이는 리뷰어 입장에서도 고통이지만 얼른 리뷰를 받아야하는 요청자 입장에서도 답답한 상황이 된다. 때문에 개발하..
이번엔 예외처리에 대한 이야기를 해보려한다. 실무에서도 흔히 보이는 방식과 그 방식에서 아쉬웠던 부분도 함께 정리해보고자 한다. # 1개의 Exception 클래스와 error enum실무에서 가장 많이 본 예외처리 방식이다. 대다수가 이런 방식을 사용하고 있을거라고 생각한다.// 예외 클래스 정의@Getterpublic class ApiException extends RuntimeException { private ErrorCode errorCode;}// 에러 코드를 담는 상수 정의, 사용자노출 메시지와 http status 코드를 관리@AllArgsConstructor@Getterpublic enum ErrorCode { ENTITY_NOT_FOUND("엔티티를 찾지 못했습니다.", 40..
이번엔 특별히 무언가 주제가 있다기보다 실무에서도 쉽게 접하는 상황에서 어떻게 인터페이스를 설계하는게 올바른지 예제를 통해 알아가보려 한다. 지난 포스팅의 후속작정도 될 것 같다. # 요구사항소셜 로그인 로직을 구현해야한다. 소셜 로그인은 네이버, 카카오, 구글을 지원할 예정이다. 소셜 로그인을 할때 각 플랫폼들이 필요로 하는 정보는 아래에 적어놨다. 실제 플랫폼들의 소셜 로그인을 구현하는건 아니어서 아래 필요정보들은 실제 플랫폼 소셜 로그인과는 상관없이 가상의 필요정보다. 네이버: client-key, 사용자 id, 사용자 동의여부카카오: client-key, 사용자 id구글: client-key, 사용자 토큰 # 인터페이스 정의소셜 로그인과 각 플랫폼들의 관계는 딱봐도 개발자로 하여금 뭔가 추상화를..
기존 spring boot 3.0.13 버전에서 3.1.12 로 버전업을 시도했다. 하위호환을 잘 보장해준 덕에 큰 이슈없이 빌드에 성공했는데 엔티티 조회시 ArrayIndexOutOfBoundsException 이 발생하는걸 확인했다. 해당 엔티티는 크게 복잡하지 않은 보통의 엔티티였는데 왜 문제가 발생한건지 정리하려한다. 문제가 발생하는 환경을 간단한 엔티티로 표현하면 이렇다.@Entity@Table(name = "car")public class Car { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "car_id") private Long id; @Column(name = "car_type") ..
spring batch 를 이용할때 어떤 reader 를 이용할지 항상 고민되는 편이다. DB 접근을 JPA 로 하고 있다면 대표적으로 JpaCursorItemReader, JpaPagingItemReader 중에 고민하게 된다. 보통 이 둘을 고민하는 상황이 오면 성능적으론 JpaCursorItemReader 가 더 좋다는걸 알게 된다. 하지만 대량의 데이터를 조회한 후 커서를 이동시키는 이 방식은 타임아웃을 유발할 수 있기에 데이터가 많을땐 조심해야해서, 이런 문제에 대해 안전한 JpaPagingItemReader 를 선택하는 경우가 많다. 하지만 페이징 기반의 리더를 쓰게되면 몇가지 곤란한 부분이 있는데 대표적으로 특정 상태를 이용해 조회한 후 상태를 변경하는 방식의 배치 잡을 만들때다. 1페이지를..
spring batch 4.3 부터 JpaCursorItemReader 가 추가됐다. 이게 추가되기 이전에는 배치에서 JPA 를 쓸땐 JpaPagingItemReader 를 사용하거나 cursor 방식이 필요하다면 HibernateCursorItemReader 를 써야했다. JpaCursorItemReader 가 추가된지 비교적 얼마 안됐기때문에 아직 HibernateCursorItemReader 를 이용해 돌아가고있는 배치가 많을 것으로 예상한다. 하지만 HibernateCursorItemReader 는 spring batch 5.0 부터 Deprecate 되었고, 5.2 부터는 아예 삭제될 예정이므로 최신 spring batch 에서 배치 로직을 작성하거나 기존 spring batch 프로젝트의 버전..
spring 을 공부하면 가장 먼저 배우는 키워드 중 하나가 DI 이다. DI 란 무엇인가? 의존성을 직접 해결하지 않고 외부로부터 주입받는 것이다. 더군다나 주입받는 대상을 구현 클래스가 아닌 인터페이스로 지정하면 확장에 열려있는 설계가 되며, DI 는 스트레티지 패턴에 기초하고 있다는걸 공부하게 된다. 그럼 spring 을 사용하고 있는 우리는 공부한걸 잘 이해하고, spring 으로 애플리케이션을 개발할때 다형성을 잘 이용하고 있을까?@Componentpublic class DataGetter { public String get() { // SQL 을 이용해 데이터 조회 }}@Componentpublic class DataAggregator { @Autowired ..
spring batch 를 이용하여 배치를 만들때 job 설정은 아래와 같이 JobbuilderFactory 를 주입받아 이를 이용한다.@Configurationpublic class SimpleBatchConfiguration { @Autowired private JobBuilderFactory jobBuilderFactory; @Bean public Job simpleJob(Step step) { return this.jobBuilderFactory.get("simpleJob") .start(step) .build(); }} 하지만 현재 최신버전(3.2.5)의 spring boot 를 이용한다면 해당 클래스가..
- Total
- Today
- Yesterday
- spring cloud
- EffectiveJava
- OOP
- TEST
- javascript
- java
- Spring
- generics
- Kotlin
- frontend개발환경
- go-core
- java8
- Jackson
- http
- programming
- servlet
- db
- Design Pattern
- JavaScript Core
- clean code
- frontcode
- toby
- Git
- DesignPattern
- code
- MySQL
- JPA
- backend개발환경
- mariadb
- 정규표현식
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |