작성
·
52
·
수정됨
0
안녕하세요
토비님 강의 듣고나서 제 나름대로 API 서버 제작 연습을 좀 해보도가 JPA 및 도메인 상태 변경에 관련해서 질문 드리고 조언을 얻고자 문의 드립니다.
상황은 아래와 같습니다.
DDD에 입각하여 Aggregator 가 하위 Entity Life Cycle 담당
Entity 식별자 타입 경우 Long
Client 에서 변경 API 요청 시 Aggregator 의 식별자는 존재하지만, 하위 Entity 에 대한 id 는 포함하지않은채 요청
{
id: AggregatorId
name: AggregatorName
list: [
{
name: 'modified name1',
type: 'type1',
status: 'active'
},
{
name: 'modified name2',
type: 'type2',
status: 'inactive'
},
{
name: 'new name3',
type: 'type3',
status: 'active'
}
]
}
id 가 없이 JPA 변경 요청 시 delete-insert 가 진행 될것 같아 자체적으로 key based diff 라는 함수를 제작하여 변경점과 신규 데이터에 대해서 병합 후 save() 를 호출 할 것같은데 이럴 경우 insert, update 문의 별도로 나가지 않을까 생각이 듭니다.
이런 경우 DB 입장에서 하나의 트랜잭션에서 수행하더라도 부하나 성능에 악영향을 미칠 것 같은데 이럴 경우 어떤식으로 애플리케이션 로직을 세우고 JPA 를 어떻게 활용해야되는지 조언 부탁드려도될까요?
참고로 저는 하위 Entity 변경 시 batchUpsert 를 고려하고 있습니다.
답변 1
0
안녕하세요, 인프런 AI 인턴입니다.
김태형님께서 설명해주신 상황에서 JPA와 관련된 효율적인 방식에 대한 조언을 드리겠습니다.
현재 상황에서는 클라이언트로부터 전송된 데이터에서 하위 엔티티 식별자가 없기 때문에, JPA는 기존 데이터를 삭제하고 새로운 데이터를 삽입하는 delete-insert 방식으로 동작할 가능성이 큽니다. 이로 인해 불필요한 부하가 발생할 수 있습니다.
이를 해결하기 위한 몇 가지 방법을 제안드리겠습니다:
Key Based Diff 사용: 말씀하신 것처럼 key based diff 함수를 통해 기존 하위 엔티티와 변경된 데이터를 비교하여 변경된 데이터만 업데이트하고, 새 데이터만 추가하는 방법을 고려할 수 있습니다. 이 때, 비효율적인 delete-insert를 피하기 위해 명시적인 merge
또는 persist
메서드를 통한 update와 insert를 사용할 수 있습니다.
Batch Update/Insert 전략: 하위 엔티티의 변경을 일괄 처리하기 위해 JPA의 벌크 연산(Batch Process)를 활용하는 것도 좋은 방법입니다. 이 방법은 일반적으로 직접적인 EntityManager
를 이용하거나, JPQL 또는 Criteria API를 사용하여 수행할 수 있습니다.
Optimistic Locking: 성능 부하를 고려할 때 중요한 것은 동시에 발생하는 여러 수정 작업을 안전하게 관리하는 것입니다. 이를 위해 Optimistic Locking을 설정하여, 수정 충돌을 최대한 배제하고, 충돌 시 적절한 에러 핸들링을 통해 일관성을 유지할 수 있습니다.
Native Query 사용: 복잡한 변경 작업이나 성능 이슈가 우려되는 경우에는 필요에 따라 JPA가 아닌 네이티브 쿼리를 활용하여 데이터베이스의 고유 기능을 사용하는 것도 고려해볼 수 있습니다.
추가적으로, JPA의 기능을 충분히 활용하면서도 상황에 따라 데이터 처리의 책임을 서비스 레이어에서 명확히 구분하여 Entity 관리의 복잡성을 줄이고 성능 최적화를 도모하는 것이 좋습니다.
추가적인 참고 자료가 필요하시면 Spring Data JPA - Auditing을 참고해주세요. 도움이 되셨길 바랍니다!