분류 전체보기

JPA

[JPA] saveAll() 문제점과 JDBC를 통한 해결

개요Spring data repository의 saveAll() 메서드는 그 이름 덕분인지, 여러 개의 데이터들을 하나의 쿼리로 처리할 것만 같다. 하지만 실제 적용해보니 예상과는 다르게 동작하는 부분들이 있었기에 기록으로 남겨보려 한다. 문제customerCreditTransactionRepository.saveAll(creditTransactions);100개 정도 되는 데이터를 한 번에 저장할 일이 있었다. 나는 위 코드처럼 saveAll()을 통해서 하나의 쿼리로 처리할 수 있을 줄 알았다. 하지만 실제 동작은 데이터를 각각의 INSERT 쿼리로 처리하는 것 아닌가... 원인왜 saveAll() 메서드가 한 번에 쿼리로 처리하지 못하는 것일까? 원인은 JPA의 기본키 생성 전략이였다. @Ent..

Language/Java

[Java] ReentrantLock을 통한 스레드 동기화

동기화란스레드 개념의 도입으로 하나의 프로세스에서 여러 스레드들이 동시에 작업을 처리할 수 있게 되었지만, 스레드들이 프로세스의 자원을 공유하며 Race Condition이나 데이터 불일치와 같은 동시성 문제들이 발생하게 되었다.여러 스레드가 접근할 때 동시성 문제가 발생할 수 있는 공유 자원을 임계 영역이라 하며, 동시성 문제가 발생하지 않으려면 임계 영역에 하나의 스레드만 접근할 수 있도록 해야한다. 스레드 간의 수행 시기를 맞추어 동시성 문제를 예방하는 것을 동기화라고 하며,자바에서도 멀티 스레드 상황에서 동시성 문제를 해결할 수 있는 여러 동기화 방법들을 제공한다. synchronized의 단점synchronized는 자바에서 동기화를 위한 가장 대표적인 키워드이다.자바에서 모든 객체는 모니터 ..

Language/Java

[Java] 자바 스레드 생명 주기와 메모리 가시성

자바 스레드 생명 주기자바 스레드의 생명 주기는 시작부터 시작하여 실행, 일시 중지, 종료의 상태를 갖고 있다. 1. New - 스레드가 생성되고 아직 시작되지 않은 상태2. Runnable - 실행될 준비가 됐거나, 실제로 실행 중인 상태3. Blocked - 동기화 락을 기다리는 상태, synchronized에서만 사용하는 특별한 스레드 대기 상태4. Waiting - 다른 스레드의 작업이 완료되기를 무기한 기다리는 상태5. Timed Waiting - 스레드가 일정 시간 동안 대기하는 상태6. Terminated - 스레드의 실행이 완료된 상태 join - 다른 스레드의 작업 대기class SumTask implements Runnable { int startValue; int endV..

Language/Java

[Java] Stream Collector, Downstream Collector

개요Stream은 중간 연산을 거친 데이터들을 collect 최종 연산을 통해 다양한 컬렉션으로 반환할 수 있다. 구조public interface Stream extends BaseStream> { .. //Collector 인터페이스를 통해 최종 연산 반환 타입 지정 R collect(Collector collector); ..}collect 연산은 Collector 인터페이스을 매개변수로 받아서 알맞은 컬렉션 형태로 반환한다. 자바에서 Collectors 클래스를 통해 Collector 인터페이스의 대부분 기능을 구현해 놓았다. Collectors 클래스에서 어떤 기능들로 어떤 타입들을 반환하는지 알아보자. List 반환//수정 가능List list = Stream...

Language/Java

[Java] Stream API와 지연 연산

Stream이란?Java 8부터 도입된 기능으로 데이터 흐름을 추상화해서 다루는 도구이다. 컬렉션 데이터를 함수형 프로그래밍 방식으로 처리할 수 있게 해준다. Stream 연산Stream 연산은 중간 연산과 최종 연산으로 나뉜다. List numbers = List.of(1,2,3,4)int sum = numbers.stream() .filter(n -> n % 2 == 0) // 중간 연산 -> 짝수 필터링 후 Stream 반환 .map(n -> n * 2) // 중간 연산 -> 두 배 변환 후 Stream 반환 .sum(); // 최종 연산 -> 합계 반환중간 연산은 Stream을 반환하여 중간 연산을 통해 체이닝이 가능하다. 최종..

Language/Java

[Java] 메서드 참조

메서드 참조란?이미 정의된 메서드를 그대로 참조하여 람다 표현식을 더 간결하게 작성하는 문법이다.즉, 람다가 단순히 이미 정의된 어떤 메서드를 호출하는 경우, 이를 축약해준다. 람다와 관련된 포스팅은 해당 글을 참고하면 좋을 것 같다. 람다 -> 메서드 참조Function function = s -> s.length();매개변수로 문자열이 들어오면 문자열의 길이를 반환해주는 람다식이다. Function function = String::length;위 람다식을 변환한 메서드 참조 형태이다.'::' 연산자를 사용해 메서드 참조를 나타 낼 수 있다. 메서드 참조에서는 컴파일러가 시그니처(매개변수, 타입)을 바탕으로 메서드 참조와 연결해주기 때문에, 명시적으로 매개변수를 작성하지 않아도 자동으로 추론되어 호..

Language/Java

[Java] 람다와 함수형 프로그래밍

개요메서드 파라미터에 값이 아닌 어떠한 로직을 넘기고 싶을 경우가 있다면, 어떻게 해야 할까? 인터페이스 구현 후, 구현한 클래스 넘기기public class ExMain { public static void hello(Procedure procedure) { //4. 메서드 실행 procedure.run(); } //1. 인터페이스 구현 static class Dice implements Procedure { @Override public void run() { int randomValue = new Random().nextInt(6) + 1; System.out.println("주사위 = " + ..

JPA

[JPA] @SQLRestriction으로 soft delete 구현하기

개요데이터 삭제 정책이 soft delete라면, 데이터 조회 시 delete 상태 여부를 확인하는 조건을 일일이 넣어주어야 할 것이다.@SQLRestriction 어노테이션을 통해 SQL의 where절에 delete 상태 여부를 체크하는 조건을 넣는 방법을 소개하려 한다. 문제코드를 살펴보자. 먼제 Hospital 엔티티이다.@Entity@Table(name = "hospitals")class Hospital( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Long? = null, val name: String, ... //삭제가 된 상태라면, 해당 필드에 값 존재 var deletedAt..

JPA

[JPA] 프록시 객체와 OneToOne 양방향 관계 이슈

개요OneToOne 양방향 관계로 설정한 엔티티에서 의도치 않게 N+1 이슈가 발생하였다. 관련된 개념인 프록시 객체와 즉시 로딩 & 지연 로딩에 대해 정리하고, 이슈를 공유하려 한다. 프록시 객체실제 엔티티 객체 대신 사용되는 가짜 객체이다. 프록시 객체는 엔티티를 상속받고 위임 패턴으로 구현된다. //실제 엔티티//DB 조회 쿼리 발생Member member = em.find(Member.class, member.getId());//프록시 객체//DB 조회 쿼리 발생되지 않음Member proxyMember = em.getReference(Member.class, member2.getId());//이 때, DB 조회 쿼리 발생proxyMember.getName();//다시 한 번 조회할 때는 쿼리 ..

JPA

[JPA] 영속성 컨텍스트와 flush 시점

개요최근 영속성 컨텍스트 내에서 flush 시점에 대해 잘못 짚고 있던 부분이 있어서, 영속성 컨텍스트와 flush 시점에 대해서 정리해보고 트러블 슈팅을 공유하려 한다. 엔티티와 생명 주기JPA에서 엔티티는 DB 테이블과 매핑되는 자바 객체를 말한다.엔티티는 다음과 같은 생명 주기를 갖는다. 1. 비영속Member member = new Member();member.setId(100L);member.setName("HelloJPA");엔티티가 처음 만들어졌을 때 상태이다. 2. 영속EntityManager em = emf.createEntityManager();//비영속Member member = new Member();member.setId(100L);member.setName("HelloJPA"..

kkang._.h00n
'분류 전체보기' 카테고리의 글 목록 (2 Page)