programing

세션의 차이점은 무엇입니까?persist()와 session.save()는 휴지 상태입니까?

bestcode 2022. 9. 30. 11:15
반응형

세션의 차이점은 무엇입니까?persist()와 session.save()는 휴지 상태입니까?

persist() »save()동상????

포럼 투고에서

persist()을 사용하다일시적인 인스턴스를 영속적으로 만듭니다.단, 식별자 값이 영구 인스턴스에 즉시 할당되는 것은 아니며 플래시 시간에 할당될 수 있습니다. 있지 , 그것이 예요.그게 바로 제가 안고 있는 문제예요persist()

persist()또한 트랜잭션 경계 밖에서 호출된 경우 INSERT 문을 실행하지 않음을 보증합니다.이 기능은 확장 세션/영속 컨텍스트를 사용하여 장시간 실행되는 컨버세이션에 도움이 됩니다.

★★★★★★★★★★★★★★★★★★ persist()필수 항목입니다.

save()는 동일한 것을 보증하지 않고 식별자를 반환하며, 식별자를 얻기 위해 INSERT를 실행해야 하는 경우(예를 들어 "시퀀스"가 아닌 "ID" 생성기), 이 INSERT는 트랜잭션의 내부 또는 외부에 관계없이 즉시 실행됩니다.이는 세션/지속성이 확장된 컨텍스트를 사용한 장시간 실행 컨버세이션에서는 좋지 않습니다.

save() vs. persist()에 대해 로컬머신에서 여러 번 실행하는 것을 포함하여 잘 조사했습니다.지금까지의 설명은 모두 혼란스럽고 부정확하다.상세한 조사를 거쳐 아래의 save() 메서드와 persist() 메서드를 비교합니다.

Save()

  1. 아이디반환 유형은 다음과 같습니다.Serializable;
  2. 변경 내용을 트랜잭션 외부에 데이터베이스에 저장합니다.
  3. 생성된 ID를 영속하는 엔티티에 할당합니다.
  4. session.save()분리된 객체의 경우 테이블에 새 행을 만듭니다.

Persist()

  1. 아이디반환 유형은 다음과 같습니다.void;
  2. 변경 내용을 트랜잭션 외부에 데이터베이스에 저장하지 않습니다.
  3. 생성된 Id를 영속하는 엔티티에 할당합니다.
  4. session.persist() 있는 는 어 a a a a a a a a a a a a a a a a a a a를 던진다.PersistentObjectException츠미야

것을 해 봅니다.Hibernate v4.0.1.

save() ★★★★★★★★★★★★★★★★★」persist().

이 두 가지 방법 모두 임시 엔티티를 처리할 때는 동일하게 동작하지만 분리된 엔티티를 처리할 때는 다르게 보입니다.

이다 Employee를 예로 . 엔티티)vehicleId이고 이 값은 생성 값입니다.vehicleName그특 、 중나나서서서 서나서서 。

예 1: 과도 객체의 처리

Session session = factory.openSession();
session.beginTransaction();
EmployeeVehicle entity = new EmployeeVehicle();
entity.setVehicleName("Honda");
session.save(entity);
// session.persist(entity);
session.getTransaction().commit();
session.close();

결과:

select nextval ('hibernate_sequence') // This is for vehicle Id generated : 36
insert into Employee_Vehicle ( Vehicle_Name, Vehicle_Id) values ( Honda, 36)

이미 지속된 개체를 가져와 저장해도 결과는 동일합니다.

EmployeeVehicle entity =  (EmployeeVehicle)session.get(EmployeeVehicle.class, 36);
entity.setVehicleName("Toyota");
session.save(entity);    -------> **instead of session.update(entity);**
// session.persist(entity);

같은 해 주세요.persist(entity): 37혼다 ID(예: 37, 혼다)를 가 됩니다.

예 2: 분리된 오브젝트 처리

// Session 1 
// Get the previously saved Vehicle Entity 
Session session = factory.openSession();
session.beginTransaction();
EmployeeVehicle entity = (EmployeeVehicle)session.get(EmployeeVehicle.class, 36);
session.close();

