728x90

Backend/JPA 7

[JPA] Entity 에 스키마 지정하기

Spring 환경에서 Database 커넥션을 설정할 때 jdbc url을 지정하게 되고 아래와 같이 기본적으로 스키마를 포함한 풀 url을 지정하게 된다. jdbc:mysql://localhost:3306/TEST 그런데 데이터베이스 안에는 업무상 여러개의 스키마를 만들어서 사용하는 경우가 있고 위와 같이 TEST 스키마로 DB 에 접속했지만 TEST2에 있는 테이블을 Entity 로 추가해서 참조하고 싶은 경우가 있을 수 있다. Mybatis 환경이라면 그냥 쿼리 사용시 테이블 앞에 TEST2. 를 추가해서 사용하면 되지만 jpa 환경에서는 어떻게 할까? 일단 Entity 클래스에 정의하는 @Table 어노테이션을 보면 schema 속성이 있는데 이게 아니고 catalog 속성에 스키마를 정의하면 된..

Backend/JPA 2022.03.15

No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)

JPA를 사용하다가 위와 같은 에러가 발생하는 경우가 있다. 의외로 서칭하니 답은 빨리나왔는데 설명이 장황하여 간단하게 원인만 정리한다. Entity 에 포함되는 속성 중 FetchType.LAZY 로 명시한 속성이 아직 Fetch 전인데 해당 Entity 를 json 직렬화 하려 할 때 발생한다. 좀 더 자세히 이야기 하면 Entity의 해당 속성이 아닌 프록시로 감싸져있는 hibernateLazyInitializer 를 직렬화 하려 하기 때문에 발생한다. 다르게 말하면 FetchType.LAZY 로 명시한 속성은 반드시 Fetch 가 완료된 뒤에 json 직렬화를 해야 한다. 만약 그게 싫다면 아래와 같이 해당 속성을 아예 직렬화에서 제외시켜야 한다. https://ahndding.tistory.co..

Backend/JPA 2022.02.14

[JPA] querydsl 정리

select 결과 일부만 가져오기 Projections 을 사용한다. Projections 을 활용하는 여러가지 방법이 있는데 가장 선호되는 방식은 @QueryProjection 이다. Projections 으로 읽어온 데이턴느 영속상태가 아니다. 즉, Dirty Checking 을 염려할 필요가 없다. Projections 은 기본이 즉시로딩이다. 지연로딩은 안되는듯? querydsl 비교식 //Standard Alternative expr isNotNull expr is not(null) expr isNull expr is null expr eq "Ben" expr === "Ben" expr ne "Ben" expr !== "Ben" expr append "X" expr + "X" expr isEmp..

Backend/JPA 2022.01.03

[JPA] 연관관계 매핑

Entity 연관관계를 매핑할 때 특별한 경우가 아니라면 단방향으로 설계가 권장된다는 말을 많이한다. 그런데 DB 테이블 설계시에는 조인을 고려하고 설계하다보니 기본적으로 양방향이 가능한 구조인데 객체만 단방향으로 설계하기란 쉽지 않다. 예를 들어 게시판을 만든다고 할 때 DB테이블은 게시글을 의미하는 Contents 테이블과 댓글을 의미하는 Reply 테이블을 생성할 것이고 외래키는 N에 해당하는 Reply 에 둘 것이다.(실무에서는 외래키 역할을 하는 칼럼을 추가하긴 하지만 제약조건까지 걸어서 사용하는 경우는 드물다) DB 입장에서 보면 join 을 통해 Contents 를 조회할 때 Reply 정보를 함께 가져올수 있고 Reply 조회시 Contents 정보를 함께 가져올 수도 있다. 어느쪽에서 출..

Backend/JPA 2021.12.17

[JPA] 대량 insert, mysql insert all

jpa 를 사용해서 대량 insert 를 해야할 일이 생겼다. 사실 딱히 대량까진 아니고 많아봐야 1,000건이란 제한이 있는 데이터였다. 그런데 이게 10초가 넘게 걸렸다. jpa에서 대량 insert 시 사용하라고 하는 saveAll 을 사용하는데도 그랬다. mybatis 환경이라면 쿼리로 insert all 를 작성해서 사용했을 것이고 이 경우 insert 하는 데이터가 1만건이 넘어가더라도 10초가 걸리진 않는다. JPA에서 saveAll 로 배치 insert 하려면 application.yml 파일에 아래 설정이 추가로 필요하다. spring.jpa.properties.hibernate.jdbc.batch_size=1000 spring.jpa.properties.hibernate.order_in..

Backend/JPA 2021.12.16

[JPA] EntityManager

JPA가 아닌 환경에서 api호출과 DB수정이 함께 필요한 로직이 있다고 가정해보자. 트랜잭션 단위로 완벽하게 묶을 순 없지만 DB수정 -> api 호출 과 같은 순서로 진행하도록 해 놓으면 api 호출에 문제가 있을 경우 RuntimeException 을 발생시켜서 DB수정을 롤백하면 된다. 하지만 JPA 환경에서는 이게 불가능하다. JPA 는 flush 단계에서 실제 DB로 쿼리를 날리고 flush는 트랜잭션이 종료된 시점에 commit 과 함께 수행되기 때문에 쿼리가 정상인지 여부를 기본적으로 트랜잭션이 종료되는 시점(일반적으로 메소드가 정상 종료된 시점)에 알 수 있다. 이에 트랜잭션으로 묶인 메소드에서 단순히 DB수정 -> api 호출 과 같은 순서로 진행하도록 구성을 해놓을 경우 DB수정 쿼리..

Backend/JPA 2021.12.08
728x90