[java] Hibernate “객체가 저장되지 않은 임시 인스턴스를 참조-플러시하기 전에 임시 인스턴스 저장”오류를 수정하는 방법

최대 절전 모드를 사용하여 개체를 저장할 때 다음 오류가 발생합니다.

object references an unsaved transient instance - save the transient instance before flushing



답변

컬렉션 매핑에 ( cascade="all"xml을 사용하는 경우) 또는 cascade=CascadeType.ALL(주석을 사용하는 경우 ) 포함해야 합니다.

이것은 엔티티에 콜렉션이 있고 해당 콜렉션에 데이터베이스에없는 하나 이상의 항목이 있기 때문에 발생합니다. 위의 옵션을 지정하면 부모를 저장할 때 데이터베이스에 저장하도록 최대 절전 모드를 설정합니다.


답변

나는 이것이 반복되는 대답 일 것이라고 생각하지만, 명확히하기 위해 @OneToOne매핑뿐만 아니라을 얻었 습니다 @OneToMany. 두 경우 모두 Child내가 추가 한 객체 Parent가 데이터베이스에 아직 저장되지 않았다는 사실입니다 . 나는를 추가 할 때 그래서 Child받는 Parent후 저장 Parent, Hibernate는 던져 것 "object references an unsaved transient instance - save the transient instance before flushing"부모를 저장할 때 메시지.

두 경우 모두 문제를 해결 하기 cascade = {CascadeType.ALL}위해 Parent's참조를 추가 Child하면 문제가 해결됩니다. 이것은 구원 Child과를 Parent.

반복되는 답변에 대해 죄송합니다. 사람들을 위해 더 명확하게 설명하고 싶었습니다.

@OneToOne(cascade = {CascadeType.ALL})
@JoinColumn(name = "performancelog_id")
public PerformanceLog getPerformanceLog() {
    return performanceLog;
}


답변

이것은 Hibernate가 당신이 저장하고있는 객체와 관련된 객체를 저장해야한다고 생각할 때 객체를 저장할 때 발생합니다.

나는이 문제가 있었고 참조 된 객체의 변경 사항을 저장하고 싶지 않아서 캐스케이드 유형이 없음을 원했습니다.

요령은 Hibernate가 참조 된 오브젝트가 저장이 필요한 새로운 오브젝트라고 생각하지 않도록 참조 된 오브젝트의 ID와 VERSION이 설정되도록하는 것이다. 이것은 나를 위해 일했습니다.

저장하는 클래스의 모든 관계를 살펴보고 연관된 오브젝트 (및 연관된 오브젝트의 연관된 오브젝트)를 해결하고 오브젝트 트리의 모든 오브젝트에 ID 및 VERSION이 설정되어 있는지 확인하십시오.


답변

소개

JPA 및 Hibernate를 사용할 때이 기사 에서 설명했듯이 엔티티는 다음 4 가지 상태 중 하나 일 수 있습니다.

  • 새로 만들기 -최대 절전 모드 세션 (일명 지속성 컨텍스트)과 연결되지 않았으며 데이터베이스 테이블 행에 매핑되지 않은 새로 생성 된 개체는 새로 만들기 또는 임시 상태 인 것으로 간주됩니다.

    지속 되려면 persist메소드 를 명시 적으로 호출 하거나 전이 지속 메커니즘을 사용해야합니다.

  • 지속적 -지속적 엔티티가 데이터베이스 테이블 행과 연관되었으며 현재 실행중인 지속성 컨텍스트에 의해 관리되고 있습니다.

    이러한 엔티티에 대한 모든 변경 사항은 감지되어 데이터베이스로 전파됩니다 (세션 플러시 시간 동안).

  • 분리됨 -현재 실행중인 지속성 컨텍스트가 닫히면 이전에 관리 된 모든 엔티티가 분리됩니다. 연속적인 변경 사항은 더 이상 추적되지 않으며 자동 데이터베이스 동기화가 수행되지 않습니다.

  • 제거됨 -JPA에서는 관리 대상 엔티티 만 제거하도록 요구하지만 Hibernate는 분리 된 엔티티를 삭제할 수도 있습니다 (단, remove메소드 호출을 통해서만 ).

