기존 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 를 이용한다면 해당 클래스가..
현재 진행중인 프로젝트에서 spring boot 2.7.18 을 사용하고 있다. 현시점(2024.04.28) 기준 2.x 버전에서 가장 최신이다. 엔티티 로딩과정에서 직관적이지 못한 이슈를 만나서 정리하고, 어떤때 발생하고 어떻게 해결할 수 있는지 정리해보려한다. spring boot2.7.18hibernate-core5.6.15.Final # 이슈상황- 엔티티 Main 과 엔티티 Sub 는 1:1 관계로 @OneToOne 관계를 맺고있다(fetchType 은 디폴트 설정인 EAGER 를 사용한다). 외래키는 Main 에서 관리한다고 가정한다.- Main 과 Sub 는 논리적 연관관계만 가질뿐 데이터베이스 설정상으로 외래키 관계를 강제하지는 않는 상태다.- Main 과 Sub 는 두 엔티티가 모두 정상적..
이번껀 spring boot 3 로 업그레이드할때 누구나 만날만한 이슈도 아니고, 어떻게 보면 그냥 내 실수이지만 비슷한 이슈를 마주할 수 있기에 적어놓는다. 기존 spring boot 2 애플리케이션에서 circuit breaker 로 resilience4j 를 사용하고 있었다면 spring boot 3 에 맞게 resilience4j 도 버전을 올려줘야한다. 다만 resilience4j 같은 경우 spring boot 버전에 최적화된 아티팩트를 제공하고 있어서 이 부분 이름도 변경해줘야 한다. spring boot 2 spring boot 3 io.github.resilience4j:resilience4j-spring-boot2:${version} io.github.resilience4j:resili..
설정파일에 정의한 내용들을 객체에 바인딩할때 @ConfigurationProperties 애노테이션을 이용해서 주입할 수 있다. // yml file config: person: age: 33 name: LichKing // binding 할 객체의 클래스 @ConfigurationProperties("config.person") @NoArgsConstructor @Setter @ToString public class Person { private String name; private int age; } // 어디엔가 이 애노테이션을 선언해줘야 한다 @ConfigurationPropertiesScan 위처럼 정의하면 spring 컨테이너가 구동될때 Person 의 기본생성자를 이용해 인스턴스를 만들고, ..
jackson 을 이용할땐 나 같은 경우 항상 ObjectMapper 클래스를 이용했다. 그러다가 Serialization/Deserialization 에 각각 특화된 ObjectWriter/ObjectReader 클래스가 있다는걸 알게됐는데 ObjectMapper 를 사용하는 것과 어떤 차이가 있는지 알아보기로 했다. 먼저 ObjectMapper 의 가장 치명적인 문제는 스레드에 안전하지 않다는 것이다. 멀티 스레드 환경에서 공유 변수로 사용하게 될 경우 원치 않는 결과가 나올 수 있다. ObjectMapper 의 javadoc 에는 이렇게 적혀있다. Mapper instances are fully thread-safe provided that ALL configuration of the instanc..
이전 포스팅에서 id 프로퍼티를 어느 위치에 선언하는게 좋을지 얘기해봤다. 이번엔 Long 과 Long? 중 어떤걸로 선언할지, 어떤차이가 있는지, 그리고 왜 이런 고민을 하게되는지 얘기해보려한다. # Long? vs Long @Entity @Table(name = "person") class Person( @Column(name = "person_name") val name: String, @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "person_id") val id: Long? = null ) id 값의 생성을 DB 에 위임하는 IDENTITY 방식을 주로 사용할텐데 이 방식을 사용하면 엔티티가 영속화되기 전에는 id..
- Total
- Today
- Yesterday
- mariadb
- OOP
- EffectiveJava
- javascript
- http
- Design Pattern
- clean code
- JavaScript Core
- MySQL
- db
- frontend개발환경
- Spring
- java8
- backend개발환경
- servlet
- Jackson
- code
- go-core
- frontcode
- toby
- java
- generics
- TEST
- programming
- spring cloud
- DesignPattern
- 정규표현식
- Git
- JPA
- Kotlin
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |