문제

EntityManager.merge() 새 객체를 삽입하고 기존 객체를 업데이트할 수 있습니다.

왜 사용하고 싶습니까? persist() (새 객체만 생성할 수 있음)?

도움이 되었습니까?

해결책

어느 쪽이든, 엔티티를 PersistenceContext에 추가하면 차이점은 나중에 엔티티와 함께하는 일에 차이가 있습니다.

지속적인 엔티티 인스턴스를 가져 와서 컨텍스트에 추가하고 인스턴스를 관리합니다 (즉, 엔티티에 대한 향후 업데이트가 추적됩니다).

Merge는 귀하의 엔티티의 새 인스턴스를 생성하고, 공급 된 엔티티에서 주를 복사하고, 새 사본을 관리합니다. 통과하는 인스턴스는 관리되지 않습니다 (변경 사항은 거래의 일부가 아닙니다.

코드 예제가 도움이 될 수 있습니다.

MyEntity e = new MyEntity();

// scenario 1
// tran starts
em.persist(e); 
e.setSomeField(someValue); 
// tran ends, and the row for someField is updated in the database

// scenario 2
// tran starts
e = new MyEntity();
em.merge(e);
e.setSomeField(anotherValue); 
// tran ends but the row for someField is not updated in the database
// (you made the changes *after* merging)

// scenario 3
// tran starts
e = new MyEntity();
MyEntity e2 = em.merge(e);
e2.setSomeField(anotherValue); 
// tran ends and the row for someField is updated
// (the changes were made to e2, not e)

시나리오 1과 3은 대략 동일하지만 시나리오 2를 사용하려는 상황이 있습니다.

다른 팁

지속과 병합은 두 가지 다른 목적을위한 것입니다 (전혀 대안이 아닙니다).

(차이를 확장하기 위해 편집)

지속 :

  • 데이터베이스에 새 레지스터를 삽입하십시오
  • 개체를 엔티티 관리자에 첨부하십시오.

병합 :

  • 동일한 ID가있는 첨부 된 객체를 찾고 업데이트하십시오.
  • 존재하는 경우 업데이트하고 이미 첨부 된 객체를 반환하십시오.
  • 존재하지 않으면 새 레지스터를 데이터베이스에 삽입하십시오.

지속 () 효율성 :

  • merge ()보다 데이터베이스에 새 레지스터를 삽입하는 것이 더 효율적일 수 있습니다.
  • 원래 객체를 복제하지 않습니다.

지속 () 의미론 :

  • 실수로 삽입하고 업데이트하지 않도록합니다.

예시:

{
    AnyEntity newEntity;
    AnyEntity nonAttachedEntity;
    AnyEntity attachedEntity;

    // Create a new entity and persist it        
    newEntity = new AnyEntity();
    em.persist(newEntity);

    // Save 1 to the database at next flush
    newEntity.setValue(1);

    // Create a new entity with the same Id than the persisted one.
    AnyEntity nonAttachedEntity = new AnyEntity();
    nonAttachedEntity.setId(newEntity.getId());

    // Save 2 to the database at next flush instead of 1!!!
    nonAttachedEntity.setValue(2);
    attachedEntity = em.merge(nonAttachedEntity);

    // This condition returns true
    // merge has found the already attached object (newEntity) and returns it.
    if(attachedEntity==newEntity) {
            System.out.print("They are the same object!");
    }

    // Set 3 to value
    attachedEntity.setValue(3);
    // Really, now both are the same object. Prints 3
    System.out.println(newEntity.getValue());

    // Modify the un attached object has no effect to the entity manager
    // nor to the other objects
    nonAttachedEntity.setValue(42);
}

이 방법은 엔티티 관리자의 모든 레지스터에 대해 1 첨부 된 객체 만 존재합니다.

ID가있는 엔티티의 MERGE ()는 다음과 같습니다.

AnyEntity myMerge(AnyEntity entityToSave) {
    AnyEntity attached = em.find(AnyEntity.class, entityToSave.getId());
    if(attached==null) {
            attached = new AnyEntity();
            em.persist(attached);
    }
    BeanUtils.copyProperties(attached, entityToSave);

    return attached;
}

MySQL Merge ()에 연결된 경우 Duplication Key Update 옵션에 삽입을 사용하여 Call을 사용하여 persist ()만큼 효율적일 수 있지만 JPA는 매우 높은 레벨 프로그래밍이며 어디에서나 그렇다고 가정 할 수는 없습니다.

할당 된 발전기를 사용하는 경우 지속 대신 병합을 사용하면 중복 SQL 문이 발생할 수 있습니다., 따라서 성능에 영향을 미칩니다.

또한, 관리 엔터티의 합병 전화 관리 된 엔티티가 Hibernate에 의해 자동으로 관리되고 해당 상태가 데이터베이스 레코드와 동기화되므로 실수입니다. 더러운 검사 메커니즘 ...에 지속성 컨텍스트를 플러시합니다.

이 모든 것이 어떻게 작동하는지 이해하려면 먼저 최대 절전 모드가 개발자 마인드를 SQL 문에서로 바꾸는 것을 알아야합니다. 엔티티 상태 전환.

엔티티가 최대 절전 모드에 의해 적극적으로 관리되면 모든 변경 사항은 데이터베이스로 자동 전파됩니다.

최대 절전 모니터는 현재 부착 된 엔티티입니다. 그러나 엔티티가 관리 되려면 올바른 엔티티 상태에 있어야합니다.

먼저 모든 엔티티 상태를 정의해야합니다.

  • 신규 (과도)

    최대 절전 모드와 관련이없는 새로 생성 된 물체 Session (일명 Persistence Context)) 데이터베이스 테이블 행에 매핑되지 않음은 새로운 (과도) 상태로 간주됩니다.

    지속 되려면 우리는 명시 적으로 전화해야합니다. EntityManager#persist 전이 지속 메커니즘을 방법 또는 사용하십시오.

  • 영구 (관리)

    영구 엔티티는 데이터베이스 테이블 행과 관련되어 있으며 현재 실행중인 지속 컨텍스트에 의해 관리되고 있습니다. 해당 엔티티에 대한 변경 사항은 데이터베이스 (세션 플러시 타임 중)로 감지 및 전파됩니다. 최대 절전 모드를 사용하면 더 이상 삽입/업데이트/삭제 명령문을 실행할 필요가 없습니다. 최대 절전 모드는 a 트랜잭션 쓰기-비만 작업 스타일과 변경 사항은 현재 동안 마지막으로 책임있는 순간에 동기화됩니다. Session 플러시 타임.

  • 떨어져 있는

    현재 실행중인 지속 컨텍스트가 닫히면 이전에 관리 된 모든 엔티티가 분리됩니다. 연속적인 변경 사항은 더 이상 추적되지 않으며 자동 데이터베이스 동기화가 발생하지 않습니다.

    분리 된 엔티티를 활성 최대 절전 모드 세션에 연결하려면 다음 옵션 중 하나를 선택할 수 있습니다.

    • 재구성

      최대 절전 모드 (JPA 2.1은 아님)는 세션#업데이트 메소드를 통해 재 부패를 지원합니다. 최대 절전 모드 세션은 주어진 데이터베이스 행에 대해 하나의 엔티티 객체 만 연결할 수 있습니다. 이는 지속성 컨텍스트가 메모리 인 캐시 (1 레벨 캐시) 역할을하고 하나의 값 (엔티티) 만 주어진 키 (엔티티 유형 및 데이터베이스 식별자)와 관련되기 때문입니다. 현재 최대 절전 모드 세션과 이미 관련된 다른 JVM 객체 (동일한 데이터베이스 행과 일치)가없는 경우에만 엔티티를 다시 잡을 수 있습니다.

    • 병합

    병합은 분리 된 엔티티 상태 (소스)를 관리 된 엔티티 인스턴스 (대상)에 복사합니다. 병합 엔티티가 현재 세션에서 동등하지 않은 경우 데이터베이스에서 가져 오게됩니다. 분리 된 객체 인스턴스는 병합 작업 후에도 계속 분리됩니다.

  • 제거됨

    JPA는 관리 된 엔티티 만 제거 할 수 있다고 요구하지만 Hibernate는 분리 된 엔티티를 삭제할 수도 있지만 세션#삭제 메소드 호출을 통해서만). 제거 된 엔티티는 삭제를 위해서만 예약되며 실제 데이터베이스 삭제 명령문은 세션 플러시 시간 중에 실행됩니다.

JPA 상태 전환을 더 잘 이해하려면 다음 다이어그램을 시각화 할 수 있습니다.

enter image description here

또는 최대 절전 모드 특정 API를 사용하는 경우 :

enter image description here

나는 내가 사용할 때를 알아 차렸다 em.merge, 나는 얻었다 SELECT 모든 진술 INSERT, JPA가 나를 위해 생성하는 필드가 없더라도, 주요 키 필드는 내가 스스로 설정 한 UUID였습니다. 나는 전환했다 em.persist(myEntityObject) 그리고 그냥 얻었습니다 INSERT 그러면 진술.

JPA 사양은 다음과 같습니다 persist().

만약에 엑스 분리 된 물체입니다 EntityExistsException 지속 작업이 호출되거나 EntityExistsException 또는 다른 PersistenceException 플러시 또는 커밋 시간에 던져 질 수 있습니다.

그래서 사용 persist() 물체 일 때는 적합합니다 그렇지 않습니다 분리 된 물체가되기 위해. 코드를 던지는 것을 선호 할 수도 있습니다 PersistenceException 그래서 그것은 빠르게 실패합니다.

하지만 사양은 불분명합니다, persist() 설정할 수 있습니다 @GeneratedValue @Id 물체를 위해. merge() 그러나 객체가 있어야합니다 @Id 이미 생성되었습니다.

