[{"data":1,"prerenderedAt":1111},["ShallowReactive",2],{"post-document:\u002Fjava\u002Fspring\u002F2026\u002F08\u002F17\u002Fjpa-entity-manager-persistence-context\u002F":3},{"id":4,"title":5,"body":6,"categories":1090,"date":1092,"description":1093,"extension":1094,"image":1095,"key_concepts":1095,"last_modified_at":1095,"legacyPath":1096,"meta":1097,"navigation":323,"part":1099,"path":1100,"published":323,"robots":1095,"seo":1101,"series":1102,"stem":1103,"strengths":1095,"summary":1095,"tags":1104,"tradeoffs":1095,"__hash__":1110},"posts\u002Fposts\u002FBackend\u002FSPRING\u002FSpring\u002F2026-08-17-jpa-entity-manager-persistence-context.md","Spring 기초 Part 5: EntityManager와 영속성 컨텍스트",{"type":7,"value":8,"toc":1073},"minimark",[9,13,20,23,34,37,42,164,166,170,173,294,297,410,417,423,425,429,475,479,488,491,497,500,509,512,521,524,527,536,539,548,551,560,566,572,604,606,610,613,628,631,637,646,649,652,654,658,664,693,703,709,731,734,736,740,743,758,764,767,781,783,794,803,808,839,845,852,858,861,863,871,876,885,891,897,903,927,930,932,936,963,969,971,975,1040,1045,1049,1069],[10,11,5],"h2",{"id":12},"spring-기초-part-5-entitymanager와-영속성-컨텍스트",[14,15,16],"blockquote",{},[17,18,19],"p",{},"EntityManager는 Entity를 영속성 컨텍스트에서 관리하고, 데이터베이스 작업을 JPA 구현체에 요청하는 핵심 인터페이스다.",[17,21,22],{},"두 개념의 관계를 먼저 기억하자.",[24,25,31],"pre",{"className":26,"code":28,"language":29,"meta":30},[27],"language-text","EntityManager\n→ 영속성 컨텍스트를 사용해 Entity를 관리하는 관리자\n\n영속성 컨텍스트\n→ Entity의 상태를 보관하고 추적하는 논리적인 작업 공간\n","text","",[32,33,28],"code",{"__ignoreMap":30},[35,36],"hr",{},[38,39,41],"h3",{"id":40},"_1-먼저-알아둘-단어","1. 먼저 알아둘 단어",[43,44,45,61],"table",{},[46,47,48],"thead",{},[49,50,51,55,58],"tr",{},[52,53,54],"th",{},"용어",[52,56,57],{},"정의",[52,59,60],{},"쉽게 말하면",[62,63,64,76,87,98,109,120,131,142,153],"tbody",{},[49,65,66,70,73],{},[67,68,69],"td",{},"EntityManager",[67,71,72],{},"Entity의 저장, 조회, 삭제와 상태 관리를 담당하는 JPA 인터페이스",[67,74,75],{},"Entity 관리자",[49,77,78,81,84],{},[67,79,80],{},"영속성",[67,82,83],{},"애플리케이션이 종료돼도 데이터가 DB에 남는 성질",[67,85,86],{},"데이터를 계속 보관",[49,88,89,92,95],{},[67,90,91],{},"영속성 컨텍스트",[67,93,94],{},"JPA가 Entity를 관리하는 논리적인 공간",[67,96,97],{},"Entity 작업실",[49,99,100,103,106],{},[67,101,102],{},"1차 캐시",[67,104,105],{},"영속성 컨텍스트 내부의 Entity 저장 공간",[67,107,108],{},"같은 트랜잭션의 조회 결과 보관",[49,110,111,114,117],{},[67,112,113],{},"스냅샷",[67,115,116],{},"Entity를 처음 관리할 때 저장한 상태",[67,118,119],{},"변경 전 값",[49,121,122,125,128],{},[67,123,124],{},"변경 감지",[67,126,127],{},"현재 상태와 스냅샷을 비교해 변경을 찾는 기능",[67,129,130],{},"수정된 필드를 자동 확인",[49,132,133,136,139],{},[67,134,135],{},"쓰기 지연",[67,137,138],{},"쓰기 SQL을 모아두었다가 flush 시점에 전달하는 방식",[67,140,141],{},"SQL을 바로 보내지 않고 준비",[49,143,144,147,150],{},[67,145,146],{},"flush",[67,148,149],{},"영속성 컨텍스트의 변경을 SQL로 DB에 전달",[67,151,152],{},"SQL 전송",[49,154,155,158,161],{},[67,156,157],{},"commit",[67,159,160],{},"트랜잭션의 변경 내용을 최종 확정",[67,162,163],{},"저장 확정",[35,165],{},[38,167,169],{"id":168},"_2-entitymanager가-하는-일","2. EntityManager가 하는 일",[17,171,172],{},"EntityManager의 대표 메서드는 다음과 같다.",[43,174,175,188],{},[46,176,177],{},[49,178,179,182,185],{},[52,180,181],{},"메서드",[52,183,184],{},"역할",[52,186,187],{},"SQL 관점",[62,189,190,206,221,236,255,268,281],{},[49,191,192,197,200],{},[67,193,194],{},[32,195,196],{},"persist(entity)",[67,198,199],{},"새 Entity를 영속 상태로 만듦",[67,201,202,203],{},"보통 ",[32,204,205],{},"INSERT",[49,207,208,213,216],{},[67,209,210],{},[32,211,212],{},"find(type, id)",[67,214,215],{},"기본키로 Entity 조회",[67,217,218],{},[32,219,220],{},"SELECT",[49,222,223,228,231],{},[67,224,225],{},[32,226,227],{},"remove(entity)",[67,229,230],{},"Entity를 삭제 상태로 만듦",[67,232,233],{},[32,234,235],{},"DELETE",[49,237,238,243,246],{},[67,239,240],{},[32,241,242],{},"merge(entity)",[67,244,245],{},"준영속 Entity의 값을 새 영속 Entity에 복사",[67,247,248,250,251,254],{},[32,249,220],{},", ",[32,252,253],{},"UPDATE"," 가능",[49,256,257,262,265],{},[67,258,259],{},[32,260,261],{},"flush()",[67,263,264],{},"변경 내용을 DB에 전달",[67,266,267],{},"쓰기 SQL 실행",[49,269,270,275,278],{},[67,271,272],{},[32,273,274],{},"detach(entity)",[67,276,277],{},"특정 Entity를 관리 대상에서 제외",[67,279,280],{},"자동 변경 감지 중단",[49,282,283,288,291],{},[67,284,285],{},[32,286,287],{},"clear()",[67,289,290],{},"영속성 컨텍스트를 비움",[67,292,293],{},"관리 중인 Entity 전체 분리",[17,295,296],{},"직접 사용하는 Repository를 만들면 다음과 같은 모습이다.",[24,298,302],{"className":299,"code":300,"language":301,"meta":30,"style":30},"language-java shiki shiki-themes github-light github-dark","@Repository\npublic class UserJpaRepository {\n\n    @PersistenceContext\n    private EntityManager entityManager;\n\n    public void save(User user) {\n        entityManager.persist(user);\n    }\n\n    public User findById(Long id) {\n        return entityManager.find(User.class, id);\n    }\n\n    public void delete(User user) {\n        entityManager.remove(user);\n    }\n}\n","java",[32,303,304,312,318,325,331,337,342,348,354,360,365,371,377,382,387,393,399,404],{"__ignoreMap":30},[305,306,309],"span",{"class":307,"line":308},"line",1,[305,310,311],{},"@Repository\n",[305,313,315],{"class":307,"line":314},2,[305,316,317],{},"public class UserJpaRepository {\n",[305,319,321],{"class":307,"line":320},3,[305,322,324],{"emptyLinePlaceholder":323},true,"\n",[305,326,328],{"class":307,"line":327},4,[305,329,330],{},"    @PersistenceContext\n",[305,332,334],{"class":307,"line":333},5,[305,335,336],{},"    private EntityManager entityManager;\n",[305,338,340],{"class":307,"line":339},6,[305,341,324],{"emptyLinePlaceholder":323},[305,343,345],{"class":307,"line":344},7,[305,346,347],{},"    public void save(User user) {\n",[305,349,351],{"class":307,"line":350},8,[305,352,353],{},"        entityManager.persist(user);\n",[305,355,357],{"class":307,"line":356},9,[305,358,359],{},"    }\n",[305,361,363],{"class":307,"line":362},10,[305,364,324],{"emptyLinePlaceholder":323},[305,366,368],{"class":307,"line":367},11,[305,369,370],{},"    public User findById(Long id) {\n",[305,372,374],{"class":307,"line":373},12,[305,375,376],{},"        return entityManager.find(User.class, id);\n",[305,378,380],{"class":307,"line":379},13,[305,381,359],{},[305,383,385],{"class":307,"line":384},14,[305,386,324],{"emptyLinePlaceholder":323},[305,388,390],{"class":307,"line":389},15,[305,391,392],{},"    public void delete(User user) {\n",[305,394,396],{"class":307,"line":395},16,[305,397,398],{},"        entityManager.remove(user);\n",[305,400,402],{"class":307,"line":401},17,[305,403,359],{},[305,405,407],{"class":307,"line":406},18,[305,408,409],{},"}\n",[17,411,412,413,416],{},"Spring Data JPA의 ",[32,414,415],{},"JpaRepository","도 내부적으로 EntityManager를 사용한다.",[24,418,421],{"className":419,"code":420,"language":29,"meta":30},[27],"내 코드\n  → JpaRepository\n  → EntityManager\n  → Hibernate\n  → JDBC\n  → Database\n",[32,422,420],{"__ignoreMap":30},[35,424],{},[38,426,428],{"id":427},"_3-entity의-네-가지-상태","3. Entity의 네 가지 상태",[43,430,431,441],{},[46,432,433],{},[49,434,435,438],{},[52,436,437],{},"상태",[52,439,440],{},"의미",[62,442,443,451,459,467],{},[49,444,445,448],{},[67,446,447],{},"비영속(New\u002FTransient)",[67,449,450],{},"객체는 있지만 JPA가 관리하지 않는 상태",[49,452,453,456],{},[67,454,455],{},"영속(Managed)",[67,457,458],{},"영속성 컨텍스트가 관리하는 상태",[49,460,461,464],{},[67,462,463],{},"준영속(Detached)",[67,465,466],{},"한때 관리됐지만 현재는 분리된 상태",[49,468,469,472],{},[67,470,471],{},"삭제(Removed)",[67,473,474],{},"삭제하도록 등록된 상태",[476,477,478],"h4",{"id":478},"비영속",[24,480,482],{"className":299,"code":481,"language":301,"meta":30,"style":30},"User user = new User(\"민형\", \"min@example.com\");\n",[32,483,484],{"__ignoreMap":30},[305,485,486],{"class":307,"line":308},[305,487,481],{},[17,489,490],{},"일반 자바 객체만 생성된 상태다.",[24,492,495],{"className":493,"code":494,"language":29,"meta":30},[27],"Java 메모리: User 객체 있음\n영속성 컨텍스트: 등록되지 않음\nDatabase: 저장되지 않음\n",[32,496,494],{"__ignoreMap":30},[476,498,499],{"id":499},"영속",[24,501,503],{"className":299,"code":502,"language":301,"meta":30,"style":30},"entityManager.persist(user);\n",[32,504,505],{"__ignoreMap":30},[305,506,507],{"class":307,"line":308},[305,508,502],{},[17,510,511],{},"또는 EntityManager로 조회한 객체도 영속 상태가 된다.",[24,513,515],{"className":299,"code":514,"language":301,"meta":30,"style":30},"User user = entityManager.find(User.class, 1L);\n",[32,516,517],{"__ignoreMap":30},[305,518,519],{"class":307,"line":308},[305,520,514],{},[17,522,523],{},"영속 상태가 되면 JPA가 객체의 변경을 추적한다.",[476,525,526],{"id":526},"준영속",[24,528,530],{"className":299,"code":529,"language":301,"meta":30,"style":30},"entityManager.detach(user);\n",[32,531,532],{"__ignoreMap":30},[305,533,534],{"class":307,"line":308},[305,535,529],{},[17,537,538],{},"영속성 컨텍스트에서 분리된 객체는 값을 바꿔도 변경 감지가 동작하지 않는다.",[24,540,542],{"className":299,"code":541,"language":301,"meta":30,"style":30},"user.changeName(\"민농\"); \u002F\u002F 자동 UPDATE 대상이 아님\n",[32,543,544],{"__ignoreMap":30},[305,545,546],{"class":307,"line":308},[305,547,541],{},[476,549,550],{"id":550},"삭제",[24,552,554],{"className":299,"code":553,"language":301,"meta":30,"style":30},"entityManager.remove(user);\n",[32,555,556],{"__ignoreMap":30},[305,557,558],{"class":307,"line":308},[305,559,553],{},[17,561,562,563,565],{},"Entity가 삭제 대상으로 등록되고 flush 시점에 ",[32,564,235],{}," SQL이 전달된다.",[17,567,568],{},[569,570,571],"strong",{},"Entity 생명주기",[24,573,577],{"className":574,"code":575,"language":576,"meta":30,"style":30},"language-mermaid shiki shiki-themes github-light github-dark","flowchart LR\n    N[비영속] -->|persist| M[영속]\n    M -->|detach, clear| D[준영속]\n    D -->|merge 후 반환 객체| M\n    M -->|remove| R[삭제]\n","mermaid",[32,578,579,584,589,594,599],{"__ignoreMap":30},[305,580,581],{"class":307,"line":308},[305,582,583],{},"flowchart LR\n",[305,585,586],{"class":307,"line":314},[305,587,588],{},"    N[비영속] -->|persist| M[영속]\n",[305,590,591],{"class":307,"line":320},[305,592,593],{},"    M -->|detach, clear| D[준영속]\n",[305,595,596],{"class":307,"line":327},[305,597,598],{},"    D -->|merge 후 반환 객체| M\n",[305,600,601],{"class":307,"line":333},[305,602,603],{},"    M -->|remove| R[삭제]\n",[35,605],{},[38,607,609],{"id":608},"_4-1차-캐시와-동일성-보장","4. 1차 캐시와 동일성 보장",[17,611,612],{},"영속성 컨텍스트는 관리 중인 Entity를 기본키 기준으로 1차 캐시에 보관한다.",[24,614,616],{"className":299,"code":615,"language":301,"meta":30,"style":30},"User user1 = entityManager.find(User.class, 1L);\nUser user2 = entityManager.find(User.class, 1L);\n",[32,617,618,623],{"__ignoreMap":30},[305,619,620],{"class":307,"line":308},[305,621,622],{},"User user1 = entityManager.find(User.class, 1L);\n",[305,624,625],{"class":307,"line":314},[305,626,627],{},"User user2 = entityManager.find(User.class, 1L);\n",[17,629,630],{},"첫 조회는 DB에서 데이터를 가져와 1차 캐시에 저장한다. 같은 영속성 컨텍스트에서 다시 조회하면 1차 캐시의 객체를 반환할 수 있다.",[24,632,635],{"className":633,"code":634,"language":29,"meta":30},[27],"첫 번째 find()\n→ 1차 캐시에 없음\n→ SELECT 실행\n→ 조회 결과를 1차 캐시에 저장\n\n두 번째 find()\n→ 1차 캐시에서 발견\n→ 같은 Entity 객체 반환\n",[32,636,634],{"__ignoreMap":30},[24,638,640],{"className":299,"code":639,"language":301,"meta":30,"style":30},"System.out.println(user1 == user2); \u002F\u002F true\n",[32,641,642],{"__ignoreMap":30},[305,643,644],{"class":307,"line":308},[305,645,639],{},[17,647,648],{},"이처럼 같은 영속성 컨텍스트에서 같은 기본키의 Entity에 대해 같은 객체 참조를 제공하는 것을 동일성 보장이라고 한다.",[17,650,651],{},"1차 캐시는 보통 하나의 트랜잭션처럼 짧은 범위에서 사용되므로 애플리케이션 전체의 공용 캐시와는 다르다.",[35,653],{},[38,655,657],{"id":656},"_5-변경-감지","5. 변경 감지",[17,659,660,661,663],{},"변경 감지(Dirty Checking)는 영속 상태의 Entity가 변경됐는지 확인하여 ",[32,662,253],{}," SQL을 만드는 기능이다.",[24,665,667],{"className":299,"code":666,"language":301,"meta":30,"style":30},"@Transactional\npublic void changeName(Long id, String newName) {\n    User user = entityManager.find(User.class, id);\n    user.changeName(newName);\n}\n",[32,668,669,674,679,684,689],{"__ignoreMap":30},[305,670,671],{"class":307,"line":308},[305,672,673],{},"@Transactional\n",[305,675,676],{"class":307,"line":314},[305,677,678],{},"public void changeName(Long id, String newName) {\n",[305,680,681],{"class":307,"line":320},[305,682,683],{},"    User user = entityManager.find(User.class, id);\n",[305,685,686],{"class":307,"line":327},[305,687,688],{},"    user.changeName(newName);\n",[305,690,691],{"class":307,"line":333},[305,692,409],{},[17,694,695,698,699,702],{},[32,696,697],{},"update()","나 ",[32,700,701],{},"save()","를 따로 호출하지 않아도 트랜잭션이 끝날 때 변경이 반영될 수 있다.",[24,704,707],{"className":705,"code":706,"language":29,"meta":30},[27],"1. User 조회\n2. 조회 당시 상태를 스냅샷으로 보관\n3. user.changeName() 호출\n4. flush 시 현재 상태와 스냅샷 비교\n5. 변경 발견\n6. UPDATE SQL 실행\n",[32,708,706],{"__ignoreMap":30},[24,710,714],{"className":711,"code":712,"language":713,"meta":30,"style":30},"language-sql shiki shiki-themes github-light github-dark","UPDATE users\nSET name = '민농'\nWHERE id = 1;\n","sql",[32,715,716,721,726],{"__ignoreMap":30},[305,717,718],{"class":307,"line":308},[305,719,720],{},"UPDATE users\n",[305,722,723],{"class":307,"line":314},[305,724,725],{},"SET name = '민농'\n",[305,727,728],{"class":307,"line":320},[305,729,730],{},"WHERE id = 1;\n",[17,732,733],{},"변경 감지는 영속 상태의 Entity에만 적용된다.",[35,735],{},[38,737,739],{"id":738},"_6-쓰기-지연","6. 쓰기 지연",[17,741,742],{},"JPA는 쓰기 SQL을 준비해두었다가 flush 시점에 DB로 전달할 수 있다.",[24,744,746],{"className":299,"code":745,"language":301,"meta":30,"style":30},"entityManager.persist(user1);\nentityManager.persist(user2);\n",[32,747,748,753],{"__ignoreMap":30},[305,749,750],{"class":307,"line":308},[305,751,752],{},"entityManager.persist(user1);\n",[305,754,755],{"class":307,"line":314},[305,756,757],{},"entityManager.persist(user2);\n",[24,759,762],{"className":760,"code":761,"language":29,"meta":30},[27],"persist(user1) → INSERT 준비\npersist(user2) → INSERT 준비\nflush          → SQL을 DB에 전달\ncommit         → 트랜잭션 확정\n",[32,763,761],{"__ignoreMap":30},[17,765,766],{},"이 방식을 쓰기 지연(Write Behind)이라고 한다.",[17,768,769,770,773,774,777,778,780],{},"다만 모든 SQL이 반드시 커밋 직전에만 실행되는 것은 아니다. 예를 들어 ",[32,771,772],{},"IDENTITY"," 기본키 전략은 생성된 ID를 얻기 위해 ",[32,775,776],{},"persist()"," 시점에 ",[32,779,205],{},"가 먼저 실행될 수 있다.",[35,782],{},[38,784,786,787,789,790,793],{"id":785},"_7-flush와-commit의-차이","7. ",[32,788,261],{},"와 ",[32,791,792],{},"commit()","의 차이",[24,795,797],{"className":299,"code":796,"language":301,"meta":30,"style":30},"entityManager.flush();\n",[32,798,799],{"__ignoreMap":30},[305,800,801],{"class":307,"line":308},[305,802,796],{},[17,804,805,807],{},[32,806,261],{},"는 변경 내용을 SQL로 DB에 전달하지만 트랜잭션을 최종 확정하지는 않는다.",[43,809,810,819],{},[46,811,812],{},[49,813,814,817],{},[52,815,816],{},"구분",[52,818,184],{},[62,820,821,830],{},[49,822,823,827],{},[67,824,825],{},[32,826,261],{},[67,828,829],{},"변경 내용을 SQL로 DB에 전달",[49,831,832,836],{},[67,833,834],{},[32,835,792],{},[67,837,838],{},"트랜잭션 변경을 최종 확정",[24,840,843],{"className":841,"code":842,"language":29,"meta":30},[27],"flush 실행\n  → SQL은 DB에 전달됨\n  → 아직 commit 전\n  → 오류 발생 시 rollback 가능\n",[32,844,842],{"__ignoreMap":30},[17,846,847,848,851],{},"일반적으로 ",[32,849,850],{},"@Transactional"," 메서드가 정상 종료될 때 다음 과정이 진행된다.",[24,853,856],{"className":854,"code":855,"language":29,"meta":30},[27],"메서드 정상 종료\n   ↓\nflush\n   ↓\n쓰기 SQL 실행\n   ↓\ncommit\n",[32,857,855],{"__ignoreMap":30},[17,859,860],{},"JPQL 쿼리를 실행하기 전에 조회 결과의 일관성을 맞추기 위해 flush가 먼저 발생할 수도 있다.",[35,862],{},[38,864,866,867,870],{"id":865},"_8-merge-주의점","8. ",[32,868,869],{},"merge()"," 주의점",[17,872,873,875],{},[32,874,869],{},"는 전달받은 준영속 객체 자체를 다시 영속 상태로 바꾸는 메서드가 아니다.",[24,877,879],{"className":299,"code":878,"language":301,"meta":30,"style":30},"User managedUser = entityManager.merge(detachedUser);\n",[32,880,881],{"__ignoreMap":30},[305,882,883],{"class":307,"line":308},[305,884,878],{},[24,886,889],{"className":887,"code":888,"language":29,"meta":30},[27],"detachedUser → 여전히 준영속\nmanagedUser  → merge가 반환한 영속 객체\n",[32,890,888],{"__ignoreMap":30},[17,892,893,894,896],{},"따라서 ",[32,895,869],{},"를 사용할 때는 반환 객체를 사용해야 한다.",[17,898,899,900,902],{},"실무에서는 준영속 Entity 전체를 ",[32,901,869],{},"하기보다 트랜잭션 안에서 Entity를 다시 조회하고 필요한 값만 변경하는 방식을 자주 사용한다.",[24,904,905],{"className":299,"code":666,"language":301,"meta":30,"style":30},[32,906,907,911,915,919,923],{"__ignoreMap":30},[305,908,909],{"class":307,"line":308},[305,910,673],{},[305,912,913],{"class":307,"line":314},[305,914,678],{},[305,916,917],{"class":307,"line":320},[305,918,683],{},[305,920,921],{"class":307,"line":327},[305,922,688],{},[305,924,925],{"class":307,"line":333},[305,926,409],{},[17,928,929],{},"이 방식은 어떤 필드가 변경되는지 코드에서 명확하게 확인할 수 있다.",[35,931],{},[38,933,935],{"id":934},"_9-실제-service-실행-흐름","9. 실제 Service 실행 흐름",[24,937,939],{"className":299,"code":938,"language":301,"meta":30,"style":30},"@Transactional\npublic void updateUser(Long id, String newName) {\n    User user = userRepository.findById(id).orElseThrow();\n    user.changeName(newName);\n}\n",[32,940,941,945,950,955,959],{"__ignoreMap":30},[305,942,943],{"class":307,"line":308},[305,944,673],{},[305,946,947],{"class":307,"line":314},[305,948,949],{},"public void updateUser(Long id, String newName) {\n",[305,951,952],{"class":307,"line":320},[305,953,954],{},"    User user = userRepository.findById(id).orElseThrow();\n",[305,956,957],{"class":307,"line":327},[305,958,688],{},[305,960,961],{"class":307,"line":333},[305,962,409],{},[24,964,967],{"className":965,"code":966,"language":29,"meta":30},[27],"1. @Transactional로 트랜잭션 시작\n2. EntityManager가 영속성 컨텍스트 사용\n3. User 조회\n4. User가 영속 상태가 됨\n5. 이름 변경\n6. 트랜잭션 종료 직전 변경 감지\n7. UPDATE SQL 실행\n8. commit\n9. 영속성 컨텍스트 범위 종료\n",[32,968,966],{"__ignoreMap":30},[35,970],{},[38,972,974],{"id":973},"핵심-정리","핵심 정리",[43,976,977,987],{},[46,978,979],{},[49,980,981,984],{},[52,982,983],{},"개념",[52,985,986],{},"한 줄 정리",[62,988,989,996,1003,1010,1020,1027,1034],{},[49,990,991,993],{},[67,992,69],{},[67,994,995],{},"Entity의 저장, 조회, 삭제와 상태를 관리",[49,997,998,1000],{},[67,999,91],{},[67,1001,1002],{},"Entity를 보관하고 변경을 추적하는 논리적인 공간",[49,1004,1005,1007],{},[67,1006,102],{},[67,1008,1009],{},"같은 영속성 컨텍스트에서 조회한 Entity 보관",[49,1011,1012,1014],{},[67,1013,124],{},[67,1015,1016,1017,1019],{},"영속 Entity의 변경을 찾아 ",[32,1018,253],{}," 실행",[49,1021,1022,1024],{},[67,1023,135],{},[67,1025,1026],{},"쓰기 SQL을 준비했다가 flush 시 전달",[49,1028,1029,1031],{},[67,1030,146],{},[67,1032,1033],{},"SQL을 DB에 전달하지만 확정하지는 않음",[49,1035,1036,1038],{},[67,1037,157],{},[67,1039,838],{},[14,1041,1042],{},[17,1043,1044],{},"EntityManager의 핵심은 SQL 메서드를 대신 제공하는 것보다 Entity의 생명주기와 상태를 관리하는 데 있다.",[38,1046,1048],{"id":1047},"참고-자료","참고 자료",[1050,1051,1052,1062],"ul",{},[1053,1054,1055],"li",{},[1056,1057,1061],"a",{"href":1058,"rel":1059},"https:\u002F\u002Fjakarta.ee\u002Fspecifications\u002Fpersistence\u002F",[1060],"nofollow","Jakarta Persistence 공식 명세",[1053,1063,1064],{},[1056,1065,1068],{"href":1066,"rel":1067},"https:\u002F\u002Fdocs.jboss.org\u002Fhibernate\u002Form\u002Fcurrent\u002Fuserguide\u002Fhtml_single\u002FHibernate_User_Guide.html",[1060],"Hibernate ORM User Guide",[1070,1071,1072],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":30,"searchDepth":314,"depth":314,"links":1074},[1075],{"id":12,"depth":314,"text":5,"children":1076},[1077,1078,1079,1080,1081,1082,1083,1085,1087,1088,1089],{"id":40,"depth":320,"text":41},{"id":168,"depth":320,"text":169},{"id":427,"depth":320,"text":428},{"id":608,"depth":320,"text":609},{"id":656,"depth":320,"text":657},{"id":738,"depth":320,"text":739},{"id":785,"depth":320,"text":1084},"7. flush()와 commit()의 차이",{"id":865,"depth":320,"text":1086},"8. merge() 주의점",{"id":934,"depth":320,"text":935},{"id":973,"depth":320,"text":974},{"id":1047,"depth":320,"text":1048},[301,1091],"spring","2026-08-17 09:00:00 +0900","EntityManager의 역할, Entity 생명주기, 1차 캐시, 변경 감지, 쓰기 지연, flush와 commit의 차이를 정리한다.","md",null,"\u002Fjava\u002Fspring\u002F2026\u002F08\u002F17\u002Fjpa-entity-manager-persistence-context\u002F",{"layout":1098},"post","5","\u002Fposts\u002Fbackend\u002Fspring\u002Fspring\u002F2026-08-17-jpa-entity-manager-persistence-context",{"title":5,"description":1093},"Spring 기초","posts\u002FBackend\u002FSPRING\u002FSpring\u002F2026-08-17-jpa-entity-manager-persistence-context",[1105,1106,1107,69,1108,1109],"Java","Spring","JPA","Persistence Context","Dirty Checking","y39nI_hxsg27O7aMX3pYbajmEcJmPGZ4yeHzbhPW-4E",1788744786249]