소개
이 기사에서는 세션 인터페이스의 여러 방법(저장,지속,업데이트,병합,저장)의 차이점에 대해 설명합니다.
이것은 최대 절전 모드에 대한 소개가 아니며 구성,객체 관계형 매핑 및 엔티티 인스턴스 작업의 기본 사항을 이미 알고 있어야합니다. 최대 절전 모드에 대한 소개 기사를 보려면 봄 최대 절전 모드 4 에 대한 자습서를 방문하십시오.
추가 읽기:
최대 절전 모드로 개체 삭제
최대 절전 모드
엔터티 식별자를 최대 절전 모드로 매핑하는 방법에 대해 알아봅니다.
지속성 컨텍스트 구현으로 세션
세션 인터페이스에는 결국 데이터베이스에 데이터를 저장하는 여러 가지 방법이 있습니다. 이러한 메서드 간의 차이점을 이해하려면 먼저 지속성 컨텍스트로서의 세션의 목적과 세션과 관련된 엔터티 인스턴스의 상태 간의 차이에 대해 논의해야 합니다.
우리는 또한 일부 부분적으로 중복 된 방법을 주도 최대 절전 모드 개발의 역사를 이해해야한다.
2.1. 엔티티 인스턴스 관리
객체 관계형 매핑 자체 외에도 최대 절전 모드가 해결하려는 문제 중 하나는 런타임 동안 엔티티를 관리하는 문제입니다. “지속성 컨텍스트”의 개념은이 문제에 대한 최대 절전 모드의 해결책입니다. 지속성 컨텍스트는 세션 중에 데이터베이스에 로드하거나 저장한 모든 개체에 대한 컨테이너 또는 첫 번째 수준 캐시로 생각할 수 있습니다.
세션은 논리적 트랜잭션이며,경계는 응용 프로그램의 비즈니스 논리에 의해 정의됩니다. 지속성 컨텍스트를 통해 데이터베이스로 작업하고 모든 엔터티 인스턴스가 이 컨텍스트에 연결된 경우 세션 중에 상호 작용한 모든 데이터베이스 레코드에 대해 항상 단일 엔터티 인스턴스가 있어야 합니다.
최대 절전 모드에서 지속성 컨텍스트는 조직에 의해 표시됩니다.최대 절전 모드.세션 인스턴스. 이 문제를 해결하기 위해 몇 가지 방법이 있습니다.지속성.자격 관리자. 이 인터페이스의 구현은 기본적으로 기본 세션 개체를 래핑합니다. 그러나,최대 절전 모드 세션은 더 많은 가능성을 가진 풍부한 인터페이스를 제공하므로 때로는 직접 세션 작업에 유용합니다.
2.2. 엔터티 인스턴스 상태
응용 프로그램의 모든 엔터티 인스턴스는 세션 지속성 컨텍스트와 관련하여 세 가지 기본 상태 중 하나에 나타납니다:
- 임시-이 인스턴스는 세션에 연결되지 않았고 연결되지 않았습니다.;
- 영구—이 인스턴스는 고유 세션 객체와 연결되어 있으며,세션을 데이터베이스로 플러시하면 이 엔터티가 데이터베이스에 상응하는 일관된 레코드를 갖도록 보장됩니다.
- 분리됨-이 인스턴스는 한 번 세션에 연결되었지만(영구 상태)지금은 그렇지 않습니다.
다음은 상태 전환을 수행하는 세션 메서드에 대한 주석이 포함된 간단한 상태 다이어그램입니다.
엔터티 인스턴스가 영구 상태이면 이 인스턴스의 매핑된 필드에 대한 모든 변경 내용이 세션을 플러시할 때 해당 데이터베이스 레코드 및 필드에 적용됩니다. 영구 인스턴스는”온라인”으로 생각할 수 있지만 분리 된 인스턴스는”오프라인”으로 전환되어 변경 사항을 모니터링하지 않습니다.
즉,영구 개체의 필드를 변경할 때 저장,업데이트 또는 이러한 메서드를 호출하여 이러한 변경 내용을 데이터베이스에 가져올 필요가 없습니다.
2.3. 최대 절전 모드
에 대한 적합성은 가장 성공적인 자바 구현이었습니다. 자바 지속성에 대한 사양이 최대 절전 모드(최대 절전 모드)에 의해 크게 영향을 받았다는 것은 놀라운 일이 아닙니다. 불행히도,많은 차이점이있었습니다:몇 가지 주요,좀 더 미묘한.
여러 메서드가 세션 인터페이스에 추가되어 권한 관리자 인터페이스와 일치했습니다. 이 방법은”원래”방법과 동일한 목적을 수행하지만 사양을 준수하므로 약간의 차이가 있습니다.
작업 간의 차이점
모든 메서드(지속,저장,업데이트,병합,저장)가 즉시 발생하지 않는다는 것을 처음부터 이해하는 것이 중요합니다. 데이터베이스에 대한 실제 데이터 저장은 트랜잭션을 커밋하거나 세션을 플러시할 때 발생합니다.
언급된 메소드는 기본적으로 라이프사이클에 따라 서로 다른 상태 사이를 전환하여 엔티티 인스턴스의 상태를 관리합니다.
예제 엔티티로서,우리는 간단한 주석 매핑 엔티티 사람을 사용합니다:
@Entitypublic class Person { @Id @GeneratedValue private Long id; private String name; // ... getters and setters}
3.1. 지속
지속 메서드는 지속성 컨텍스트에 새 엔터티 인스턴스를 추가하는 데 사용됩니다.
우리는 일반적으로 데이터베이스에 레코드를 추가 할 때 호출(엔티티 인스턴스를 유지):
Person person = new Person();person.setName("John");session.persist(person);
지속 메서드가 호출된 후에는 어떻게 됩니까? 개인 개체가 일시적 상태에서 영구 상태로 전환되었습니다. 개체가 현재 지속성 컨텍스트에 있지만 아직 데이터베이스에 저장되지 않았습니다. 삽입 명령문의 생성은 트랜잭션을 커밋하거나 세션을 플러시하거나 닫을 때만 발생합니다.
지속 메서드에 무효 반환 유형이 있는지 확인합니다. 그것은 그 상태를 변경,”장소에서”전달 된 객체에서 작동합니다. 사람 변수는 실제 지속 개체를 참조합니다.
이 방법은 세션 인터페이스에 나중에 추가되었습니다. 이 방법의 주요 차별화 기능은 다음과 같습니다. 이 방법의 의미는 기본적으로 다음과 같은 사양에 엄격하게 정의되어 있습니다:
- 임시 인스턴스가 영구적으로됨(작업이 캐스케이드=지속 또는 캐스케이드=모두와의 모든 관계로 캐스케이드됨),
- 인스턴스가 이미 영구적인 경우 이 호출은 이 특정 인스턴스에 영향을 미치지 않습니다(하지만 여전히 캐스케이드=지속 또는 캐스케이드=모두와의 관계로 캐스케이드됨),
- 인스턴스가 분리된 경우 이 메서드를 호출하거나 세션을 커밋하거나 플러시할 때 예외가 발생해야 합니다..
여기서 인스턴스의 식별자와 관련된 것은 없습니다. 이 스펙은 아이디 생성 전략에 관계없이 아이디가 즉시 생성될 것이라고 명시하지 않습니다. 또한 이 메서드를 호출한 후에는 이 메서드가 널이 아닌 것으로 보장되지 않으므로 이 메서드에 의존해서는 안 됩니다.
이미 영구 인스턴스에서 이 메서드를 호출할 수 있으며 아무 일도 발생하지 않습니다. 그러나 분리된 인스턴스를 유지하려고 하면 구현이 예외를 발생시킬 수밖에 없습니다. 다음 예제에서는 엔터티를 유지하고 컨텍스트에서 제거하여 분리된 다음 다시 유지하려고 합니다. 세션에 대한 두 번째 호출.유지()는 예외가 발생하므로 다음 코드가 작동하지 않습니다:
Person person = new Person();person.setName("John");session.persist(person);session.evict(person);session.persist(person); // PersistenceException!
3.2. 저장
저장 방법은”원래”최대 절전 모드 메서드입니다.
그 목적은 기본적으로 지속과 동일하지만 구현 세부 사항이 다릅니다. 이 방법에 대한 설명서에는”먼저 생성 된 식별자 할당”이라는 인스턴스가 계속 유지된다고 엄격하게 명시되어 있습니다. 메서드는 이 식별자의 직렬화 가능 값을 반환하도록 보장됩니다.
Person person = new Person();person.setName("John");Long id = (Long) session.save(person);
이미 지속된 인스턴스를 저장하는 효과는 지속과 동일합니다. 분리 된 인스턴스를 저장하려고 할 때 차이가 발생합니다:
Person person = new Person();person.setName("John");Long id1 = (Long) session.save(person);session.evict(person);Long id2 = (Long) session.save(person);
이 변수에는 두 가지 유형이 있습니다. 분리된 인스턴스에 대한 저장 호출은 새 영구 인스턴스를 만들고 새 식별자를 할당하여 커밋 또는 플러시할 때 데이터베이스에 중복 레코드가 생성됩니다.
3.3. 병합
병합 방법의 주요 목적은 분리된 엔터티 인스턴스의 새 필드 값으로 영구 엔터티 인스턴스를 업데이트하는 것입니다.예를 들어,호출자에게 이 개체의 업데이트된 버전을 수신하는 메서드와 호출자에게 직렬화된 개체를 검색하는 메서드와 편안한 인터페이스가 있다고 가정합니다. 이러한 직렬화/역 직렬화를 통과 한 엔터티는 분리 된 상태로 나타납니다.
이 엔터티 인스턴스를 역직렬화한 후에는 지속성 컨텍스트에서 영구 엔터티 인스턴스를 가져와 이 분리된 인스턴스의 새 값으로 필드를 업데이트해야 합니다. 그래서 병합 방법은 정확히 그 작업을 수행합니다:
- 전달된 개체의 필드를 이 인스턴스로 복사합니다.
- 새로 업데이트된 인스턴스를 반환합니다.
다음 예제에서는 저장된 엔터티를 컨텍스트에서 제거(분리)하고 이름 필드를 변경한 다음 분리된 엔터티를 병합합니다.
Person person = new Person(); person.setName("John"); session.save(person);session.evict(person);person.setName("Mary");Person mergedPerson = (Person) session.merge(person);
병합 메서드는 개체를 반환합니다. 그것들은 두 개의 다른 객체이며,사람 객체는 일반적으로 폐기 될 필요가 있습니다(어쨌든 지속성 컨텍스트에 첨부 된 것으로 간주하지 마십시오).
지속 메서드와 마찬가지로 병합 메서드는 신뢰할 수 있는 특정 의미를 갖도록 지정됩니다:
- 이 연산은 계단식=병합 또는 계단식=모든 매핑을 사용하는 모든 관계에 대해 계단식입니다.
3.4. 업데이트
지속 및 저장과 마찬가지로 업데이트 메서드는 병합 메서드가 추가되기 훨씬 전에 존재했던”원래”최대 절전 모드 메서드입니다. 그 의미는 몇 가지 핵심 사항이 다릅니다:
- 업데이트 메서드는 전달된 개체를 분리된 상태에서 영구 상태로 전환합니다.
다음 예제에서는 개체를 저장 한 다음 컨텍스트에서 개체를 제거(분리)한 다음 이름을 변경하고 업데이트를 호출합니다. 업데이트가 개인 개체 자체에서 이루어지기 때문에 업데이트 작업의 결과를 별도의 변수에 넣지 않습니다. 기본적으로 우리는 기존 엔티티 인스턴스를 지속성 컨텍스트에 다시 연결하고 있습니다.
Person person = new Person();person.setName("John");session.save(person);session.evict(person);person.setName("Mary");session.update(person);
임시 인스턴스에서 업데이트를 호출하려고 하면 예외가 발생합니다. 다음은 작동하지 않습니다:
Person person = new Person();person.setName("John");session.update(person); // PersistenceException!
3.5. 2228>
이 메서드는 최대 절전 모드에만 표시되며 표준화된 대응이 없습니다. 업데이트와 마찬가지로 인스턴스를 다시 연결하는 데에도 사용할 수 있습니다.
실제로 업데이트 메서드를 처리하는 내부 기본값 업데이트 이벤트 목록 작성기 클래스는 일부 기능을 재정의하는 기본 데이터 목록 작성기의 하위 클래스입니다. 대신 이 임시 인스턴스를 영구적으로 만듭니다. 다음 코드는 새로 만든 사람 인스턴스를 유지합니다:
Person person = new Person();person.setName("John");session.saveOrUpdate(person);
이 메서드는 일시적이거나 분리된 상태에 관계없이 개체를 영구적으로 만드는 범용 도구라고 생각할 수 있습니다.
무엇을 사용해야합니까?
특별한 요구 사항이 없는 경우,일반적으로 지속 및 병합 방법을 고수해야 합니다.
다른 지속성 공급자로 전환하기로 결정한 경우에도 이식 가능하지만”원래”최대 절전 모드 메서드,저장,업데이트 및 저장 업데이트로 유용하지 않은 경우가 있습니다.
결론
런타임에서 영구 엔티티를 관리하는 것과 관련하여 다른 최대 절전 모드 세션 방법의 목적에 대해 논의했습니다. 우리는 이러한 메소드가 라이프 사이클을 통해 엔티티 인스턴스를 전송하는 방법과 이러한 메소드 중 일부가 기능을 복제 한 이유를 배웠습니다.