Bulk & History

save lifecycle이 적용되는 일반 저장과 bulk insert/upsert, remove backup, history snapshot의 동작 차이를 구분합니다.


save / saveAll

save(entity)

id가 없으면 insertOne, id가 있으면 _id 기준 replaceOne(..., upsert=true)를 사용합니다.

saveAll(...)

각 entity에 대해 save()를 수행하므로 beforePersist/afterPersist lifecycle hook이 적용됩니다.

Bulk API 선택

saveAllBulk

insertMany 기반 bulk insert입니다. 기존 id를 update하는 API가 아닙니다.

saveAllBulkUpsert

entity id가 없으면 insert, 있으면 _id filter + $set + upsert를 수행합니다.

saveAllBulkUpsertByKey

업무 복합키를 기준으로 upsert합니다. key 중 하나라도 없으면 해당 entity는 insert로 처리합니다.

java
Mono<BulkWriteResult> result = dsl
    .executeEntity(Auction.class, MongoTemplateName.FRONT)
    .saveAllBulkUpsertByKey(
        auctions,
        "caseNo",
        "caseYear",
        "court"
    );

Entity delete와 remove backup

java
dsl.executeEntity(User.class, key).delete(user);
dsl.executeEntity(User.class, key).delete(user, true);
dsl.executeEntity(User.class, key).deleteBulk(users, true);

backup을 활성화하면 <sourceCollection>_remove collection을 사용합니다. delete와 backup을 하나의 원자 작업으로 묶어야 한다면 호출 측에서 getTxJob(...) transaction 범위를 잡습니다.

History snapshot

java
dsl.executeEntity(User.class, key).createHistory(user);
dsl.executeEntity(User.class, key).createHistory(user, "snapshot");

createHistory는 현재 MongoExecutionContext.write(...) 결과를 deep copy하고 _id를 제거한 뒤 <sourceCollection>_history 또는 지정한 prefix collection에 insert합니다. history write도 save lifecycle hook을 호출하지 않습니다.

© 2026 Byeolnaerim. All rights reserved.소개개인정보처리방침