JPA와 Hibernate에서 persist ()와 merge ()의 차이점은 무엇입니까?


119

Hibernate에서 persist ()와 merge ()의 차이점은 무엇입니까?

persist() UPDATE & INSERT 쿼리를 만들 수 있습니다. 예 :

SessionFactory sef = cfg.buildSessionFactory();
Session session = sef.openSession();
A a=new A();
session.persist(a);
a.setName("Mario");
session.flush();

이 경우 쿼리 는 다음과 같이 생성됩니다.

Hibernate: insert into A (NAME, ID) values (?, ?)
Hibernate: update A set NAME=? where ID=?

그래서 persist()메소드 는 삽입과 업데이트를 생성 할 수 있습니다 .

이제 merge():

SessionFactory sef = cfg.buildSessionFactory();
Session session = sef.openSession();
Singer singer = new Singer();
singer.setName("Luciano Pavarotti");
session.merge(singer);
session.flush();

이것이 내가 데이터베이스에서 보는 것입니다.

SINGER_ID   SINGER_NAME
1           Ricky Martin
2           Madonna
3           Elvis Presley
4           Luciano Pavarotti

이제 다음을 사용하여 레코드를 업데이트하십시오. merge()

SessionFactory sef = cfg.buildSessionFactory();
Session session = sef.openSession();
Singer singer = new Singer();
singer.setId(2);
singer.setName("Luciano Pavarotti");
session.merge(singer);
session.flush();

이것이 내가 데이터베이스에서 보는 것입니다.

SINGER_ID   SINGER_NAME
1           Ricky Martin
2           Luciano Pavarotti
3           Elvis Presley

7
javadoc은 그들이하는 일과 차이점에 대해 매우 명시 적입니다. 읽고 이해 했습니까?
skaffman


답변:


144

JPA 사양 에는 이러한 작업의 의미에 대한 매우 정확한 설명이 포함되어 있으며 javadoc보다 더 좋습니다.

엔티티 X에 적용되는 지속 조작 의 의미는 다음과 같습니다.

  • X가 새 엔티티이면 관리됩니다. 엔티티 X는 트랜잭션 커밋시 또는 이전에 또는 플러시 작업의 결과로 데이터베이스에 입력됩니다.

  • X가 기존의 관리 엔티티 인 경우 지속 조작에서 무시됩니다. 그러나 X에서 이러한 다른 엔티티로의 관계가 cascade=PERSIST또는 cascade=ALL 주석 요소 값으로 주석 처리되거나 동등한 XML 설명자 요소로 지정된 경우, 지속 작업은 X에서 참조하는 엔티티에 계단식으로 연결됩니다 .

  • X가 제거 된 엔티티이면 관리됩니다.

  • X가 분리 된 개체 인 EntityExistsException경우 지속 작업이 호출 될 때는 throw되거나 플러시 또는 커밋 시간에 EntityExistsException또는 다른 개체 가 throw 될 PersistenceException수 있습니다.

  • X의 관계로 참조되는 모든 엔티티 Y에 대해 Y에 대한 관계에 계단식 요소 값 cascade=PERSIST또는 으로 주석이 추가 된 cascade=ALL경우 지속 작업이 Y에 적용됩니다.


엔티티 X에 적용되는 병합 작업 의 의미는 다음과 같습니다.

  • X가 분리 된 엔티티 인 경우 X의 상태가 동일한 ID의 기존 관리 엔티티 인스턴스 X '에 복사되거나 X의 새로운 관리 사본 X'가 작성됩니다.

  • X가 새 엔티티 인스턴스 인 경우 새 관리 엔티티 인스턴스 X '가 작성되고 X의 상태가 새 관리 엔티티 인스턴스 X'에 복사됩니다.

  • X가 제거 된 엔터티 인스턴스 인 경우 IllegalArgumentException병합 작업에 의해는 throw됩니다 (또는 트랜잭션 커밋이 실패 함).

  • X가 관리되는 엔터티 인 경우 병합 작업에서 무시되지만 이러한 관계에 계단식 요소 값 cascade=MERGE또는 cascade=ALL주석 이 추가 된 경우 병합 작업은 X의 관계에서 참조하는 엔터티로 계단식으로 연결됩니다 .

  • 계단식 요소 값 cascade=MERGE또는을 갖는 X의 관계에 의해 참조되는 모든 엔티티 Y의 cascade=ALL경우 Y는 Y '로 재귀 적으로 병합됩니다. X가 참조하는 모든 Y에 대해 X '는 Y'를 참조하도록 설정됩니다. (X가 관리되는 경우 X는 X '와 동일한 객체입니다.)

  • X가 지정 cascade=MERGE되거나 cascade=ALL지정되지 않은 다른 엔티티 Y에 대한 참조와 함께 X '에 병합 된 엔티티 인 경우, X'에서 동일한 연관을 탐색하면 Y와 동일한 영구 ID를 가진 관리 객체 Y '에 대한 참조가 생성됩니다.


정보 주셔서 감사합니다. 두 정의의 의미를 봅니다. 그러나 문제는 그들 사이의 차이점에 관한 것입니다. 아마도 persistvs merge? 의 서로 다른 동작에 대한 상태 목록과 2 개의 하위 섹션을 제공 할 수 있습니다 .
AlikElzin-kilaka

25

이것은에서옵니다 JPA. 아주 간단한 방법으로 :

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

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


설명에 출처를 추가해 주시겠습니까? 감사.
AlikElzin-kilaka

@ AlikElzin-kilaka는 "Beginning Java EE 7"책에서 찾았습니다.
Krystian

12

Persist는 새 엔티티에서만 호출되어야하며 병합은 분리 된 엔티티를 다시 연결하는 것을 의미합니다.

할당 된 생성기를 사용하는 경우 persist 대신 merge를 사용하면 중복 SQL 문이 발생하여 성능에 영향을 미칠 수 있습니다.

또한 관리되는 엔티티에 대해 병합을 호출하는 것도 실수입니다. 관리되는 엔티티는 Hibernate에 의해 자동으로 관리되고 Persistence Context 플러시더티 검사 메커니즘 에 의해 해당 상태가 데이터베이스 레코드와 동기화되기 때문 입니다.


1

가장 중요한 차이점은 다음과 같습니다.

  • 의 경우 persist인 기업이 영속 컨텍스트에서 관리 할 경우 방법, 이미 상황 지속성에 존재하는, 새로운 하나는 무시됩니다. (아무 일도하지)

  • 그러나 merge메소드의 경우 지속성 컨텍스트에서 이미 관리되고있는 엔티티가 새 엔티티 (업데이트 됨)로 대체되고이 업데이트 된 엔티티의 사본이 다시 반환됩니다. (지금부터 지속성 컨텍스트에 변경 사항을 반영하려면이 반환 된 엔터티를 변경해야합니다.)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.