엔터티 상태 전환

다른 한 상태에서 개체를 이동하려면, 당신은 사용할 수 있습니다 persist, remove또는 merge방법.

JPA 엔티티 상태

문제 해결

질문에서 설명하는 문제 :

object references an unsaved transient instance - save the transient instance before flushing

New 상태의 엔터티를 Managed 상태 인 엔터티에 연결하면 발생합니다 .

자식 엔터티를 부모 엔터티의 일대 다 컬렉션에 연결하고 컬렉션이 cascade엔터티 상태 전환 이 아닌 경우에 발생할 수 있습니다 .

따라서이 기사 에서 설명했듯이 다음과 같이이 실패를 트리거 한 엔티티 연관에 계단식을 추가하여이 문제를 해결할 수 있습니다.

@OneToOne협회

@OneToOne(
    mappedBy = "post",
    orphanRemoval = true,
    cascade = CascadeType.ALL)
private PostDetails details;

속성에 CascadeType.ALL추가 한 값을 확인하십시오 cascade.

@OneToMany협회

@OneToMany(
    mappedBy = "post",
    orphanRemoval = true,
    cascade = CascadeType.ALL)
private List<Comment> comments = new ArrayList<>();

또한, 양방향 연관에 CascadeType.ALL적합합니다 .@OneToMany

이제 계단식 배열이 양방향으로 제대로 작동하려면 부모 및 자식 연결이 동기화되어 있는지 확인해야합니다.

이 목표를 달성하는 가장 좋은 방법에 대한 자세한 내용은 이 기사 를 확인하십시오 .

@ManyToMany협회

@ManyToMany(
    mappedBy = "authors",
    cascade = {
        CascadeType.PERSIST,
        CascadeType.MERGE
    }
)
private List<Book> books = new ArrayList<>();

@ManyToMany연관 에서는 CascadeType.ALL또는 orphanRemoval하나의 상위 엔티티에서 다른 상위 엔티티로 엔티티 삭제 상태 전이를 전파하므로 또는 사용할 수 없습니다 .

따라서 @ManyToMany연결의 경우 일반적으로 CascadeType.PERSIST또는 CascadeType.MERGE작업을 계단식으로 연결 합니다. 또는이를 DETACH또는로 확장 할 수 있습니다 REFRESH.

@ManyToMany연결 을 매핑하는 가장 좋은 방법에 대한 자세한 내용은 이 기사 도 확인하십시오 .


답변

또는 최소한의 “파워”를 사용하려면 (예 : 계단식 삭제를 원하지 않는 경우) 원하는 것을 달성하십시오.

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;

...

@Cascade({CascadeType.SAVE_UPDATE})
private Set<Child> children;


답변

제 경우이를 구비하지 기인 된 CascadeType@ManyToOne쌍방향 관계의 측면. 더 정확히 말하면, 나는했다 CascadeType.ALL@OneToMany측면과 그것을하지 않았다 @ManyToOne. 추가 CascadeType.ALL하여 @ManyToOne문제 를 해결했습니다.
일대 다 측면 :

@OneToMany(cascade = CascadeType.ALL, mappedBy="globalConfig", orphanRemoval = true)
private Set<GlobalConfigScope>gcScopeSet;

다대 일면 (문제를 일으켰다)

@ManyToOne
@JoinColumn(name="global_config_id")
private GlobalConfig globalConfig;

다 대일 (을 추가하여 수정 CascadeType.PERSIST)

@ManyToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name="global_config_id")
private GlobalConfig globalConfig;


답변

이것은 데이터베이스의 기존 레코드에 @Version으로 주석이 달린 필드에 대한 NULL 값이있는 엔티티를 유지할 때 발생했습니다 (낙관적 잠금). 데이터베이스에서 NULL 값을 0으로 업데이트하면이 문제가 해결되었습니다.