좀 더 차이점이 있습니다 merge 그리고 persist (여기에 이미 게시된 내용을 다시 열거하겠습니다):

D1. merge 전달된 엔터티를 관리하도록 만드는 것이 아니라 관리되는 다른 인스턴스를 반환합니다. persist 다른 쪽에서는 전달된 엔터티를 관리하게 됩니다.

//MERGE: passedEntity remains unmanaged, but newEntity will be managed
Entity newEntity = em.merge(passedEntity);

//PERSIST: passedEntity will be managed after this
em.persist(passedEntity);

D2.엔터티를 제거한 다음 엔터티를 다시 유지하기로 결정한 경우 persist()를 통해서만 그렇게 할 수 있습니다. merge 던질 것이다 IllegalArgumentException.

D3.ID를 수동으로 관리하기로 결정한 경우(예: UUID 사용) merge 작업은 후속 작업을 트리거합니다 SELECT 해당 ID를 가진 존재하는 엔터티를 찾기 위한 쿼리 persist 해당 쿼리가 필요하지 않을 수도 있습니다.

D4.단순히 코드를 호출하는 코드를 신뢰하지 않는 경우가 있으며, 데이터가 업데이트되지 않고 삽입되었는지 확인하려면 다음을 사용해야 합니다. persist.

Merge Over Persist를 사용하는 데 도움이되는 Merge에 대한 자세한 내용은 다음과 같습니다.

원래 엔티티 이외의 관리 인스턴스를 반환하는 것은 병합 프로세스의 중요한 부분입니다. 동일한 식별자가있는 엔티티 인스턴스가 지속성 컨텍스트에 이미 존재하는 경우 공급자는 병합 된 엔티티의 상태로 상태를 덮어 쓰지 만, 존재하는 관리 버전은 이미 클라이언트에게 반환하여 클라이언트가 될 수 있도록해야합니다. 사용된. 제공자가 지속성 컨텍스트에서 직원 인스턴스를 업데이트하지 않은 경우 해당 인스턴스에 대한 참조는 새로운 상태가 병합되는 것과 일치하지 않습니다.

새로운 엔티티에서 merge ()가 호출되면 persist () 작업과 유사하게 동작합니다. 엔티티를 지속성 컨텍스트에 추가하지만 원래 엔티티 인스턴스를 추가하는 대신 새 사본을 생성하고 대신 해당 인스턴스를 관리합니다. merge () 조작에 의해 생성 된 사본은 maker () 메소드가 그 위에 호출되는 것처럼 유지됩니다.

관계가있는 경우, merge () 작업은 분리 된 엔티티가 참조하는 엔터티의 관리 버전을 가리 키도록 관리 된 엔티티를 업데이트하려고 시도합니다. 엔티티가 지속적으로 정체성이없는 객체와 관계가있는 경우, 병합 작업의 결과는 정의되지 않습니다. 일부 제공 업체는 관리 된 사본이 비 연개 객체를 가리킬 수있는 반면, 다른 공급자는 즉시 예외를 던질 수 있습니다. 이 경우 예외가 발생하지 않도록 merge () 조작을 선택적으로 계단식으로 만들 수 있습니다. 이 섹션 후반에 Merge () 작업의 계단식을 다룰 것입니다. 병합 된 엔티티가 제거 된 엔티티를 가리키면 불법 행위 예외 예외가 발생합니다.