// Session 2
// Here in Session 2 , vehicle entity obtained in previous session is a detached object and now we will try to save / persist it 
// (i) Using Save() to persist a detached object 
Session session2 = factory.openSession();
session2.beginTransaction();
entity.setVehicleName("Toyota");
session2.save(entity);
session2.getTransaction().commit();
session2.close();

결과: 이전 세션에서 얻은 ID 36의 차량은 이름이 '도요타'로 갱신됩니다.그러나 새로운 엔티티가 생성되고 이름이 '도요타'로 DB에 저장됩니다.

select nextval ('hibernate_sequence')
insert into Employee_Vehicle ( Vehicle_Name, Vehicle_Id) values ( Toyota, 39)

persist를 사용하여 분리된 엔티티 유지

// (ii) Using Persist()  to persist a detached
// Session 1 
Session session = factory.openSession();
session.beginTransaction();
EmployeeVehicle entity = (EmployeeVehicle)session.get(EmployeeVehicle.class, 36);
session.close();

// Session 2
// Here in Session 2 , vehicle entity obtained in previous session is a detached object and now we will try to save / persist it 
// (i) Using Save() to persist a detached
Session session2 = factory.openSession();
session2.beginTransaction();
entity.setVehicleName("Toyota");
session2.persist(entity);
session2.getTransaction().commit();
session2.close();

결과:

Exception being thrown : detached entity passed to persist

따라서 Save()가 아닌 Persist()를 사용하는 것이 좋습니다.Transient 객체를 다룰 때는 저장을 신중하게 사용해야 하기 때문입니다.

중요사항 : 위의 예에서는 차량 엔티티의 pk는 생성된 값입니다.따라서 save()를 사용하여 독립 엔티티를 유지할 경우 hibernate는 지속하기 위한 새로운 ID를 생성합니다.그러나 이 pk가 생성된 값이 아닌 경우 키 위반을 나타내는 예외가 발생합니다.

질문에는 휴지 상태의 다양한 지속성 방법에 대한 좋은 답변이 있습니다.질문에 직접 답변하기 위해 save()를 사용하면 트랜잭션 상태에 관계없이 삽입문이 즉시 실행됩니다.삽입된 키가 반환되므로 다음과 같은 작업을 수행할 수 있습니다.

long newKey = session.save(myObj);

따라서 영속 인스턴스에 즉시 ID를 할당해야 할 경우 save()를 사용합니다.

persist()를 사용하면 insert 문이 트랜잭션에서 즉시 실행되지는 않습니다.대부분의 경우 이 방법이 더 좋습니다.

트랜잭션에서 순서가 어긋나거나 삽입된 키를 반환할 필요가 없는 경우 persist()를 사용합니다.

persist 메서드와 save 메서드의 장점을 이해하는 데 도움이 되는 차이는 다음과 같습니다.

  • 저장과 지속의 첫 번째 차이점은 반환 유형입니다.이고 반환 입니다.
    method serial시리얼화 가능
  • persist() 메서드는 식별자 값이 즉시 영속적인 상태에 할당되는 것을 보증하지 않습니다.플래시 시에 할당될 수 있습니다.

  • persist() 메서드는 삽입 쿼리가 트랜잭션 경계 밖에서 호출될 경우 해당 쿼리를 실행하지 않습니다.한편, save() 메서드는 ID를 반환하므로 트랜잭션 내부 또는 외부에 관계없이 삽입 쿼리가 즉시 실행되어 ID를 가져옵니다.

  • 지속 메서드는 트랜잭션 경계 외부에서 호출되며 확장 세션 컨텍스트와의 장시간 대화에서 유용합니다.한편, 확장 세션콘텍스트를 사용한 장시간 실행 컨버세이션에서는 save 방식은 적합하지 않습니다.

  • 휴지 상태에서의 저장과 지속 방법의 다섯 번째 차이: 지속은 JPA에서 지원되지만 저장 기능은 휴지 상태에서만 지원됩니다.

휴지 상태의 저장과 지속 방법의 차이에서 전체 작업 예를 볼 수 있습니다.

