Estou com o seguinte problema ao tentar atualizar minha entidade:
"A collection with cascade=”all-delete-orphan” was no longer referenced by the owning entity instance".
Eu tenho uma entidade pai e ela tem uma Set<...>
de algumas entidades filhas. Quando tento atualizá-lo, recebo todas as referências a serem configuradas para essas coleções e defini-lo.
O código a seguir representa meu mapeamento:
@OneToMany(mappedBy = "parentEntity", fetch = FetchType.EAGER)
@Cascade({ CascadeType.ALL, CascadeType.DELETE_ORPHAN })
public Set<ChildEntity> getChildren() {
return this.children;
}
Tentei limpar apenas o Set <..>, de acordo com o seguinte: Como "possível" resolver o problema, mas não funcionou.
Se você tiver alguma idéia, entre em contato.
Obrigado!
java
hibernate
hibernate-mapping
axcdnt
fonte
fonte
something.manyother.remove(other)
ifmanyother
é aList<T>
. Faça manyother mutável, comoArrayList<T>
e usoorphanDelete = true
Respostas:
Verifique todos os lugares onde você está atribuindo algo para sonEntities. O link que você referiu distintamente indica a criação de um novo HashSet, mas você pode ter esse erro sempre que redesignar o conjunto. Por exemplo:
Geralmente você deseja "novo" apenas o conjunto uma vez em um construtor. Sempre que você deseja adicionar ou excluir algo da lista, você deve modificar o conteúdo da lista em vez de atribuir uma nova lista.
Para adicionar filhos:
Para remover crianças:
fonte
O método:
funciona se o
parentEntity
estiver desanexado e novamente se o atualizarmos.Porém, se a entidade não for desanexada por contexto, (ou seja, as operações de localização e atualização estão na mesma transação), o método abaixo funcionará.
fonte
Quando li em vários lugares que o hibernate não gostaria que você atribuísse a uma coleção, presumi que a coisa mais segura a fazer seria obviamente torná-la final assim:
No entanto, isso não funciona, e você recebe o temido erro "não mais referenciado", o que é realmente bastante enganador neste caso.
Acontece que o hibernate chama seu método setRoles E deseja que sua classe de coleção especial seja instalada aqui e não aceita sua classe de coleção. Isso me deixou perplexo por muito tempo, apesar de ler todos os avisos sobre não atribuir à sua coleção no seu método definido.
Então eu mudei para isso:
Para que, na primeira chamada, o hibernate instale sua classe especial e, nas chamadas subsequentes, você possa usar o método sem destruir tudo. Se você quiser usar sua classe como um bean, provavelmente precisará de um levantador de trabalho, e isso pelo menos parece funcionar.
fonte
List<String> list = new ArrayList<>();
. Mudá-lo paraList<String> list = null;
corrigir o problema :)Na verdade, meu problema era sobre iguais e hashcode das minhas entidades. Um código legado pode trazer muitos problemas, nunca se esqueça de conferir. Tudo o que fiz foi apenas manter a estratégia de excluir órfãos e corrigir os iguais e o código de hash.
fonte
Eu tive o mesmo erro. O problema para mim foi que, depois de salvar a entidade, a coleção mapeada ainda era nula e, ao tentar atualizar a entidade, a exceção foi lançada. O que me ajudou: Salvar a entidade, fazer uma atualização (a coleção não é mais nula) e executar a atualização. Talvez inicializar a coleção com o novo ArrayList () ou algo possa ajudar também.
fonte
TEM TIPO DE RELAÇÃO:
Não tente instanciar a coleção quando ela estiver declarada
hasMany
, basta adicionar e remover objetos.TIPO DE RELAÇÃO DE USO:
Mas a coleção pode ser nula somente quando é declarada como uma propriedade (relação de uso) e não é inicializada na declaração.
fonte
Eu usei a abordagem @ user2709454 com pequenas melhorias.
fonte
Eu tive esse problema ao tentar usar
TreeSet
. Eu inicializeioneToMany
com oTreeSet
que funcionaMas, isso trará o erro descrito
question
acima. Parece que éhibernate
suportadoSortedSet
e se alguém mudar a linha acima parafunciona como mágica :) mais informações
hibernate SortedSet
podem estar aquifonte
A única vez que recebo esse erro é quando tento passar NULL para o setter da coleção. Para evitar isso, meus setters ficam assim:
fonte
Eu me deparei com isso ao atualizar uma entidade com uma solicitação de postagem JSON. O erro ocorreu quando atualizei a entidade sem dados sobre os filhos, mesmo quando não havia nenhum. Adicionando
ao organismo da solicitação resolveu o problema.
fonte
Uma outra causa pode estar usando o lombok.
@Builder
- causas para salvar,Collections.emptyList()
mesmo se você disser.myCollection(new ArrayList());
@Singular
- ignora os padrões no nível da classe e deixa o camponull
mesmo que o campo da classe tenha sido declarado comomyCollection = new ArrayList()
Meus 2 centavos, apenas passei 2 horas com o mesmo :)
fonte
Eu estava pegando
A collection with cascade=”all-delete-orphan” was no longer referenced by the owning entity instance
quando estava sentadoparent.setChildren(new ArrayList<>())
. Quando mudei paraparent.getChildren().clear()
, ele resolveu o problema.Verifique para obter mais detalhes: HibernateException - Uma coleção com cascade = "all-delete-orphan" não era mais referenciada pela instância da entidade proprietária .
fonte
Estou usando o Spring Boot e tive esse problema com uma coleção, apesar de não a sobrescrever diretamente, porque estou declarando um campo extra para a mesma coleção com um serializador e desserializador personalizado , a fim de fornecer uma representação mais amigável ao front-end do dados:
Parece que mesmo que eu não estou substituindo a coleção mim mesmo , a desserialização faz isso sob o capô, provocando esta questão tudo a mesma coisa. A solução foi alterar o setter associado ao desserializador para limpar a lista e adicionar tudo, em vez de substituí-lo:
fonte
Eu tive o mesmo problema, mas foi quando o conjunto foi nulo. Somente na coleção Definir na lista de trabalho encontra. Você pode tentar a anotação de hibernação @LazyCollection (LazyCollectionOption.FALSE) instalada na anotação de JPA fetch = FetchType.EAGER.
Minha solução: esta é minha configuração e funciona bem
fonte
Ocorreu o mesmo erro ao adicionar o objeto filho à lista existente de objetos filho.
O que resolveu meu problema está mudando para:
Agora a criança também revive com outros detalhes e funcionou bem.
fonte
Adicionando minha resposta idiota. Estamos usando o Spring Data Rest. Esse era o nosso relacionamento bastante padrão. O padrão foi usado em outro lugar.
Com o relacionamento que criamos, sempre se pretendeu que as crianças fossem adicionadas através de seu próprio repositório. Eu ainda não tinha adicionado o repositório. O teste de integração que tínhamos estava passando por um ciclo de vida completo da entidade por meio de chamadas REST, para que as transações fossem fechadas entre solicitações. Nenhum repo para a criança significava que o json tinha os filhos como parte da estrutura principal em vez de dentro
_embedded
. Atualizações para o pai causariam problemas.fonte
A seguinte solução funcionou para mim
fonte
Em vez de atribuir nova coleção
Substitua todos os elementos por
fonte
tenha cuidado com
Este método também interrompe a hibernação.
fonte
Pode ser causado por
hibernate-enhance-maven-plugin
. Quando eu ativeienableLazyInitialization
propriedade, essa exceção começou a acontecer na minha coleção lenta. Estou usando o hibernate 5.2.17.Final.Observe estes dois problemas de hibernação:
fonte
O meu era completamente diferente com o Spring Boot! Para mim, não foi devido à configuração da propriedade de coleção.
Nos meus testes, eu estava tentando criar uma entidade e estava recebendo esse erro para outra coleção que não era usada!
Depois de tanto tentar, acabei de adicionar um
@Transactional
no método de teste e ele o resolveu. Não, não a razão embora.fonte
Isso contrasta com as respostas anteriores, eu tive exatamente o mesmo erro: "Uma coleção com cascade =” all-delete-órphan ”não era mais referenciada ...." quando minha função setter ficou assim:
E então desapareceu quando eu mudei para a versão simples:
(versões de hibernação - tentei 5.4.10 e 4.3.11. Passei vários dias tentando todos os tipos de soluções antes de retornar à tarefa simples no setter. Confuso agora sobre o motivo disso.)
fonte