Remover uma lista sem cascade="all-delete-orphan" was no longer referenced by [resolvido]

Eu tenho um objeto pessoa que possui algumas listas. Qdo preciso atualizar nao tenho como saber se é uma operacao de update ou delete, entao eu optei
por deletar as listas e inserir de novo. E tive os problemas abaixo além da exeção: A collection with cascade=“all-delete-orphan” was no longer referenced by the owning entity instance:

1 - primeiro tentei inserir os emails(codigo do salvaremail()) apos usar o emails().clear. Ao inserir dava erro dizendo que já existia, devido a constraint
2 - ainda usando emails().clear, fiz um metodo separado para adicionar os emails, esperando finalizar a transacao do metodo atualizarpessoa() e depois chamando salvaremail() pudesse resolver
3 - removi o emails.clear() e fiz um delete na mao, dae funcionou, usando atualizarpessoa() e salvaremail()

A melhor maneira de eu remover uma lista e adicionar novamente seria como fiz ? a princípio nao posso mexer no mapeamento…

fluxo dos metodos:
atualizarpessoa();
salvaremail()

[code]
class PessoaService { //ejb

public atualizarpessoa(){
//1
pessoa.getEmails().clear();
//3
entityManager.createQuery(“DELETE Email p WHERE p.pessoa.idPessoa = :idPessoa”).setParameter(“idPessoa”, pessoa.getIdPessoa()).executeUpdate();

}

//2
public salvaremail(){

	try {
		List<Email> emails = pessoa.getEmails();
		for (Email pe : pessoar.getEmails()) {
			if (pe.getEmail().isEmpty())
				continue;
			pe.setPessoa(pessoa);
			emails.add(pe);
		}
		pessoa.setEmails(emails);
	} catch (Exception e) {
		e.printStackTrace();
	}
	return pessoa;

}

}

//estou usando yy xx pra simplificar…
class Pessoa extends YY{

@OneToMany(mappedBy = "pessoa")
@Cascade({
    CascadeType.ALL,
    CascadeType.DELETE_ORPHAN
})
private List<Email> emails = newList();

}

class YY extends XX {}
class XX {

public static <T> List<T> newList() {
    return new ArrayList<T>();
}

}[/code]

Seu passo dois se não te mantou vai te matar.

Ao executar entityManager.createQuery(“DELETE Email p WHERE p.pessoa.idPessoa = :idPessoa”).setParameter(“idPessoa”, pessoa.getIdPessoa()).executeUpdate(); caso exista esse email dentro do seu PersistenceUnit, ele vai ficar furado.
O JPA/Hibernate não detecta se houve não alguma alteração em algum objeto attached quando você usa o executeUpdate().

Ou você mudar para entityManager.remove(); e passa o objeto aí ou então vc chama o flush antes de executar o executeUpdate();

resolv vi assim:

//classe pessoa
 @OneToMany(mappedBy = "pessoa")
    @Cascade({
        CascadeType.ALL,
        CascadeType.DELETE_ORPHAN
    })
	private List<Email> emails = newList();


//codigo no ejb
pessoa.getEmails().clear();
entityManager.flush();
salvaremail();

:slight_smile: