최대 절전 모드를 사용하여 개체를 저장할 때 다음 오류가 발생합니다.
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
방법.
문제 해결
질문에서 설명하는 문제 :
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으로 업데이트하면이 문제가 해결되었습니다.