save()- 메서드 이름에서 알 수 있듯이 hibernate save()를 사용하여 엔티티를 데이터베이스에 저장할 수 있습니다.트랜잭션 외부에서 이 메서드를 호출할 수 있습니다.트랜잭션 없이 이를 사용하고 엔티티 간에 캐스케이드가 있는 경우 세션을 플러시하지 않는 한 프라이머리 엔티티만 저장됩니다.

persist()-Hibernate persist는 저장(트랜잭션 사용)과 비슷하며 엔티티 객체를 영속 컨텍스트에 추가하므로 추가 변경이 추적됩니다.트랜잭션이 커밋되거나 세션이 플러시되기 전에 개체 속성이 변경되면 데이터베이스에도 저장됩니다.또한 persist() 메서드는 트랜잭션 경계 내에서만 사용할 수 있기 때문에 안전하고 캐스케이드된 오브젝트를 처리할 수 있습니다.마지막으로 persist는 아무것도 반환하지 않으므로 생성된 식별자 값을 가져오기 위해 persisted 객체를 사용해야 합니다.

기본 규칙은 다음과 같습니다.

식별자가 생성된 엔티티의 경우:

save() : 오브젝트를 영속화할 뿐만 아니라 엔티티의 ID를 즉시 반환합니다.따라서 삽입 쿼리가 즉시 실행됩니다.

persist() : 영속적인 오브젝트를 반환합니다.ID를 즉시 반환할 필요가 없기 때문에 삽입이 즉시 실행된다는 보장은 없습니다.인서트가 즉시 발사될 수 있지만 보장되지는 않습니다.쿼리가 즉시 실행되는 경우도 있고 세션플래시 시간에 실행되는 경우도 있습니다.

식별자가 할당된 엔티티의 경우:

save(): 엔티티의 ID를 즉시 반환합니다.ID는 save를 호출하기 전에 이미 엔티티에 할당되어 있기 때문에 삽입은 즉시 실행되지 않습니다.세션 플래시 시간에 실행됩니다.

persist() : 저장과 동일합니다.플러시 타임에 인서트를 발사하기도 합니다.

다음과 같이 생성된 식별자를 사용하는 엔티티가 있다고 가정합니다.

@Entity
@Table(name="USER_DETAILS")
public class UserDetails {
    @Id
    @Column(name = "USER_ID")
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int userId;

    @Column(name = "USER_NAME")
    private String userName;

    public int getUserId() {
        return userId;
    }
    public void setUserId(int userId) {
        this.userId = userId;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
}

save() :

    Session session = sessionFactory.openSession();
    session.beginTransaction();
    UserDetails user = new UserDetails();
    user.setUserName("Gaurav");
    session.save(user); // Query is fired immediately as this statement is executed.
    session.getTransaction().commit();
    session.close();

persist() :

    Session session = sessionFactory.openSession();
    session.beginTransaction();
    UserDetails user = new UserDetails();
    user.setUserName("Gaurav");
    session.persist(user); // Query is not guaranteed to be fired immediately. It may get fired here.
    session.getTransaction().commit(); // If it not executed in last statement then It is fired here.
    session.close();

이제 id 필드가 주석을 생성하지 않고 다음과 같이 정의된 동일한 엔티티가 있다고 가정합니다.ID는 수동으로 할당됩니다.

@Entity
@Table(name="USER_DETAILS")
public class UserDetails {
    @Id
    @Column(name = "USER_ID")
    private int userId;

    @Column(name = "USER_NAME")
    private String userName;

    public int getUserId() {
        return userId;
    }
    public void setUserId(int userId) {
        this.userId = userId;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
}

save()의 경우:

Session session = sessionFactory.openSession();
session.beginTransaction();
UserDetails user = new UserDetails();
user.setUserId(1);
user.setUserName("Gaurav");
session.save(user); // Query is not fired here since id for object being referred by user is already available. No query need to be fired to find it. Data for user now available in first level cache but not in db.
session.getTransaction().commit();// Query will be fired at this point and data for user will now also be available in DB
session.close();

persist()의 경우:

Session session = sessionFactory.openSession();
session.beginTransaction();
UserDetails user = new UserDetails();
user.setUserId(1);
user.setUserName("Gaurav");
session.persist(user); // Query is not fired here.Object is made persistent. Data for user now available in first level cache but not in db.
session.getTransaction().commit();// Query will be fired at this point and data for user will now also be available in DB
session.close();

트랜잭션 내에서 저장 또는 지속이 호출되었을 때 위의 경우가 해당되었습니다.

save와 persist의 다른 차이점은 다음과 같습니다.

  1. save()는 트랜잭션 외부에서 호출할 수 있습니다.할당된 식별자를 사용하는 경우 ID가 이미 사용 가능하므로 삽입 쿼리는 즉시 실행되지 않습니다.쿼리는 세션이 플러시될 때만 실행됩니다.

  2. 생성된 식별자를 사용하는 경우 ID를 생성해야 하므로 삽입이 즉시 실행됩니다.하지만 주요 엔티티만 구합니다.엔티티에 캐스케이드된 엔티티가 있는 경우 해당 엔티티는 현재 db에 저장되지 않습니다.세션이 플러시되면 저장됩니다.

  3. persist()가 트랜잭션 외부에 있는 경우 어떤 종류의 식별자(생성 또는 할당됨)가 사용되든 세션이 플러시될 때만 삽입이 실행됩니다.

  4. 영구 개체를 통해 저장을 호출한 경우 엔티티는 업데이트 쿼리를 사용하여 저장됩니다.

차이점은 다음과 같습니다.

  1. 저장:

    1. 오브젝트가 데이터베이스에 저장되면 ID/ID가 반환됩니다.
    2. 또한 오브젝트가 분리된 후 새 세션을 열어 동일한 작업을 수행하려고 할 때도 저장됩니다.
  2. 지속:

    1. 오브젝트가 데이터베이스에 저장되면 void가 반환됩니다.
    2. 새 세션을 통해 분리된 개체를 저장하려고 하면 Persistent Object Exception이 느려집니다.

실제로 hibernate save() 메서드와 persist() 메서드의 차이는 사용하고 있는 제너레이터 클래스에 따라 달라집니다.
제너레이터 클래스가 할당되어 있는 경우 save() 메서드와 persist() 메서드는 차이가 없습니다.generator 'assigned' generator ' 、 [ Hope you know this generators concept ]그래서 generator ID 인크리먼트할당된 제너레이터보다 하이버네이션은 프라이머리 키 ID 값 remember]에만 사용됩니다.따라서 이 경우 save() 또는 persist() 메서드를 호출하면 레코드는 정상적으로 데이터베이스에 삽입됩니다.
서 save에 의해 키할 수 save()를 통해 확인할 수 .
s = long s = session.save(k);
이 경우 persist()는 클라이언트에 값을 반환하지 않고 void 유형을 반환합니다.
persist()는 INSERT 스테이트먼트가 트랜잭션 경계 밖으로 호출되었을 경우에도 실행되지 않음을 보증합니다.
한편 save()에서는 트랜잭션 내부 또는 외부에 관계없이 INSERT가 즉시 실행됩니다.

엔티티를 저장하면서 ID의 "제너레이터" 유형에 따라 완전히 응답했습니다.생성기 값이 "할당됨"인 경우, 즉 ID를 제공합니다.그 후 저장 또는 지속을 위해 휴지 상태에서도 차이가 없습니다.원하는 방법으로 갈 수 있다.값이 "할당"되지 않고 save()를 사용하는 경우 save() 작업에서 반환되는 ID를 얻을 수 있습니다.

또 다른 체크는 트랜잭션 제한 범위를 벗어난 작업을 수행하는지 여부입니다.persist()는 JPA에 속하고 save()는 휴지 상태이기 때문입니다.따라서 외부 트랜잭션 경계에서 persist()를 사용하면 persistent와 관련된 예외를 발생시킬 수 없습니다.한편 save()에서는 이러한 제한이 없으며 트랜잭션 제한 범위를 벗어나 save()를 통해 DB 트랜잭션을 수행할 수 있습니다.

언급URL : https://stackoverflow.com/questions/5862680/whats-the-difference-between-session-persist-and-session-save-in-hibernate

반응형