최대 절전 모드에서의 서로 다른 저장 방법의 차이점은?
최대 절전 모드에는 어떤 식으로든 여러분의 개체를 가져다가 데이터베이스에 넣는 몇 가지 방법이 있다.그들 사이의 차이점은 무엇인가, 언제 무엇을 사용할 것인가, 그리고 왜 어떤 것을 언제 사용할지 아는 지능적인 방법이 하나 없을까?
지금까지 확인한 방법은 다음과 같다.
save()
update()
saveOrUpdate()
saveOrUpdateCopy()
merge()
persist()
여기 방법에 대한 나의 이해가 있다.주로 API를 기반으로 하지만, 나는 이 모든 것을 실제로 사용하지 않는다.
saveOrUpdate 호출은 일부 검사에 따라 저장하거나 업데이트하십시오.예: 식별자가 없는 경우 save를 호출한다.그렇지 않으면 업데이트가 호출된다.
저장 - 엔티티를 유지한다.식별자가 없는 경우 할당함.만약 그렇다면, 그것은 본질적으로 업데이트를 하는 것이다.엔티티의 생성된 ID를 반환한다.
업데이트 기존 식별자를 사용하여 엔티티를 유지하려는 시도.식별자가 없으면 예외가 발생한다고 믿는다.
saveOrUpdateCopy 이것은 더 이상 사용되지 않으므로 사용하지 마십시오.대신...
이제 여기서 내 지식이 흔들리기 시작한다.여기서 중요한 것은 일시적, 분리적, 지속적 실체의 차이다.개체 상태에 대한 자세한 내용은 여기를 참조하십시오.저장 및 업데이트를 통해 영구 객체를 처리하십시오.그들은 세션에 연결되어 있어서 겨울잠은 무엇이 바뀌었는지 안다.그러나 과도적인 물체가 있을 때는 세션이 관여되지 않는다.이러한 경우 업데이트를 위해 병합을 사용하고 저장을 계속해야 한다.
위에서 언급했듯이, 이것은 일시적인 물체에 사용된다.생성된 ID를 반환하지 않는다.
╔══════════════╦═══════════════════════════════╦════════════════════════════════╗
║ METHOD ║ TRANSIENT ║ DETACHED ║
╠══════════════╬═══════════════════════════════╬════════════════════════════════╣
║ ║ sets id if doesn't ║ sets new id even if object ║
║ save() ║ exist, persists to db, ║ already has it, persists ║
║ ║ returns attached object ║ to DB, returns attached object ║
╠══════════════╬═══════════════════════════════╬════════════════════════════════╣
║ ║ sets id on object ║ throws ║
║ persist() ║ persists object to DB ║ PersistenceException ║
║ ║ ║ ║
╠══════════════╬═══════════════════════════════╬════════════════════════════════╣
║ ║ ║ ║
║ update() ║ Exception ║ persists and reattaches ║
║ ║ ║ ║
╠══════════════╬═══════════════════════════════╬════════════════════════════════╣
║ ║ copy the state of object in ║ copy the state of obj in ║
║ merge() ║ DB, doesn't attach it, ║ DB, doesn't attach it, ║
║ ║ returns attached object ║ returns attached object ║
╠══════════════╬═══════════════════════════════╬════════════════════════════════╣
║ ║ ║ ║
║saveOrUpdate()║ as save() ║ as update() ║
║ ║ ║ ║
╚══════════════╩═══════════════════════════════╩════════════════════════════════╝
지속성과 저장 간의 미묘한 차이점에 대한 설명은 최대 절전 모드 포럼을 참조하십시오.차이점은 INSERT 문이 궁극적으로 실행되는 시간인 것 같다.저장하면 식별자가 반환되기 때문에 INSERT 문은 거래의 상태(일반적으로 나쁜 것)에 관계없이 즉시 실행되어야 한다.지속은 식별자를 할당하기 위해 현재 실행 중인 트랜잭션 이외의 문구를 실행하지 않는다.Save/Persister는 둘 다 임시 인스턴스(즉, 식별자가 아직 할당되지 않은 인스턴스)에서 작동하며 DB에 저장되지 않는다.
업데이트 및 병합은 DB에 해당 항목이 있지만 현재 세션에 연결되거나 세션에 의해 관리되지 않는 분리된 인스턴스(instance)에 대해 수행된다.그들 사이의 차이는 함수에 전달되는 인스턴스에게 일어나는 것이다.업데이트는 인스턴스를 다시 연결하려고 시도한다. 즉, 세션에 연결된 영구 엔터티의 다른 인스턴스가 없어야 하고 그렇지 않으면 예외가 발생해야 한다. 그러나 병합은 모든 값을 세션의 영구 인스턴스(현재 로드되지 않은 경우 로드됨)에 복사하기만 하면 된다.입력 개체는 변경되지 않는다.따라서 병합은 업데이트보다 일반적이지만 더 많은 리소스를 사용할 수 있다.
대부분의 경우 JPA 방식을 선호해야 하며, 또한 JPA 방식을 선호해야 한다.update
배치 처리 태스크의 경우.
JPA 또는 최대 절전 모드 엔티티는 다음 네 가지 상태 중 하나일 수 있다.
- 과도(신규)
- 관리됨(영구적)
- 분리됨
- 제거됨(삭제됨)
한 상태에서 다른 상태로의 전환은 기업관리자 또는 세션 방법을 통해 이루어진다.
를 들어, 예어 어, JPA는EntityManager
다음과 같은 엔티티 상태 전환 방법을 제공한다.
겨잠Session
모든 JPA 구현 EntityManager
메소드 및 와 같은 일부 추가 엔티티 상태 전환 방법을 제공한다.
지속하다
엔터티의 상태를 과도(신규)에서 관리(지속)로 변경하려면 JPA에서 제공하는 방법을 사용하십시오.EntityManager
또한 최대 절전 모드에서도 상속됨Session
.
그
persist
메소드가 a를 트리거한다.PersistEvent
에 의해 처리되는DefaultPersistEventListener
이벤트 수신기를 최대 절전 모드로 전환하십시오.
따라서 다음과 같은 테스트 케이스를 실행할 때:
doInJPA(entityManager -> {
Book book = new Book()
.setIsbn("978-9730228236")
.setTitle("High-Performance Java Persistence")
.setAuthor("Vlad Mihalcea");
entityManager.persist(book);
LOGGER.info(
"Persisting the Book entity with the id: {}",
book.getId()
);
});
최대 절전 모드에서는 다음 SQL 문이 생성된다.
CALL NEXT VALUE FOR hibernate_sequence
-- Persisting the Book entity with the id: 1
INSERT INTO book (
author,
isbn,
title,
id
)
VALUES (
'Vlad Mihalcea',
'978-9730228236',
'High-Performance Java Persistence',
1
)
다음 사항에 주목하십시오.id
다음 구성 요소를 장착하기 전에Book
현재 지속성 컨텍스트에 대한 엔티티.관리 엔티티가 다음 위치에 저장되기 때문에 이 작업이 필요함Map
키가 엔티티 유형과 그 식별자에 의해 형성되고 그 값이 엔티티 참조인 구조. JPA가 JPA가 있는 다.EntityManager
그리고 겨울잠Session
퍼스트 레벨 캐시로 알려져 있다.
전화할 때persist
, 엔티티는 현재 실행 중인 지속성 컨텍스트에만 연결되며, INSERT는 다음 기간까지 연기할 수 있다.flush
라고 불린다.
유일한 예외는 INSERT가 엔티티 식별자를 얻을 수 있는 유일한 방법이기 때문에 INSERT를 즉시 트리거하는 것이다.이 때문에 최대 절전 모드에서는 를 사용하여 엔티티에 대한 삽입물을 배치할 수 없다.IDENTITY
발전기
저장하다
최대 절전 모드별save
메소드는 JPA보다 앞서 있으며, 동면기 프로젝트가 시작된 이후부터 사용 가능했다.
그
save
메소드가 a를 트리거한다.SaveOrUpdateEvent
에 의해 처리되는DefaultSaveOrUpdateEventListener
이벤트 수신기를 최대 절전 모드로 전환하십시오.그러므로, The는save
방법은 에 해당한다.update
그리고saveOrUpdate
방법들
어떻게 하는지 보기 위해save
메서드가 작동하며, 다음 테스트 사례를 고려하십시오.
doInJPA(entityManager -> {
Book book = new Book()
.setIsbn("978-9730228236")
.setTitle("High-Performance Java Persistence")
.setAuthor("Vlad Mihalcea");
Session session = entityManager.unwrap(Session.class);
Long id = (Long) session.save(book);
LOGGER.info(
"Saving the Book entity with the id: {}",
id
);
});
위 테스트 케이스를 실행할 때, 최대 절전 모드에서는 다음과 같은 SQL 문이 생성된다.
CALL NEXT VALUE FOR hibernate_sequence
-- Saving the Book entity with the id: 1
INSERT INTO book (
author,
isbn,
title,
id
)
VALUES (
'Vlad Mihalcea',
'978-9730228236',
'High-Performance Java Persistence',
1
)
보시다시피 결과는 다음과 같다.persist
메서드 콜하지만, 달리persist
그save
메서드는 엔티티 식별자를 반환한다.
갱신하다
최대 절전 모드별update
방법은 더러운 점검 메커니즘을 무시하고 플러시 시간에 엔티티를 강제로 업데이트하기 위한 것이다.
그
update
메소드가 a를 트리거한다.SaveOrUpdateEvent
에 의해 처리되는DefaultSaveOrUpdateEventListener
이벤트 수신기를 최대 절전 모드로 전환하십시오.그러므로, The는update
방법은 에 해당한다.save
그리고saveOrUpdate
방법들
어떻게 하는지 보기 위해update
은 메소드 한다.Book
하나의 거래에서 엔티티를 수정한 다음, 엔티티가 분리된 상태일 때 수정하고, 를 사용하여 SQL UPDATE를 강제한다.update
메서드 콜
Book _book = doInJPA(entityManager -> {
Book book = new Book()
.setIsbn("978-9730228236")
.setTitle("High-Performance Java Persistence")
.setAuthor("Vlad Mihalcea");
entityManager.persist(book);
return book;
});
LOGGER.info("Modifying the Book entity");
_book.setTitle(
"High-Performance Java Persistence, 2nd edition"
);
doInJPA(entityManager -> {
Session session = entityManager.unwrap(Session.class);
session.update(_book);
LOGGER.info("Updating the Book entity");
});
위 테스트 케이스를 실행할 때, 최대 절전 모드에서는 다음과 같은 SQL 문이 생성된다.
CALL NEXT VALUE FOR hibernate_sequence
INSERT INTO book (
author,
isbn,
title,
id
)
VALUES (
'Vlad Mihalcea',
'978-9730228236',
'High-Performance Java Persistence',
1
)
-- Modifying the Book entity
-- Updating the Book entity
UPDATE
book
SET
author = 'Vlad Mihalcea',
isbn = '978-9730228236',
title = 'High-Performance Java Persistence, 2nd edition'
WHERE
id = 1
다음 사항에 주목하십시오.UPDATE
커밋 직전에 지속성 컨텍스트 플러시 중에 실행되므로Updating the Book entity
메시지가 먼저 기록된다.
사용.@SelectBeforeUpdate
불필요한 업데이트를 피하기 위해
이제 독립된 상태에 있는 동안 엔티티가 변경되지 않았더라도 업데이트는 항상 실행될 것이다. 이 지만하 기 를 하면 @SelectBeforeUpdate
를 트리거할 최대 절전 모드 주석SELECT
의 문안.loaded state
그 다음 더러운 점검 메커니즘에 의해 사용된다.
그래서 우리가 주석을 달면Book
에 동의하다@SelectBeforeUpdate
주석:
@Entity(name = "Book")
@Table(name = "book")
@SelectBeforeUpdate
public class Book {
//Code omitted for brevity
}
그리고 다음과 같은 테스트 케이스를 실행한다.
Book _book = doInJPA(entityManager -> {
Book book = new Book()
.setIsbn("978-9730228236")
.setTitle("High-Performance Java Persistence")
.setAuthor("Vlad Mihalcea");
entityManager.persist(book);
return book;
});
doInJPA(entityManager -> {
Session session = entityManager.unwrap(Session.class);
session.update(_book);
});
최대 절전 모드에서는 다음 SQL 문이 실행된다.
INSERT INTO book (
author,
isbn,
title,
id
)
VALUES (
'Vlad Mihalcea',
'978-9730228236',
'High-Performance Java Persistence',
1
)
SELECT
b.id,
b.author AS author2_0_,
b.isbn AS isbn3_0_,
b.title AS title4_0_
FROM
book b
WHERE
b.id = 1
주목하라, 이번에는, 아무것도 없다.UPDATE
최대 절전 모드 더러운 검사 메커니즘이 실체가 수정되지 않았음을 감지한 이후 실행됨.
SaveOrUpdate
최대 절전 모드별saveOrUpdate
방법은 단지 의 가명일 뿐이다.save
그리고update
.
그
saveOrUpdate
메소드가 a를 트리거한다.SaveOrUpdateEvent
에 의해 처리되는DefaultSaveOrUpdateEventListener
이벤트 수신기를 최대 절전 모드로 전환하십시오.그러므로, The는update
방법은 에 해당한다.save
그리고saveOrUpdate
방법들
이제, 당신은 사용할 수 있다.saveOrUpdate
엔티티를 유지하거나 강제로 적용하려는 경우UPDATE
다음 예에서 예시된 바와 같이
Book _book = doInJPA(entityManager -> {
Book book = new Book()
.setIsbn("978-9730228236")
.setTitle("High-Performance Java Persistence")
.setAuthor("Vlad Mihalcea");
Session session = entityManager.unwrap(Session.class);
session.saveOrUpdate(book);
return book;
});
_book.setTitle("High-Performance Java Persistence, 2nd edition");
doInJPA(entityManager -> {
Session session = entityManager.unwrap(Session.class);
session.saveOrUpdate(_book);
});
에 주의하라.NonUniqueObjectException
에 발생할 수 있는 한 가지 문제save
update
그리고saveOrUpdate
지속성 컨텍스트에 다음 예시와 동일한 ID와 유형의 엔티티 참조가 이미 포함되어 있는 경우:
Book _book = doInJPA(entityManager -> {
Book book = new Book()
.setIsbn("978-9730228236")
.setTitle("High-Performance Java Persistence")
.setAuthor("Vlad Mihalcea");
Session session = entityManager.unwrap(Session.class);
session.saveOrUpdate(book);
return book;
});
_book.setTitle(
"High-Performance Java Persistence, 2nd edition"
);
try {
doInJPA(entityManager -> {
Book book = entityManager.find(
Book.class,
_book.getId()
);
Session session = entityManager.unwrap(Session.class);
session.saveOrUpdate(_book);
});
} catch (NonUniqueObjectException e) {
LOGGER.error(
"The Persistence Context cannot hold " +
"two representations of the same entity",
e
);
}
이제 위의 테스트 케이스를 실행할 때, 최대 절전 모드에서는NonUniqueObjectException
두 번째가 되기 때문에EntityManager
이미 a를 포함하고 있다.Book
당사가 이전하는 것과 동일한 식별자를 가진 도면요소update
그리고 지속성 컨텍스트는 동일한 엔터티의 두 가지 표현을 포함할 수 없다.
org.hibernate.NonUniqueObjectException:
A different object with the same identifier value was already associated with the session : [com.vladmihalcea.book.hpjp.hibernate.pc.Book#1]
at org.hibernate.engine.internal.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:651)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:284)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:227)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:92)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:682)
at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:674)
병합
피하려면NonUniqueObjectException
, 당신은 그것을 사용할 필요가 있다.merge
JPA가 하는 방법은 과 같다.EntityManager
최대 절전 모드에 의해 상속됨Session
뿐만 아니라.
지속성 컨텍스트에 엔티티 참조가 없는 경우 데이터베이스에서 새 엔티티 스냅숏을 가져오고, 이 스냅샷은 에 전달된 분리된 엔티티의 상태를 복사한다.merge
방법
그
merge
메소드가 a를 트리거한다.MergeEvent
에 의해 처리되는DefaultMergeEventListener
이벤트 수신기를 최대 절전 모드로 전환하십시오.
어떻게 하는지 보기 위해merge
은 메소드 한다.Book
하나의 거래에서, 그 다음, 기업이 분리된 상태에 있는 동안 그것을 수정하고, 그 분리된 엔터티를 다음과 같이 전달한다.merge
지속성 컨텍스트에서 반복한다.
Book _book = doInJPA(entityManager -> {
Book book = new Book()
.setIsbn("978-9730228236")
.setTitle("High-Performance Java Persistence")
.setAuthor("Vlad Mihalcea");
entityManager.persist(book);
return book;
});
LOGGER.info("Modifying the Book entity");
_book.setTitle(
"High-Performance Java Persistence, 2nd edition"
);
doInJPA(entityManager -> {
Book book = entityManager.merge(_book);
LOGGER.info("Merging the Book entity");
assertFalse(book == _book);
});
위 테스트 케이스를 실행할 때, 최대 절전 모드에서는 다음 SQL 문을 실행했다.
INSERT INTO book (
author,
isbn,
title,
id
)
VALUES (
'Vlad Mihalcea',
'978-9730228236',
'High-Performance Java Persistence',
1
)
-- Modifying the Book entity
SELECT
b.id,
b.author AS author2_0_,
b.isbn AS isbn3_0_,
b.title AS title4_0_
FROM
book b
WHERE
b.id = 1
-- Merging the Book entity
UPDATE
book
SET
author = 'Vlad Mihalcea',
isbn = '978-9730228236',
title = 'High-Performance Java Persistence, 2nd edition'
WHERE
id = 1
다음에 의해 엔티티 참조가 반환됨merge
우리가 지나온 분리된 것과 다르다.merge
방법
지금은 JPA를 사용하는 것을 선호하지만merge
분리된 엔티티 상태를 복사할 때 추가 항목SELECT
일괄 처리 작업을 실행할 때 문제가 발생할 수 있다.
이러한 이유로 현재 실행 중인 지속성 컨텍스트에 이미 연결된 엔티티 참조가 없고 분리된 엔티티가 수정되었다고 확신할 때 사용하는 것을 선호해야 한다.
결론
엔티티를 유지하려면 JPA를 사용하십시오.persist
방법분리된 엔티티 상태를 복사하려면,merge
선호되어야 한다.그update
메소드는 배치 처리 작업에만 유용하다.그save
그리고saveOrUpdate
의 가명일 뿐이다update
그리고 너는 그것들을 전혀 사용해서는 안 될 것이다.
일부 개발자가 전화함save
심지어 엔티티가 이미 관리되고 있지만, 이것은 실수이며, 관리 엔티티의 경우, UPDATE는 지속성 컨텍스트 플러시 시간에 자동으로 처리되기 때문에 중복 이벤트를 트리거한다.
이 링크는 다음과 같이 잘 설명된다.
http://www.stevideter.com/2008/12/07/saveorupdate-versus-merge-in-hibernate/
우리 모두는 우리가 자주 접하지 않는 문제들을 가지고 있기 때문에 그것들을 다시 볼 때, 우리는 우리가 이것을 해결했다는 것을 알고 있지만, 어떻게 했는지 기억하지 못한다.
최대 절전 모드에서 Session.saveOrUpdate()를 사용할 때 발생하는 NonUniqueObjectException은 내 것 중 하나이다.복잡한 응용 프로그램에 새로운 기능을 추가할 겁니다.내 모든 유닛 테스트는 잘 작동한다.그런 다음 UI를 테스트하면서 개체를 저장하려고 하면 "이미 동일한 식별자 값을 가진 다른 개체가 세션에 연결되어 있었다"라는 메시지와 함께 예외를 받기 시작한다.다음은 최대 절전 모드인 Java Persistence의 몇 가지 예제 코드 입니다.
Session session = sessionFactory1.openSession();
Transaction tx = session.beginTransaction();
Item item = (Item) session.get(Item.class, new Long(1234));
tx.commit();
session.close(); // end of first session, item is detached
item.getId(); // The database identity is "1234"
item.setDescription("my new description");
Session session2 = sessionFactory.openSession();
Transaction tx2 = session2.beginTransaction();
Item item2 = (Item) session2.get(Item.class, new Long(1234));
session2.update(item); // Throws NonUniqueObjectException
tx2.commit();
session2.close();
이 예외의 원인을 이해하려면 분리된 개체와 분리된 개체에 대해 saveOrUpdate()(또는 업데이트()만 호출할 때 발생하는 상황을 이해하는 것이 중요하다.
개별 최대 절전 모드 세션을 닫으면 작업 중인 영구 개체가 분리된다.즉, 데이터가 애플리케이션의 메모리에 남아 있지만, 최대 절전 모드에서는 더 이상 개체의 변경 사항을 추적할 책임이 없다.
그런 다음 분리된 개체를 수정하고 업데이트하려면 개체를 다시 연결해야 한다.이 재첨부 과정 동안, 최대 절전 모드에서는 동일한 개체의 다른 복사본이 있는지 확인할 것이다.만약 발견된다면, 그것은 우리에게 "진짜" 복사본이 무엇인지 더 이상 알 수 없다고 말해야 한다.아마도 우리가 저장될 것으로 예상하는 다른 복사본에 다른 변경이 가해졌을 것이다. 하지만 브라이버나이트는 그 복사본에 대해 알지 못한다. 왜냐하면 당시에는 그것을 관리하지 않았기 때문이다.
Brievenote는 나쁜 데이터를 저장하기 보다는 NonUniqueObjectException을 통해 문제에 대해 알려준다.
그럼 우린 어떻게 해야 하지?최대 절전 모드 3에서는 병합()이 있으며 최대 절전 모드 2에서는 saveOrUpdateCopy()를 사용하십시오.이 방법을 사용하면 최대 절전 모드에서는 다른 분리된 인스턴스의 변경 내용을 저장하려는 인스턴스로 복사하므로 저장하기 전에 메모리의 모든 변경 내용을 병합한다.
Session session = sessionFactory1.openSession();
Transaction tx = session.beginTransaction();
Item item = (Item) session.get(Item.class, new Long(1234));
tx.commit();
session.close(); // end of first session, item is detached
item.getId(); // The database identity is "1234"
item.setDescription("my new description");
Session session2 = sessionFactory.openSession();
Transaction tx2 = session2.beginTransaction();
Item item2 = (Item) session2.get(Item.class, new Long(1234));
Item item3 = session2.merge(item); // Success!
tx2.commit();
session2.close();
merge는 인스턴스의 새로 업데이트된 버전에 대한 참조를 반환한다는 점에 유의하십시오.그것은 세션에 항목을 다시 첨부하는 것이 아니다.예를 들어 동등성(항목 == 항목3)을 검정하면 이 경우 거짓이 반환된다는 것을 알 수 있다.당신은 아마 이 시점부터 항목3로 작업하기를 원할 것이다.
JPA(Java Persistence API)는 분리 및 재연결 객체의 개념이 없고 엔티티 매니저를 사용한다는 점도 유의해야 한다.지속() 및 엔티티 매니저.merge().
일반적으로 최대 절전 모드를 사용할 때 saveOrUpdate()가 내 필요에 충분하다는 것을 알게 되었다.나는 대개 같은 유형의 객체에 대한 참조를 가질 수 있는 객체가 있을 때만 병합을 사용하면 된다.가장 최근, 예외의 원인은 참조가 재귀적이지 않다는 것을 증명하는 코드였다.유효성 검사의 일부로 세션에 동일한 개체를 로드하여 오류를 발생시키는 중이었습니다.
어디서 이 문제를 접하셨습니까?합병은 당신에게 효과가 있었는가 아니면 다른 해결책이 필요했는가?항상 병합을 사용하는 것이 좋으십니까? 아니면 특정 경우에 필요한 경우에만 병합을 사용하는 것이 좋으십니까?
사실 겨울잠과의 차이점save()
그리고persist()
방법은 우리가 사용하고 있는 발전기 등급에 따라 달라진다.
제너레이터 클래스가 할당되면save()
그리고persist(
방법 ' 키 값을 해야 한다는 것을 하기 때문에 를 희망한다 ], 만일 키 [제너레이터 'assigned'는 프로그래머로서 우리는 데이터베이스에 저장할 기본 키 값을 제공해야 함을 의미하기 때문에 [이 발전기 개념을 알고 있기를 ] 할당된 제너레이터 클래스가 아닌 다른 경우, 만일 우리의 제너레이터 클래스 이름이 Incremental(증분)이라면 그것은 스스로 기본 키 ID 값을 데이터베이스 권리에 할당한다고 가정하자 [oth]할당된 제너레이터보다 높은 최대 절전 모드에서는 기본 키 ID 값을 기억하는 데만 사용되므로, 이 경우 호출할 경우save()
또는persist()
그러면 정상적으로 데이터베이스에 기록을 삽입할 수 있지만, 하지만 듣기론save()
메소드는 최대 절전 모드로 생성되는 기본 키 ID 값을 반환할 수 있으며 우리는 다음을 통해 이를 확인할 수 있다.
long s = session.save(k);
은색 경우,persist()
고객에게 어떤 가치도 돌려주지 않을 것이다.
모든 최대 절전 모드 저장 방법의 차이를 보여주는 좋은 예를 찾았다.
http://www.journaldev.com/3481/hibernate-session-merge-vs-update-save-saveorupdate-persist-example
간단히, 위의 링크에 따라:
절약하다
- 우리는 거래 밖에서 이 방법을 호출할 수 있다.만약 우리가 이것을 거래 없이 사용하고, 우리가 기업들 사이에 폭포화가 있다면, 우리가 세션을 해제하지 않는 한, 오직 주요 기업만이 저장될 것이다.
- 따라서 주 개체에서 매핑된 다른 개체가 있으면 트랜잭션을 커밋하거나 세션을 플러시할 때 저장된다.
끈질기게 물고 늘어지다
- 트랜잭션에서 저장()을 사용하는 것과 비슷하므로 안전하고 계단식 객체를 관리하십시오.
saveOrUpdate()
트랜잭션과 함께 또는 트랜잭션 없이 사용될 수 있으며, 저장()과 마찬가지로, 트랜잭션 없이 사용될 경우 매핑된 엔티티가 저장되지 않으며, 세션을 플러시해야 한다.
제공된 데이터를 기반으로 쿼리를 삽입하거나 업데이트하는 결과.데이터베이스에 데이터가 있으면 업데이트 쿼리가 실행된다.
update
- 최대 절전 모드 업데이트는 엔티티 정보만 업데이트한다는 것을 알고 있는 경우에 사용해야 한다.이 작업은 엔티티 객체를 영구 컨텍스트에 추가하며, 트랜잭션이 커밋될 때 추가 변경사항을 추적하여 저장한다.
- 따라서 업데이트를 호출한 후에도, 만약 우리가 엔티티에 어떤 값을 설정한다면, 그것들은 거래가 성사될 때 업데이트될 것이다.
합병하다
- 최대 절전 모드 병합은 기존 값을 업데이트하는 데 사용할 수 있지만 이 방법은 전달된 엔티티 개체에서 복사본을 만들어 반환한다.반환된 개체는 영구 컨텍스트의 일부로서 변경사항을 추적하지만 전달된 개체는 추적되지 않는다.이것은 다른 모든 방법들과 병합()의 주요한 차이점이다.
또한 이러한 모든 방법의 실제적인 예는 위에서 언급한 링크를 참조하십시오. 이 모든 방법의 예는 다음과 같다.
분리된 개체에 대한 업데이트를 호출하는 경우, 개체를 변경했는지 여부에 관계없이 데이터베이스에는 항상 업데이트가 수행된다는 점에 유의하십시오.Session.lock()을 LockMode와 함께 사용하십시오.없음
개체가 현재 세션 범위 밖에서 변경된 경우에만(분리 모드일 때) 업데이트를 호출하십시오.
다음 답은 하나도 맞지 않는다.이 모든 방법은 그저 비슷해 보이지만 실제로는 전혀 다른 일을 한다.짧은 코멘트를 하는 것은 어렵다.다음 방법에 대한 전체 설명서에 대한 링크를 제공하는 것이 좋다. http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/objectstate.html
위의 답변 중 어느 것도 완전하지 않다.비록 레오 테오발드의 대답은 가장 가까운 대답으로 보인다.
기본 포인트는 동면기가 실체의 상태를 어떻게 다루고 있으며, 상태 변화가 있을 때 실체를 어떻게 처리하느냐이다.모든 것은 모든 사람이 완전히 무시한 것처럼 보이는, 플러싱과 커미션에 관해서도 보여야 한다.
절대 동면 저장 방법을 사용하지 마십시오. 동면 모드에도 동면 방법이 존재한다는 사실을 잊으십시오!
지속하다
모두가 설명했듯이, 지속은 기본적으로 엔터티를 "투명" 상태에서 "관리됨" 상태로 전환한다.이때 슬러시나 범행이 삽입문을 만들 수 있다.그러나 기업은 여전히 "관리됨" 상태를 유지할 것이다.그것은 플러쉬와는 달라지지 않는다.
이쯤에서 다시 '퍼시스트'하면 아무런 변화도 없을 것이다.그리고 우리가 지속된 실체를 유지하려고 노력한다면 더 이상의 구제는 없을 것이다.
그 재미는 우리가 그 실체를 쫓아내려고 할 때 시작된다.
퇴출은 "관리됨"에서 "상세됨"으로 전환되는 최대 절전 모드 특수 기능이다.우리는 독립된 단체를 고집할 수 없다.그러면 최대 절전 모드에서는 예외가 발생하고 전체 트랜잭션은 커밋에서 롤백된다.
병합 및 업데이트
이것들은 서로 다른 방식으로 다루어질 때 서로 다른 일을 하는 두 가지 흥미로운 기능이다.두 사람 모두 실체를 '상세' 상태에서 '관리됨' 상태로 전환하려 하고 있다.하지만 다르게 한다.
분리된 상태가 일종의 "오프라인" 상태를 의미한다는 사실을 이해하십시오.관리됨은 "온라인" 상태를 의미한다.
아래 코드를 준수하십시오.
Session ses1 = sessionFactory.openSession();
Transaction tx1 = ses1.beginTransaction();
HibEntity entity = getHibEntity();
ses1.persist(entity);
ses1.evict(entity);
ses1.merge(entity);
ses1.delete(entity);
tx1.commit();
이럴 때?어떻게 될 것 같아?만약 당신이 이것이 예외를 제기할 것이라고 말했다면, 당신은 옳다.이는 병합이 독립된 상태인 개체에서 작동했기 때문에 예외를 제기할 것이다.그러나 그것이 물체의 상태를 바꾸지는 않는다.
현장 뒤에서, 병합은 선택된 질의를 제기할 것이고 기본적으로 첨부된 상태의 실체 사본을 반환할 것이다.아래 코드를 준수하십시오.
Session ses1 = sessionFactory.openSession();
Transaction tx1 = ses1.beginTransaction();
HibEntity entity = getHibEntity();
ses1.persist(entity);
ses1.evict(entity);
HibEntity copied = (HibEntity)ses1.merge(entity);
ses1.delete(copied);
tx1.commit();
위의 샘플은 합병으로 인해 새로운 실체가 지속되는 컨텍스트에 도달했기 때문에 효과가 있다.
업데이트가 실제로 병합과 같은 엔티티의 복사본을 가져오지 않기 때문에 Update를 적용하면 동일한 작업이 수행된다.
Session ses1 = sessionFactory.openSession();
Transaction tx1 = ses1.beginTransaction();
HibEntity entity = getHibEntity();
ses1.persist(entity);
ses1.evict(entity);
ses1.update(entity);
ses1.delete(entity);
tx1.commit();
동시에 디버그 추적에서 Update가 병합과 같은 선택 SQL 쿼리를 올리지 않았음을 알 수 있다.
삭제하다
위의 예에서 나는 삭제에 대해 말하지 않고 삭제를 사용했다.삭제는 기본적으로 엔티티를 관리 상태에서 "제거된" 상태로 전환한다.그리고 플러시되거나 커밋되면 저장하기 위해 삭제 명령을 내린다.
그러나 지속적 방법을 사용하여 엔터티를 "제거된" 상태에서 "관리된" 상태로 되돌릴 수 있다.
위의 설명이 의심스러운 점이 없기를 바란다.
'Programing' 카테고리의 다른 글
Vue v-model.lazy 또는 @change가 내 Vue 데이터를 업데이트하지 않음 (0) | 2022.04.26 |
---|---|
GCC의 ##_VA_에 대한 표준 대안ARGS__ 트릭? (0) | 2022.04.26 |
이 항목에 대한 액세스.Vuex 스토어에서 $apollo, NUXT에서 vue-apollo? (0) | 2022.04.26 |
JPA 및 최대 절전 모드 - 기준 대 JPQL 또는 HQL (0) | 2022.04.25 |
렌더 오류: "TypeError: 정의되지 않은 속성 '길이'를 읽을 수 없음" (0) | 2022.04.25 |