본문 바로가기

Development/DB, JPA

(15)
Is Redis-connection-pooling necessary ? (lettuce) 기본적으로 Blocking, Single Thread 이다 Lettuce 는 여러 스레드 사이에서 하나의 connection을 공유하더라도 thread-safe 하게 동작하도록 설계되어 있으며, auto-reconnection설정도 defualt이다. 그래서 대부분의 경우에는 Connection pooling이 필요없다. 또한 어차피 모든 레디스 사용자 Operation은 싱글 스레드기반으로 수행되기 때문에, 여러 커넥션을 사용한다 하더라도 어플리케이션 성능이 좋아지지도 않는다. 그러면 언제 유용한가? 제한적으로 사용되며, 당연히 복잡도와 유지보수의 비용은 들어간다. Redis의 blocking operation은 보통 해당 워커스레드에서 물고있는 커넥션을 통해 수행되는데, 그렇다면 커넥션을 필요로 하는..
DBCP maxLIfeTime Issue Error Msg Failed to validate connection com.mysql.cj.jdbc.ConnectionImpl@17061015 (No operations allowed after connection closed.)Possibly consider using a shorter maxLifetime value. 즉, Pool 내의 Connection을 validate 해보니, DB에서 이미 해당 커넥션을 종료시켰기 때문에 발생하는 에러이다. public class HikariConfig implements HikariConfigMXBean { private static final Logger LOGGER = LoggerFactory.getLogger(HikariConfig.class); p..
Lazy Initialize Exception 방어코드 뷰에 필요한 엔티티를 미리 로딩해줌으로서 지연 로딩 익셉션에 대한 방어를 할 수있다.1. Global Fetch 전략 수정가장 간단한 방법으로 글로벌 페치를 fetch = FetchType.EAGER 로 잡아주면 즉시로딩을 하기 때문에 지연 로딩에 대한 문제가 발생하지 않는다. 단점해당 엔티티가 필요없는 경우에도 무조건 로딩한다.N+1 Problem 발생 가능성 2. JPQL 페치 조인기존 //JPQL select o from Order o //SQL select * from orderJPQL 페치 조인 사용 //JPQL select o from Order o join fetch o.orderItem //SQL select o.*, i.* from Order o join OrderItem i on o.o..
스프링 JPA 그리고 LazyInitializeException 1. 스프링 컨테이너의 기본전략 스프링 컨테이너를 사용하면, 컨테이너가 트랜잭션과 영속성 컨텍스트를 관리해준다. 스프링 컨테이너는 트랜잭션 범위의 영속성 컨텍스트 전략을 기본으로 사용한다.이는 다음을 의미한다.트랜잭션의 범위 = 영속성 컨텍스트의 생존 범위 즉 , 트랜잭션을 시작할 때 영속성 컨텍스트를 생성하고, 트랜잭션이 종료될 때 영속성 컨텍스트를 종료한다 2. @Transactional 어노테이션 @Transactional을 통해 동작하는 스프링 트랜잭션 AOP는 대상 메소드를 호출하기전에 트랜잭션을 시작하고 메소드가 종료되면 커밋을 하면서 종료한다. 이때 트랜잭션을 커밋하기 직전 JPA는 영속성 컨텍스트를 플러시해서 변경 내용을 데이타베이스에 반영한다. 트랜잭션을 시작할 때 영속성 컨텍스트를 생..
NULL 제약 조건과 조인 전략 JPA는 매핑관계의 필수 여부에 따라 실제 데이타베이스로 보내는 SQL 구문이 달라진다선택적 관계 @Entity public class Member { //... @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "teamId") private Team team; //... }@ManyToOne 의 optional 속성이 true (default) 이거나 @JoinColumn 의 nullable 속성이 true(default) 인 경우에는 Team이 없는 Member도 조회될 것을 보장해야 하기 때문에 Outer Join 을 수행한다. SELECT * FROM Member m left outer join Team t ON m.teamId = t.teamId..
JPA를 이용한 다대일 객체 관계 매핑 JPA를 이용한 다대일 객체 관계 매핑한 회원은 하나의 팀에 속하며, 한 팀에는 여러 회원이 속하는 경우를 생각해보자. 팀은 회원에 대한 정보를 몰라도 괜찮다고 하면 아래와 같이 표현할 수 있다. JPA EntityMember.java @Entity public class Memeber { @Id @GeneratedValue @Column(name = "memberId") private Long id; private String userName; @ManyToOne @JoinColumn(name = "teamId") private Team team ​ //bla bla }@JoinColumn을 사용하여 Team과 다대일 관계를 매핑한다. @JoinColumn 주요 속성name - 속성은 외래키 컬럼의 이..
JPA 기본 키 전략 JPA 기본 키 전략1. 직접 할당@id 애노테이션으로 필드와 매핑한다. 자바 기본형, 래퍼형, String, Date, BigDecimal, BigInteger가 타입이 가능하다 2. IDENTITY기본 키 생성을 데이타베이스에 위임한다. 데이타베이스의 auto_increment와 같은 기능을 사용할 때 쓴다. 키 필드에 @GeneratedValue(strategy = GenerationType.IDENTITY)를 사용한다.이 전략을 사용하면 JPA는 기본 키 값을 얻어오기 위해 데이타베이스를 추가로 조회한다. 따라서 이 전략을 사용하는 엔티티를 새로 생성하여 식별자 값을 할당하려면 1차 캐시를 넘어서 데이타베이스에서 Insert한 후에 기본 키 값을 조회한다. 즉, persist()를 호출하는 즉시 ..
JPA를 이용한 엔티티 CUD(등록,수정,삭제) 엔티티 등록엔티티 매니저를 이용해서 엔티티를 영속성 컨텍스트에 등록한다1 transaction.begin(); 2 em.persist(memA); 3 em.persist(memB); 4 transaction.commit();트랜잭션이 시작된 후 memA 를 persist 하면 DB에 바로 반영되는 것이 아니다. memA의 Insert Query 를 영속성 컨텍스트 내의 내부 쿼리 저장소(쓰기 지연 SQL 저장소)에 저장하고 1차 캐시에만 엔티티를 저장한다. memB를 persist 할 때에도 마찬가지이다. 마지막으로 transaction.commit()이 호출될 때 flush가 일어나고 이때 실제 DB로 SQL을 날린다.persist 할 때마다 쿼리를 날리든, 모아서 한번에 날리든 결국 트랜잭션 커밋이 ..