게으른로드 관계는 병합 작업에서 특별한 경우입니다. 게으른로드 관계가 분리되기 전에 엔티티에서 트리거되지 않은 경우, 실체가 병합되면 해당 관계가 무시됩니다. 관계가 관리되는 동안 트리거되고 엔티티가 분리되는 동안 NULL로 설정되면 엔티티의 관리 된 버전은 병합 중에 관계가 지워집니다. "

위의 모든 정보는 Mike Keith와 Merrick Schnicariol의 "Pro JPA 2 Mastering the Java ™ Persistence API"에서 가져 왔습니다. 제 6 장 단면 분리 및 병합. 이 책은 실제로 저자가 JPA에 헌신 한 두 번째 책입니다. 이 새로운 책에는 이전 정보보다 많은 새로운 책이 있습니다. 나는 JPA에 진지하게 관여 할 사람들을 위해이 책을 읽는 것이 좋습니다. 첫 번째 답변을 anonimously로 게시해서 죄송합니다.

나는 세션에있는 게으른로드 컬렉션에 액세스하려고했기 때문에 내 엔티티에서 lazyloading 예외를 얻고있었습니다.

내가 할 일은 별도의 요청에 있었고, 세션에서 엔티티를 검색 한 다음 문제가되는 JSP 페이지에서 컬렉션에 액세스하려고 시도했습니다.

이를 완화하기 위해 컨트롤러의 동일한 엔티티를 업데이트하여 JSP로 전달했지만 세션에서 다시 구할 때도 액세스 할 수 있다고 상상합니다. SessionScope 그리고 던지지 마십시오 LazyLoadingException, 예 2의 수정 :

다음은 저를 위해 일했습니다.

// scenario 2 MY WAY
// tran starts
e = new MyEntity();
e = em.merge(e); // re-assign to the same entity "e"

//access e from jsp and it will work dandy!!

