휴지 상태 - 소유 엔티티 인스턴스에서 캐스케이드="all-delete-module" 컬렉션을 더 이상 참조하지 않습니다.
엔티티를 갱신하려고 하면 다음과 같은 문제가 발생합니다.
"A collection with cascade=”all-delete-orphan” was no longer referenced by the owning entity instance".
, 그 는 '어느 엔티티'를 .Set<...>
일부 하위 엔티티의 경우.업데이트를 시도하면 이 컬렉션에 대한 모든 참조를 가져와 설정합니다.
다음 코드는 매핑을 나타냅니다.
@OneToMany(mappedBy = "parentEntity", fetch = FetchType.EAGER)
@Cascade({ CascadeType.ALL, CascadeType.DELETE_ORPHAN })
public Set<ChildEntity> getChildren() {
return this.children;
}
세트장을 청소하려고 노력했어요.>만, 이하에 준거합니다.문제를 "가능"하게 해결하는 방법은 효과가 없었습니다.
뭔가 좋은 생각이 있으면 알려주세요.
감사합니다!
sonEntities에 할당하는 모든 위치를 체크합니다.참조한 링크는 새로운 HashSet 작성을 명확하게 나타내지만 세트를 재할당할 때마다 이 오류가 발생할 수 있습니다.예를 들어 다음과 같습니다.
public void setChildren(Set<SonEntity> aSet)
{
this.sonEntities = aSet; //This will override the set that Hibernate is tracking.
}
일반적으로 생성자에서 세트를 한 번만 "새롭게" 하려고 합니다.목록에 항목을 추가하거나 삭제할 때마다 새 목록을 할당하는 대신 목록의 내용을 수정해야 합니다.
하위 추가 방법:
public void addChild(SonEntity aSon)
{
this.sonEntities.add(aSon);
}
하위 항목 제거 방법:
public void removeChild(SonEntity aSon)
{
this.sonEntities.remove(aSon);
}
방법:
public void setChildren(Set<SonEntity> aSet) {
this.sonEntities = aSet;
}
하는 것은, 「」의 입니다.parentEntity
하다
그러나 엔티티가 컨텍스트별로 분리되지 않은 경우(즉, 검색 및 업데이트 작업이 동일한 트랜잭션에 있는 경우) 다음 방법이 작동합니다.
public void setChildren(Set<SonEntity> aSet) {
//this.sonEntities = aSet; //This will override the set that Hibernate is tracking.
this.sonEntities.clear();
if (aSet != null) {
this.sonEntities.addAll(aSet);
}
}
여러 곳에서 동면 중인 사용자가 컬렉션에 할당하는 것을 원치 않는 글을 읽었을 때, 가장 안전한 방법은 다음과 같이 최종화하는 것이라고 생각했습니다.
class User {
private final Set<Role> roles = new HashSet<>();
public void setRoles(Set<Role> roles) {
this.roles.retainAll(roles);
this.roles.addAll(roles);
}
}
그러나, 이것은 동작하지 않고, 「더 이상 참조되지 않는다」라고 하는 무시무시한 에러가 표시됩니다.이 경우, 실제로는 꽤 오해의 소지가 있습니다.
휴지 상태가 setRoles 메서드를 호출하고 여기에 특별한 컬렉션 클래스를 설치하려고 하지만 컬렉션 클래스를 받아들이지 않습니다.당신의 세트 방식에서 당신의 컬렉션에 할당하지 않는 것에 대한 모든 경고를 읽었음에도 불구하고, 나는 오랫동안 고민했습니다.
그래서 이렇게 바꿨어요.
public class User {
private Set<Role> roles = null;
public void setRoles(Set<Role> roles) {
if (this.roles == null) {
this.roles = roles;
} else {
this.roles.retainAll(roles);
this.roles.addAll(roles);
}
}
}
따라서 첫 번째 콜에서는 휴지 상태가 되어 특수 클래스가 설치되고 이후 콜에서는 모든 것을 파괴하지 않고 직접 메서드를 사용할 수 있습니다.만약 당신이 당신의 수업을 콩으로 사용하고 싶다면, 당신은 아마 일하는 세터가 필요할 것이고, 적어도 이것은 효과가 있을 것 같다.
사실 내 문제는 내 엔티티의 동등과 해시코드에 관한 것이었다.레거시 코드는 많은 문제를 일으킬 수 있으므로 확인하는 것을 잊지 마십시오.내가 한 일은 그냥 delete-orphan strategy를 유지하고 등호화 및 해시코드를 수정한 것뿐이다.
다음과 같이 수정했습니다.
1. 기존 자녀 목록을 클리어하여 데이터베이스에서 삭제합니다.
parent.getChildren().clear();
2. 위에서 작성한 새 자녀 목록을 기존 목록에 추가합니다.
parent.getChildren().addAll(children);
이 게시물이 오류 해결에 도움이 되기를 바랍니다.
저도 같은 실수를 했어요.문제는 엔티티를 저장한 후에도 매핑된 컬렉션은 여전히 null이며 엔티티를 업데이트하려고 할 때 예외가 발생했다는 것입니다.도움이 된 점: 엔티티를 저장하고 새로 고친 후 업데이트를 수행합니다(수집은 null이 아닙니다).새로운 ArrayList() 또는 다른 것으로 컬렉션을 초기화하는 것도 도움이 될 수 있습니다.
JSON 투고 요청으로 엔티티를 업데이트 할 때 우연히 마주쳤습니다.자녀에 대한 데이터가 없는 경우에도 엔티티를 업데이트 할 때 오류가 발생했습니다.추가 중
"children": [],
문제를 해결하도록 요청했습니다.
@user2709454 어프로치를 사용하여 조금 개선했습니다.
public class User {
private Set<Role> roles;
public void setRoles(Set<Role> roles) {
if (this.roles == null) {
this.roles = roles;
} else if(this.roles != roles) { // not the same instance, in other case we can get ConcurrentModificationException from hibernate AbstractPersistentCollection
this.roles.clear();
if(roles != null){
this.roles.addAll(roles);
}
}
}
}
원인일 수 있습니다.hibernate-enhance-maven-plugin
를 유효하게 했을 때enableLazyInitialization
이 예외는 저의 게으른 컬렉션에서 발생하기 시작했습니다.5.2.17
다음 두 가지 휴지 상태 문제에 주의하십시오.
HAS 관계 유형:
「인스턴스화」로 그 .hasMany
오브젝트를 추가 및 삭제하기만 하면 됩니다.
class Parent {
static hasMany = [childs:Child]
}
관계 유형 사용:
그러나 컬렉션은 가 속성(사용 관계)으로 선언되고 선언에서 초기화되지 않은 경우에만 null일 수 있습니다.
class Parent {
List<Child> childs = []
}
이 에러가 발생하는 것은 NULL을 수집용 세터에 전달하려고 했을 때 뿐입니다.이를 방지하기 위해 세터는 다음과 같습니다.
public void setSubmittedForms(Set<SubmittedFormEntity> submittedForms) {
if(submittedForms == null) {
this.submittedForms.clear();
}
else {
this.submittedForms = submittedForms;
}
}
그 모든 대답들이 내게 도움이 되지 않았지만, 나는 다른 해결책을 찾았다.
엔티티 B의 리스트를 포함한 엔티티 A를 가지고 있었습니다.기업 B는 기업 C의 목록을 포함하였다.
엔티티 A와 B를 업데이트하려고 했습니다.됐다.그러나 엔티티 C를 업데이트 할 때 언급된 오류가 발생했습니다.엔티티 B에서는 다음과 같은 주석을 달았다.
@OneToMany(mappedBy = "entity_b", cascade = [CascadeType.ALL] , orphanRemoval = true)
var c: List<EntityC>?,
뺐어요.orphanRemoval
이치노
사용하려고 할 때 이 문제가 발생했습니다.TreeSet
oneToMany
TreeSet
쪽이 효과가 있다
@OneToMany(mappedBy = "question", fetch = FetchType.EAGER, cascade = { CascadeType.ALL }, orphanRemoval=true)
@OrderBy("id")
private Set<WizardAnswer> answers = new TreeSet<WizardAnswer>();
'아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아question
위. 위. 위. 위. 위. 위. 위. 위. 위. 위. 위. 위. 위. 위.hibernate
SortedSet
의 행을 '일부러'로 됩니다.
@OneToMany(mappedBy = "question", fetch = FetchType.EAGER, cascade = { CascadeType.ALL }, orphanRemoval=true)
@OrderBy("id")
private SortedSet<WizardAnswer> answers;
더 정보를 합니다.hibernate SortedSet
여기 있을 수 있다
이 버그에는 의심스러운 점이 있습니다.https://hibernate.atlassian.net/browse/HHH-9940 입니다.
그리고 그것을 재현하기 위한 코드: https://github.com/abenneke/sandbox/tree/master/hibernate-null-collection/src/test
여기에는 다음 2가지 수정이 있습니다.
컬렉션이 빈 컬렉션으로 초기화됩니다(null 제외).
orphan Removal이 false로 설정되었습니다.
예:
@OneToMany(cascade = CascadeType.REMOVE,
mappedBy = "jobEntity", orphanRemoval = true)
private List<JobExecutionEntity> jobExecutionEntities;
다음과 같이 되었습니다.
@OneToMany(cascade = CascadeType.REMOVE,
mappedBy = "jobEntity")
private List<JobExecutionEntity> jobExecutionEntities;
저도 같은 문제가 있었는데 세트가 무효일 때였어요.「목록」을 설정합니다..@LazyCollection(LazyCollectionOption.FALSE)
JPA 주석을 사용합니다.fetch = FetchType.EAGER.
솔루션:이것은 나의 구성이며 정상적으로 동작한다.
@OneToMany(mappedBy = "format", cascade = CascadeType.ALL, orphanRemoval = true)
@LazyCollection(LazyCollectionOption.FALSE)
private Set<Barcode> barcodes;
@OneToMany(mappedBy = "format", cascade = CascadeType.ALL, orphanRemoval = true)
@LazyCollection(LazyCollectionOption.FALSE)
private List<FormatAdditional> additionals;
다른 한 가지 원인은 롬복 사용일 수 있다.
@Builder
save - 저장 이유Collections.emptyList()
라고 해도.myCollection(new ArrayList());
@Singular
- 를 남깁니다.null
가 ""로 myCollection = new ArrayList()
내 2센트, 그냥 같은 걸로 2시간 보냈어:)
는 ★★★★★★★★★★★★★★를 받고 있었다.A collection with cascade=”all-delete-orphan” was no longer referenced by the owning entity instance
★★★★★★★를 설정했을 때parent.setChildren(new ArrayList<>())
parent.getChildren().clear()
를 해결했습니다
자세한 내용은 다음을 참조하십시오.휴지 상태예외 - 소유 엔티티 인스턴스에서 캐스케이드="all-delete-module" 컬렉션을 더 이상 참조하지 않았습니다.
Spring Boot을 사용하고 있으며 데이터를 보다 프런트 엔드 친화적으로 표현하기 위해 커스텀시리얼라이저와 디시리얼라이저를 사용하여 동일한 컬렉션에 추가 필드를 선언하기 때문에 직접 덮어쓰지는 않지만 컬렉션에서 이 문제가 발생했습니다.
public List<Attribute> getAttributes() {
return attributes;
}
public void setAttributes(List<Attribute> attributes) {
this.attributes = attributes;
}
@JsonSerialize(using = AttributeSerializer.class)
public List<Attribute> getAttributesList() {
return attributes;
}
@JsonDeserialize(using = AttributeDeserializer.class)
public void setAttributesList(List<Attribute> attributes) {
this.attributes = attributes;
}
내가 직접 컬렉션을 덮어쓰지는 않지만, 탈직렬화가 비밀리에 이루어지기 때문에, 이 모든 것이 같은 문제의 발단이 되는 것 같습니다.해결책은 디시리얼라이저와 관련된 세터를 변경하여 목록을 덮어쓰지 않고 모든 것을 추가하는 것이었습니다.
@JsonDeserialize(using = AttributeDeserializer.class)
public void setAttributesList(List<Attribute> attributes) {
this.attributes.clear();
this.attributes.addAll(attributes);
}
나는 스프링 부츠랑 완전 달라!나에게 그것은 컬렉션 속성 설정 때문이 아니었다.
테스트에서 엔티티를 생성하려고 했는데 사용되지 않은 다른 컬렉션에 대해 이 오류가 발생했습니다.
'어느새'를 붙였습니다.@Transactional
시험방법에 따라 해결했습니다.하지만 이유를 알지는 마세요.
@OneToMany(mappedBy = 'parent', cascade= CascadeType.ALL, orphanRemoval = true)
List<Child> children = new ArrayList<>();
기존 하위 개체 목록에 하위 개체를 추가할 때 동일한 오류가 발생했습니다.
childService.saveOrUpdate(child);
parent.addToChildren(child);
parentService.saveOrUpdate(parent);
문제를 해결한 것은 다음과 같습니다.
child = childService.saveOrUpdate(child);
이제 아이는 다른 디테일과 함께 되살아났고 잘 작동했다.
[Intelij Idea]버전 2020.3에서 일괄 테스트를 실행할 때 스프링 부트 2.4.1에서 이 문제가 발생하였습니다.IntelliJ에서 한 번에 하나의 테스트만 실행하거나 명령줄에서 테스트를 실행하는 경우에는 이 문제가 발생하지 않습니다.
Intelij 캐싱 문제?
후속 조치:
이 문제는 maven-surefire-plugin reuseForks true를 사용하여 테스트를 실행할 때 나타납니다.reuseForks false를 사용하면 빠른 수정이 가능하지만 테스트 실행 시간이 크게 증가합니다.포크를 재사용하고 있기 때문에 데이터베이스 컨텍스트를 청소하지 않고 실행되는 다른 테스트로 인해 데이터베이스 컨텍스트가 더러워질 수 있습니다.확실한 해결책은 테스트를 실행하기 전에 데이터베이스 콘텍스트를 청소하는 것이지만, 각 테스트 후에 데이터베이스 콘텍스트를 청소하는 것(원래 문제의 근본 원인 해결)이 최선입니다.테스트 방법에서 @Transactional 주석을 사용하면 테스트 방법 종료 시 데이터베이스 변경이 롤백됩니다.트랜잭션에 대한 Spring 문서를 참조하십시오.https://docs.spring.io/spring-framework/docs/current/reference/html/testing.html#testcontext-tx
모기업에서 다음 주석을 사용하던 것과 유사한 문제에 직면해 있습니다.
@Cascade({ CascadeType.ALL, CascadeType.DELETE_ORPHAN })
실수로 늘 부모 개체를 데이터베이스에 저장하려고 했는데 엔티티 개체에 값을 올바르게 설정하면 오류가 해결되었습니다.따라서 잘못된 값을 설정하거나 null 개체를 데이터베이스에 저장하려고 하는 바보인지 확인하십시오.
바보 같은 대답도 덧붙이고Spring Data Rest를 사용하고 있습니다.이게 우리의 꽤 표준적인 관계였어.그 패턴은 다른 곳에서 사용되었습니다.
//Parent class
@OneToMany(mappedBy = 'parent',
cascade= CascadeType.ALL, orphanRemoval = true)
@LazyCollection(LazyCollectionOption.FALSE)
List<Child> children = new LinkedList<>()
//Child class
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = 'ParentID', updatable = false)
@JsonBackReference
Parent parent
우리가 만든 인연은 항상 아이들이 자신의 레포에 의해 추가되는 것을 의도하고 있었다.나는 아직 보고서를 추가하지 않았다.우리가 실시한 통합 테스트는 요청 간에 트랜잭션이 종료되도록 REST 호출을 통해 엔티티의 전체 라이프사이클을 거치고 있었습니다.가 없다는 것은 가 주 했다._embedded
부모에게 업데이트를 하면 문제가 발생합니다.
다음과 같은 솔루션이 나에게 효과가 있었다
//Parent class
@OneToMany(mappedBy = 'parent',
cascade= CascadeType.ALL, orphanRemoval = true)
@OrderBy(value="ordinal ASC")
List<Child> children = new ArrayList<>()
//Updated setter of children
public void setChildren(List<Children> children) {
this.children.addAll(children);
for (Children child: children)
child.setParent(this);
}
//Child class
@ManyToOne
@JoinColumn(name="Parent_ID")
private Parent parent;
새 컬렉션을 할당하는 대신
public void setChildren(Set<ChildEntity> children) {
this.children = children;
}
모든 요소 교체 대상
public void setChildren(Set<ChildEntity> children) {
Collections.replaceAll(this.children,children);
}
조심하다
BeanUtils.copyProperties(newInsum, insumOld,"code");
이 방법으로도 휴지 상태가 해제됩니다.
이전 답변과 달리 세터 함수가 다음과 같이 생겼을 때 "cascade="all-delete-module"을 사용한 컬렉션이 더 이상 참조되지 않았습니다."라는 오류가 발생했습니다.
public void setTaxCalculationRules(Set<TaxCalculationRule> taxCalculationRules_) {
if( this.taxCalculationRules == null ) {
this.taxCalculationRules = taxCalculationRules_;
} else {
this.taxCalculationRules.retainAll(taxCalculationRules_);
this.taxCalculationRules.addAll(taxCalculationRules_);
}
}
그리고 심플 버전으로 바꾸자 사라졌습니다.
public void setTaxCalculationRules(Set<TaxCalculationRule> taxCalculationRules_) {
this.taxCalculationRules = taxCalculationRules_;
}
(hibernate 버전 - 5.4.10과 4.3.11을 모두 사용해 보았습니다.세터의 간단한 할당으로 돌아가기 전에, 모든 종류의 솔루션을 시험해 보았습니다.왜 그러는지 지금 혼란스럽다.)
내 경우 여러 스레드에서 하나의 휴지 상태 세션에 동시에 액세스했습니다.Spring Boot Batch 및 RepositoryItemReader 구현에서는 사이즈가 10인 페이지 요청별로 엔티티를 가져옵니다.
예를 들어 다음과 같은 엔티티가 있습니다.
@Entity
class JobEntity {
@ManyToOne(fetch = FetchType.LAZY)
private GroupEntity group;
}
@Entity
class GroupEntity {
@OneToMany(mappedBy = "group", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
private Set<Config> configs;
}
배치 프로세스:reader -> processor -> writer
한 번의 거래로.
이 엔티티 설정에서 GroupEntity는 다른 스레드로 이스케이프할 수 있습니다.
읽기 섹션에 입력한 첫 번째 스레드는 크기가 10(RepositoryItemReader#doRead)인 JobEntity 페이지를 가져옵니다.이 항목에는 공유 GroupEntity 오브젝트가1개 포함되어 있습니다(모두 같은 그룹 ID를 가리키고 있기 때문입니다).그리고 첫 번째 엔티티를 가져갑니다.다음 읽기 섹션은 이 페이지가 모두 사용될 때까지 이 페이지에서 JobEntity를 하나씩 가져옵니다.
따라서 스레드는 JobEntity 인스턴스와 동일한 GroupEntity 인스턴스에 액세스할 수 있습니다.이는 하나의 휴지 상태 세션에 대한 안전하지 않은 멀티 스레드 액세스입니다.
2021 및 Spring Boot 2.5에서는 필드를 즉시 초기화할 수 있었습니다.
@OneToMany(mappedBy="target",fetch= FetchType.EAGER,cascade = CascadeType.ALL, orphanRemoval = true)
private List<TargetEntity> targets = new ArrayList<>();
아이를 최종적으로 만들면 문제가 해결된다.
우리는 세터뿐만 아니라 컨스트럭터에서 아이에 대한 참조를 변경해서는 안 된다.
언급URL : https://stackoverflow.com/questions/5587482/hibernate-a-collection-with-cascade-all-delete-orphan-was-no-longer-referenc
'programing' 카테고리의 다른 글
LokiSFSAdapter는 Linux에서는 동작하지만 Windows에서는 동작하지 않는 이유는 무엇입니까? (0) | 2022.07.16 |
---|---|
Vue prop 유형 유효성 검사 개체 스키마 (0) | 2022.07.16 |
커스텀 dev/prod 서버에서 vue cli 서비스 기능을 활용하는 방법 (0) | 2022.07.16 |
getter가 업데이트되지 않는 것을 수신하는 Vuex 계산 속성 (0) | 2022.07.16 |
C에서 가변 함수의 호출을 전송합니다. (0) | 2022.07.16 |