본문 바로가기

Development/DB, JPA

(13)
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 할 때마다 쿼리를 날리든, 모아서 한번에 날리든 결국 트랜잭션 커밋이 ..
EntityManager 와 EntityManagerFactory Entity Manger FactoryEntity Manger 를 생성하기 위해서는 persistence.xml의 설정 정보를 사용해서 Entity Manger Factory를 먼저 생성해야한다.EntityManagerFactory emf = Psersistence.createEntityManagerFactory("name");Entity Manager Factory 생성 비용은 굉장히 크기 때문에, 애플리케이션 전체에 걸쳐 한 번 생성하고 재사용 해야 한다.Entity Manager Entity Manager Factory 에서 Entity Manager를 생성한다.EntityManager em = emf.createEntityManager();JPA 대부분의 기능은 Entity Manger 가 제공한..
Persistence Context 영속성 컨텍스트 Persistence Context - 영속성 컨텍스트영속성 컨텍스트는 엔티티 매니저를 생성할 때 같이 만들어 지며 엔티티 매니저를 통해서 영속성 컨텍스트에 접근할 수 있다. 즉, 엔티티 매니저가 하는 어떤 행위는 영속성 컨텍스트에 반영되고 이것이 최종적으로 DB에 반영된다.특징식별자 값영속성 컨텍스트는 엔티티를 식별자 값으로 구분한다(@Id 애노테이션)데이터베이스와의 관계영속성 컨텍스트에 엔티티가 저장된다고 바로 DB에 반영되는 것이 아니라 일반적으로 트랜잭션이 커밋될 때 DB에 반영된다.(flush)영속성 컨텍스트에 엔티티를 관리할 때의 장점1차캐시동일성 보장트랜잭션이 지원되는 지연 쓰기변경 감지지연 로딩Entity Life Cyclenew / transient : 비영속 상태라고 하며 영속성 컨텍스..