답변을 살펴보면 `Cascade' 및 ID 생성과 관련된 몇 가지 세부 정보가 누락되어 있습니다. 질문 보기

또한, 별도로 가질 수 있다는 점도 언급할 가치가 있습니다. Cascade 병합 및 지속을 위한 주석: Cascade.MERGE 그리고 Cascade.PERSIST 사용된 방법에 따라 처리됩니다.

사양은 당신의 친구입니다 ;)

나는 사용 사례가 포함되어 있기 때문에 최대 절전 모드 문서에서 깨달음 에서이 설명을 발견했습니다.

Merge ()의 사용 및 의미는 새로운 사용자에게 혼란스러워 보입니다. 첫째, 다른 새로운 엔티티 관리자의 한 엔티티 관리자에로드 된 객체 상태를 사용하려고하지 않는 한 merge ()를 전혀 사용할 필요가 없습니다. 일부 전체 응용 프로그램은이 방법을 사용하지 않습니다.

일반적으로 merge ()는 다음 시나리오에서 사용됩니다.

  • 응용 프로그램은 첫 번째 엔티티 관리자에 객체를로드합니다.
  • 객체는 프레젠테이션 계층으로 전달됩니다
  • 객체에 약간의 수정이 이루어집니다
  • 객체는 비즈니스 로직 계층으로 다시 전달됩니다.
  • 응용 프로그램은 두 번째 엔티티 관리자에서 merge ()를 호출하여 이러한 수정을 유지합니다.

다음은 merge ()의 정확한 의미입니다.

  • 현재 지속성 컨텍스트와 관련된 동일한 식별자가있는 관리 된 인스턴스가있는 경우 주어진 객체의 상태를 관리되는 인스턴스에 복사하십시오.
  • 현재 지속성 컨텍스트와 관련된 관리 인스턴스가없는 경우 데이터베이스에서로드하거나 새로운 관리 인스턴스를 작성하십시오.
  • 관리되는 인스턴스가 반환됩니다
  • 주어진 인스턴스는 지속성 컨텍스트와 관련이 없으며 분리되어 있으며 일반적으로 폐기됩니다.

에서: http://docs.jboss.org/hibernate/entitymanager/3.6/reference/en/html/objectstate.html

JPA는 Java 플랫폼을 기반으로 구축 된 엔터프라이즈 애플리케이션 영역에서 논란의 여지가없는 단순화입니다. J2EE의 오래된 엔티티 콩의 복잡성에 대처해야했던 개발자로서 나는 Java EE 사양 중에 JPA가 큰 도약으로 포함되는 것을 볼 수 있습니다. 그러나 JPA 세부 사항을 더 깊이 파고 들면서 쉽지 않은 것들을 찾습니다. 이 기사에서는 EntityManager의 병합 병합 및 겹치는 행동이 초보자뿐만 아니라 혼란을 야기 할 수있는 지속적인 방법을 비교합니다. 또한 나는 두 가지 방법을보다 일반적인 방법의 특별한 경우로 보는 일반화를 제안합니다.

지속적인 엔티티

병합 방법과 달리 지속적인 방법은 매우 간단하고 직관적입니다. 지속 메소드 사용의 가장 일반적인 시나리오는 다음과 같이 요약 할 수 있습니다.

"새로 생성 된 엔티티 클래스 인스턴스는 지속적인 메소드로 전달됩니다.이 방법이 반환되면 엔티티가 관리되고 데이터베이스에 삽입 될 계획이 있습니다. 트랜잭션이 커밋되기 전에 또는 플러시 메소드가 호출 될 때 발생할 수 있습니다. 엔티티가 지속적인 캐스케이드 전략으로 표시된 관계를 통해 다른 엔티티를 참조하면이 절차도 적용됩니다. "

enter image description here

그러나 사양은 세부 사항으로 더 자세히 설명되어 있지만, 이러한 세부 사항은 다소 이국적인 상황에만 적용되므로이를 기억하는 것이 중요하지 않습니다.

병합 엔티티

지속과 비교할 때, 합병의 행동에 대한 설명은 그렇게 간단하지 않습니다. 지속의 경우와 같이 주요 시나리오는 없으며 프로그래머는 올바른 코드를 작성하려면 모든 시나리오를 기억해야합니다. JPA 디자이너는 분리 된 엔티티를 처리하는 주요 관심사가있는 방법을 갖고 싶어하는 것 같습니다 (주로 새로 생성 된 엔티티를 다루는 지속적인 방법과는 반대) Merge 메소드의 주요 작업은 상태를 관리되지 않는 실체 (인수로 전달됨)는 지속성 컨텍스트 내에서 관리되는 상대에게 전달됩니다. 그러나이 작업은 전체 방법의 동작의 명료성을 악화시키는 몇 가지 시나리오로 더 나뉩니다.

JPA 사양에서 단락을 반복하는 대신 병합 메소드의 동작을 개략적으로 표시하는 흐름도를 준비했습니다.

enter image description here

그렇다면 언제 지속과 병합을 사용해야합니까?

지속

  • 이 방법이 항상 새로운 엔티티를 생성하고 엔티티를 업데이트하지 않기를 원합니다. 그렇지 않으면,이 방법은 1 차 주요 고유성 위반의 결과로 예외를 던집니다.
  • 배치 프로세스, 상태가 적합한 처리 엔터티 (게이트웨이 패턴 참조).
  • 성능 최적화

병합

  • 메소드가 데이터베이스에 엔터티를 삽입하거나 업데이트하려고합니다.
  • 상태에서 실체를 처리하려고합니다 (서비스의 데이터 전송 개체)
  • 당신은 아직 생성되지 않을 수있는 다른 엔티티를 참조 할 수있는 새 엔티티를 삽입하려고합니다 (관계는 병합으로 표시되어야 함). 예를 들어, 새로운 앨범 또는 기존 앨범을 참조하여 새 사진을 삽입합니다.

시나리오 x :

표 : Spitter (One), Table : Spittles (많은) (Spittles는 FK와의 관계의 소유자입니다 : Spitter_id)

이 시나리오는 저장을 초래합니다 : Spitter와 Spittles는 같은 스피터가 소유 한 것처럼 보입니다.

        Spitter spitter=new Spitter();  
    Spittle spittle3=new Spittle();     
    spitter.setUsername("George");
    spitter.setPassword("test1234");
    spittle3.setSpittle("I love java 2");       
    spittle3.setSpitter(spitter);               
    dao.addSpittle(spittle3); // <--persist     
    Spittle spittle=new Spittle();
    spittle.setSpittle("I love java");
    spittle.setSpitter(spitter);        
    dao.saveSpittle(spittle); //<-- merge!!

시나리오 y :

이것은 스퍼터를 저장하고, 2 개의 스티클을 저장하지만 그들은 같은 스피터를 참조하지 않습니다!

        Spitter spitter=new Spitter();  
    Spittle spittle3=new Spittle();     
    spitter.setUsername("George");
    spitter.setPassword("test1234");
    spittle3.setSpittle("I love java 2");       
    spittle3.setSpitter(spitter);               
    dao.save(spittle3); // <--merge!!       
    Spittle spittle=new Spittle();
    spittle.setSpittle("I love java");
    spittle.setSpitter(spitter);        
    dao.saveSpittle(spittle); //<-- merge!!

또 다른 관찰 :

merge() 자동 생성 ID에만 관심이 있습니다 (테스트 IDENTITY 그리고 SEQUENCE) 그러한 ID가있는 레코드가 이미 테이블에 존재하는 경우. 이 경우 merge() 레코드를 업데이트하려고합니다. 그러나 ID가 결석하거나 기존 레코드와 일치하지 않는 경우 merge() 그것을 완전히 무시하고 DB에 새 것을 할당하도록 요청합니다. 이것은 때때로 많은 버그의 원천입니다. 사용하지 마세요 merge() 새로운 레코드에 대한 ID를 강요합니다.

persist() 반면에 ID를 전달하지 못하게 할 수는 없습니다. 즉시 실패합니다. 제 경우에는 다음과 같습니다.

원인 : org.hibernate.persistentobjectexception : 분리 된 엔티티가 지속되기 위해 통과되었습니다.

Hibernate-JPA Javadoc은 다음과 같습니다.

던졌습니다: javax.persistence.entityExistSexception- 엔티티가 이미 존재하는 경우. (엔티티가 이미 존재하는 경우, 지속적인 작업이 호출되거나 EntityExistSexception 또는 다른 지속성 지출이 플러시 또는 커밋 시간에 던져 질 수 있습니다.)

당신은 언제 사용 해야하는지에 대한 조언을 구할 수 있습니다. 지속 그리고 언제 사용 해야하는지 병합. 나는 그것이 상황에 달려 있다고 생각합니다. 새로운 레코드를 만들어야 할 가능성이 얼마나 높고 지속 된 데이터를 검색하기가 얼마나 어려운지.

자연스러운 키/식별자를 사용할 수 있다고 가정 해 봅시다.

  • 데이터는 지속되어야하지만 가끔 레코드가 존재하고 업데이트가 요구됩니다. 이 경우 지속을 시도하고 EntityExistSexception을 던지면 데이터를 결합합니다.

    {entityManager.Persist (entity)} try

    catch (entityExistSexception Exception) { / * 검색 및 병합 * /}

  • 지속 된 데이터를 업데이트해야하지만 가끔 데이터에 대한 기록은 없습니다. 이 경우, 당신은 그것을 찾아서 엔티티가 누락 된 경우 지속적으로 수행합니다.

    엔티티 = EntityManager.Find (키);

    if (entity == null) {entityManager.Persist (entity); }

    else { / * 합병 * /}

자연스러운 키/식별자가없는 경우 엔티티가 존재하는지 여부를 파악하기가 더 어려운 시간이 있습니다.

합병은 두 가지 방법으로 다룰 수 있습니다.

  1. 변경 사항이 일반적으로 작은 경우 관리 엔티티에 적용하십시오.
  2. 변경 사항이 일반적인 경우, 변경되지 않은 데이터뿐만 아니라 지속 된 엔티티에서 ID를 복사하십시오. 그런 다음 EntityManager :: merge ()를 호출하여 이전 컨텐츠를 대체하십시오.

persist(entity)는 완전히 새로운 엔터티와 함께 ​​사용되어야 하며 이를 DB에 추가해야 합니다(엔티티가 이미 DB에 존재하는 경우 EntityExistsException이 발생합니다).

엔터티가 분리되고 변경된 경우 엔터티를 지속성 컨텍스트로 되돌리려면 merge(entity)를 사용해야 합니다.

아마도 지속은 INSERT SQL 문을 생성하고 UPDATE SQL 문을 병합하는 것입니다(그러나 확실하지 않습니다).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top