'새 객체를 삽입하십시오 및 업데이트하려면 렌티티만거스메르게 ()' 가 기존 수준들과.
왜 사용할 옛일에 () '한' (새 객체를 생성할 수 있는 전용)?
어느 쪽이든 추가할 수 있는 엔티티입니다 퍼시스텐스콘티스트, 차이는 왜 함께 엔티티입니다 된다.
옛일에 엔티티입니다 인스턴스입니다 자도으로 있는 데, 이를 컨텍스트로 하면 인스턴스입니다 관리됨 (즉 향후 업데이트뿐 그 엔티티와 적립율은 추적됨).
새 인스턴스를 만듭니다 너회의 엔티티입니다 병합해야 복사됩니다 스테이드 에서 제공된 엔티티입니다 하면 새로운 복제본에 관리됨. 이 인스턴스입니다 관리됨 통과 하지 않을 수 있습니다 (변경한 트랜잭션까지 전화하시기 다시 병합해야 에는 포함되지 않을 경우를 제외하고).
아마 코드 예제 도움이 된다.
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 은 거의 동등한 수준의 수축됐는데 일부 you&; d # 39 사용할 경우에, 시나리오 2.
이 두 가지 목적을 위해 옛일에 및 병합 (그들은 전혀 다른 aren& # 39, t).
(편집하여 변경분 확장하십시오 정보)
옛일에:
병합해야:
옛일에 () 효율성:
시맨틱스를 옛일에 ():
그 과정에서 실수로 합니다 - 삽입 및 업데이트되지 않고 있다.
예:
{
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 만 존재하는 모든 장부를요 config. 엔티티에는 direct-attached 객체에는 메니저야
id 가 엔티티입니다 병합해야 () 는 다음과 같은 것이 있다.
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 병합해야 연결된 경우 () 로 전화를 사용할 수 있는 효율적인 옛일에 () 로, 제파 는 주요 업데이트 옵션을 삽입하려면 복제본임을 매우 높은 수준의 프로그래밍 진실이며당신이 can& # 39 이 사건을 전부 t solaris. 될 것입니다.
또한, [호출하십시오 대한 병합해야 관리됨 엔티티에는] (https://vladmihalcea.com/jpa-persist-and-merge/) 도 이후 최대 절전 모드 및 그 상태는 엔티티에는 관리됨 실수가 자동으로 관리하는 데이터베이스 레코드를 통해 동기화되도록 [더러운 검사 메커니즘은] (https://vladmihalcea.com/the-anatomy-of-hibernate-dirty-checking/) 빛위에 [플러시하는 지속 컨텍스트로] (https://vladmihalcea.com/a-beginners-guide-to-jpahibernate-flush-strategies/).
이 모든 것을 알고, 최대 절전 모드 작동 방법을 이해할 수 있도록 먼저 부족의 개발자 마인드 엔티티입니다 스테이드 전환 에서 SQL 문을.
한 번 적극 관리하는 엔티티입니다 데이터베이스에 자동으로 전파할지 최대 절전 모드, 모든 변경 사항이 될 것입니다.
현재 최대 절전 모드 모니터합니다 direct-attached 엔티티에는. 하지만 엔티티입니다 비활성화해야 되기 위해 관리됨, 오른쪽 엔티티입니다 상태.
첫째, 모든 엔티티에는 정의하십시오 해야 한다 "는 다음과 같은 뜻이 있다.
새로 만든 객체에는 하지 않았던 적이 최대 절전 모드 '세션' (앨k.a 컨텍스트로 '영구') 와 관련된 모든 데이터베이스 테이블 행일 수 없는 매핑됨 고려되는지 새로운 (임시) 상태.
영구 엔티티에는 연결되어 있으며 현재 실행 중인 지속성을 관리하는 데이터베이스 테이블 행일 애태우면 컨텍스트입니다. 이러한 엔티티에는 변경할 경우 데이터베이스에 대한 인식 및 전파할지 것입니다 (세션 동안 플러시합니다 시간). 최대 절전 모드, 우리는 더 이상 함께 할 autoexec. 삽입 / 업데이트 / 삭제 명령문입니다. 2 는 [트랜잭션용 뒤에 쓰기] 는 최대 절전 모드 변경 작업 스타일 및 세션 중 가장 마지막 순간, '현재' 책임 있는 동기화되는지 emc. 플러시합니다 시간.
일단 현재 실행 중인 모든 이전에 관리됨 엔티티에는 분리되었는지 영구 컨텍스트로 닫혀 있다. 더 이상 제공되지 않고 자동 데이터베이스 통기화를 추적됨 연속 변화가 일어나는.
최대 절전 모드 세션용으로 연관시키려면 분리되었는지 엔티티입니다 활성 옵션 중 하나를 선택할 수 있습니다.
최대 절전 모드 (단, 제파 2.1) 를 통해 재장착하는 방법에 汲摹窍妨绰 세션이고 # 업데이트 방법입니다. 최대 절전 모드 가능 한 한 엔티티입니다 객체에는 세션용으로 연관시킵니다 주어진 데이터베이스 행. 이 때문에 지속 컨텍스트로 표시됨과 인메모리를 캐시 (1 급 캐시) 는 단 1 개 값 (엔티티) 는 연관됨 특정 키 (엔티티입니다 유형 및 데이터베이스 식별자입니다). 엔티티입니다 다시 연결했습니다 수 없는 경우에만 다른 JVM 객체에는 일치 같은 데이터베이스 행) 이미 관련 현재 최대 절전 모드 세션에만 적용됩니다.
결합 상태 (소스) 를 진행 과정은 복사합니다를 분리되었는지 엔티티에는 관리됨 엔티티입니다 인스턴스입니다 (대상). 현재 세션에 병합합니다 엔티티에는 avamer 없는 경우 한 데이터베이스에서 반입됨 됩니다. 이 후에도 계속 분리되었는지 인스턴스입니다 분리되었는지 객체에는 병합 작업을 했다.
비록 제거할 수 있는 최대 절전 모드, 제파 요구를 관리됨 엔티티에는 친절과 분리되었는지 엔티티에는 삭제할 수도 있습니다 (단, 세션 # 삭제하시겠습니까 통해서만 메서드 호출). 제거된 엔티티에는 스케줄링된 삭제용으로 경우에만 실제 데이터베이스 및 세션 동안 기술서임을 삭제하시겠습니까 실행됨을 플러시합니다 시간.
제파 스테이드 전환 더 잘 이해하기 위해 다음 구성도를 시각화합니다 수 있습니다.
최대 절전 모드를 사용하는 경우 또는 특정 API:
제파 () 는 다음과 같은 '대한' 옛일에 사양명세 밝혔습니다.
>. 이 때 ',' 는 분리되었는지 객체에는 렌티티렉시체스세페시옹 X 경우 던져 옛일에 수 있습니다. 작업은 '또는' 다른 '또는' 렌티티렉시체스세페시옹 호출되었을 퍼시스텐스엑스티온 버린 시간 또는 커밋합니다 http://support. 플러시합니다 수 있습니다.
그래서 맞지 않을 때 ' ()' 를 사용하여 옛일에 약간만이라도 객체에는 분리되었는지 객체에는 수 있어야 한다. 같이 코드를 가질 수 있도록 '빠른' 실패한 퍼시스텐스엑스티온 선호할 수도 있습니다.
비록 사양명세 아직 확실히 밝혀지지 않았다 () ',' 옛일에 설정할 수 있다 '' @Id '' @GeneratedValue 객체에 대한. 그러나 ' ()' 와 '이미' @Id 생성할지 객체에는 병합해야 있어야 합니다.
몇 가지 더 많은 차이점을 '병합' 과 '옛일에' (내아기마저도 열거하십시오 cerner 이미 게시하기를 다시 여기).
D1. '지' 할 수 있는 것이 아니라, 다른 인스턴스입니다 병합해야 언약보다는 엔티티입니다 관리됨 되돌려줍니다 관리됨. '이' on the other side 발쿰치로 옛일에 엔티티입니다 관리됨 통과시켰다.
//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. 엔티티입니다 제거하면 결정한 후 그 엔티티와 옛일에 뒤로를 할 수 있습니다 () ',' 은 '한' 이가라구멍렉세페시옹 던지기 때문에 오로지 옛일에 병합해야.
D3. 잘있게나 경우 해당 id 를 수동으로 했다 (에드그 uuid 사용하여), 그리고 '병합' '후속' 를 찾는 작업을 위해 트리거됩니다 쿼리합니다 현존하는 엔티티에는 그 동안 해당 ID 의 ',' 옛일에 쿼리합니다 필요로 하지 않을 수 있습니다.
D4). 간단히 코드를 호출하는 경우가 믿지 않을 경우 해당 코드와 데이터가 업데이트되지만 없도록 하기 위해 삽입된 '대신' 옛일에 사용해야 합니다.
이를 통해 좀 더 자세히 병합해야 도움말에서는 옛일에 병합해야 사용할 수 있습니다.
>. 반환 관리됨 인스턴스입니다 원본 엔티티와 매우 중요한 부분을 제외한 결합 과정이다. 와 같은 맥락, 이미 존재하는 경우 엔티티입니다 인스턴스입니다 식별자입니다 영속성 그 상태로 제공업체입니다 덮어써지며 상태가 중인 엔티티에는 있지만 관리됨 병합되었습니다. 이미 존재했던 귀의하지않는다고 클라이언트로 버전을 사용할 수 있도록 합니다. 만약 공급자입니다 않았다. 예를 들어, 지속 될 수 있는 모든 참조입니다 컨텍스트로 부하예요 업데이트하십시오 어울리지 않는 새로운 스테이드 결합할 것이다. >. >. 병합해야 때 () 는 신규 엔티티입니다 호출되었을 작동합니다 유사하게 옛일에 (), 운영할 수 있다. 새롭게 대신 이 항목을 추가하는 것이 영속성 컨텍스트로, 원본 엔티티와 새 인스턴스를 만듭니다. 그 대신 인스턴스입니다 복사 및 관리. 이 작업은 지속되어 카피됐나 만든 결합 () () 메서드를 호출할 수 있었던 것처럼 옛일에 때문이다. >. >. In the presence of 관계, 결합 () 작업은 관리됨 엔티티에는 업데이트하려면 봅니다. 이 버전은 가리키십시오 관리됨 엔티티들을 참조됨 분리되었는지 엔티티입니다. 한 경우 엔티티에는 객체 관계 없는 결과를 병합해야 작업은 영구 정체성, 정의되지 않았습니다. 일부 제공자에서 허용할 수 있다는 점에서, 비지속성 객체에는 관리됨 사본이라는 다른 즉시 예외가 될 수 있다는 것입니다. 결합 () 작업에 수도 있습니다 이 경우에 예외가 발생하지 않도록 계층화할. 다룰 캐스케이딩이란 병합의 () 나중에 작업이 이 부분. 엔티티입니다 결합할 경우 한 점을 재거됨 엔티티입니다 이가라구멍렉세페시옹 idfsysobject. 버린 것입니다. >. >. 게으른 로드중 관계는 병합해야 있는 특수한 경우로, 운영할 수 있다. 게으른 로드중 경우 그 전에 트리거되면 협력하였습니다 엔티티에는 comp. 분리되었는지 릴레이션십 적립율은 릴레이션십 않았다. 이 때 무시됨 엔티티에는 존재한다. Null 로 설정할 경우, 그 동안 트리거됨 관리됨 관계라고 했다, 그 동안 엔티티에는 분리되었는지 관리됨 버전의 엔티티에는 elationship 클리어런스됩니다 거역한다면 거짓하였으니 merge." 중에 있다.
위의 모든 정보를 빼앗아, 제파 는 영구 API" 센스를 Java™ " pro/무선 2. 마이크 키스 및 메릭 의해 슈니카리오. 6 장. 섹선에서 분견대 및 병합. 제파 는 실제로 이 책을 만든 두 번째 소설 바쳤다. 이 새 책은 전 한 후 새로운 정보를 많이 가지고 있다. 정말 이 책을 읽을 수 레코메드 수준들과 관련된 농담하십니까 누가 담당합니까 제파. 내 첫 게시 안로니무스리 후회하고 있다고 대답.
I was getting on my 엔티티에는 라시로이딩 예외 있었기 때문에 그 게으른 로드됨 취합은 액세스하려는 롬폭 세션에만 적용됩니다.
내가 해야한다고 롬폭 별도의 요청을 한 후 내 jsp 페이지이므로 액세스하려는 세션에서 엔티티에는 읽어들입니다 취합은 하는 것은 무리다.
이 같은 엔티티에는 이를 완화하기 위해, 난 내 jsp, 비록 내가 내 컨트롤러거 업데이트되도록 때 내가 상상할 수 있었던 것이 아니라 재 저장 세션에서 'a', '던질 수 도 있지만 세실론스코프 라시로딩렉세페시옹 마시오' 예 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!!
>. 제파 는 논란의 여지 도메인의 숭배자들로부터도 단순화 엔터프라이즈 >. 자바 플랫폼 기반으로 애플리케이션을. 개발자의 했던 >. 내가 보고 있는 이 오래된 엔티티에는 대응할 수 있는 보다 더 복잡한 J2EE 콩 >. java EE 의 가장 큰 발전을 사양명세를 포함인지 제파 >. 앞으로. 그러나 내가 찾을 때 더 detaiils 제파 꽂으십시오 탐구 >. 일들이 그렇게 쉽지 않은 일입니다. 이 글에서는 계약을 비교 >. 이 방법 및 그 중첩되도록 옛일에 렌티티만거 의 병합해야 >. 단지 한 뉴비 비헤이비어를 혼란을 일으킬 수 있습니다. 또 내가 >. 두 방법 모두 특별한 사례가 있는 것으로 보고 제안하십시오 일반화 >. 더 일반적인 방법을 합칩니다.
이 방법은 아주 간단하고 직관적인 방법을 반대로 병합해야 옛일에. # 39 의 사용 중 가장 일반적인 경우에 옛일에 method& inet6.0 으로 압축된다.
그 엔티티와 클래스용 ", 새로 만든 인스턴스에서는 전달되는 옛일에 메서드입니다. 이 방법은, 후에 그 엔티티와 되돌려줍니다 삽입에서 데이터베이스에 관리됨 및 예정. 이 때 또는 플러시합니다 메서드입니다 호출됨 커밋한 앞이나 트랜잭션까지 일어날 수 있습니다. 엔티티 참조를 통해 경우 다른 엔티티와 릴레이션십 표시된 옛일에 케스케이드 전략을 이 절차는 적용되어 also.".
그러나 더 중요한 것은 그들을 기억하는 detaiils 분할합니다 사양명세 댁이라면 같은 이국적인 상황을 자세히 빽이라는 늘리거나 줄일 수 있습니다.
내가 대신 리피팅 단락 &solarisdvd 제파 는 사양명세 위해수치스러운 흐름도 개략적으로 병합해야 동작을 하는 방법:
그래서 언제 옛일에 가능* 병합해야 사용해야 하는 경우
옛일에 *
또 다른 결합 및 유지하기 위한 '케스케이드' 주석입니다 가질 수 있는 것도 가치가 있습니다. '카스카데스메르게 카스카드스페르시스트 다룰 수 있는' 와 '에 따르면' 사용하는 방법입니다.
Spec 은 친구;)
[1]: # 17830782 https://stackoverflow.com/questions/17816196/jpa-how-can-i-get-the-generated-id-object-when-using-merge-from-parent-but-child/17830782
내가 찾은 포함되어 있기 때문에 이같은 설명은 docs 에서 최대 절전 모드, 계몽적인 览侩 荤례:
>. Merge () 는 사용도와 시맨틱스를 복잡할 신규 사용자를 위한 것으로 보인다. 첫째, as long as you are not 사용하려는 객체에는 스테이드 로드되었는지 엔티티입니다 관리자에서 한 또 다른 새로운 엔티티입니다 manager 를 전혀 사용하지 않아도 됩니다 () 병합해야 합니다. 결코 일부 전체 애플리케이션을 사용하는 방법입니다.
>. 일반적으로 결합 () 는 다음과 같은 경우에 사용된다:
>. * 첫 번째 엔티티입니다 관리자 응용 프로그램 객체를 로드되는지
>. 다음은 정확한 의미 merge ():
>. * 와 같은 경우 현재 연관된 식별자입니다 관리됨 인스턴스입니다 영속성 컨텍스트로 복사합니다를 스테이드 주어진 객체에는 관리됨 인스턴스입니다 드래그합니다
출처: http://docs.jboss.org/hibernate/entitymanager/3.6/reference/en/html/objectstate.html
책정안 X:
(1), Table: 스피터 table: 침 (많은) () 는 관계를 FK:spitter_id 침 소유자)
이 시나리오는 결과 저장: 이 스피터 침 소유한 것처럼, 둘 다 동일한 스피터.
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!!
다른 관측.
() '에서는' 병합해야 신경을 쓰고 있는 자동으로 id (id '와' 에 '테스트되었습니다 e0100042.log') 와 사용자 id 를 기록할 때 이미 존재하는 표. 이 경우 ' ()' 가 시도하시겠습니까 병합해야 업데이트하려면 기록. 그러나 그 id 가 존재하지 않는 경우 기존 기록, '무시' 가 완전히 일치하는 병합해야 () 또는 정보기술 (it) 과 새 불신하니 하나님께용서를 할당하고자 데이터베이스 (db) 이는 때로 a source of 많은 버그. '병합해야 ()' 을 강제로 id 를 사용하지 않는 새로운 기록을 경신했다.
반면 '옛일에 () 는' never let you fopen id 를 통과할 수 있도록 한다. It 페일오버됩니다 지원했다. 제 경우에는 it& # 39, s:
>. 원인: 오르g. 히베르나티스페르시스텐토비치렉세페시옹: 분리되었는지 엔티티에는 >. 옛일에 전달된
최대 절전 모드 제파 javadoc 는 힌트:
>. 던지는 : 엔티티에는 자바스스페르시스텐스트렌티티렉시체스세페시옹 경우 - >. 이미 있습니다. (이 경우 이미 엔티티에는 >. 렌티티렉시체스세페시옹 옛일에 작업은 때 마운드에 설 수 있습니다. >. 또는, 또는 다른 퍼시스텐스엑스티온 렌티티렉시체스세페시옹 호출되었을 >. 좋은 시간 또는 커밋합니다 http://support. 플러시합니다 수 있습니다.)
사용하는 경우에 대한 조언을 할 수 있습니다 및 사용 시 이리와라 옛일에 병합해야 . 상황을 달려 있다고 생각한다. 가능성은 얼마나, 어떻게 만들어야 하는 것은 어려운 새로운 기록을 유지하고 읽어들입니다 데이터.
시도하시겠습니까 렌티티만거스페르시스트 (엔티티)} {
캐치 (렌티티렉시체스세페시옹 idfsysobject.)} 과 {/ 읽어들입니다 병합해야 /
엔티티입니다 = 렌티티만거스피드 (키).
if (null = 엔티티에는) {렌티티만거스페르시스트 (엔티티); }
/ 병합해야 /} else {
이 두 가지 방법으로 처리할 수 있는 병합합니다 너무: