[RESOLVIDO]Update oneToMany

5 respostas
D

Olá a todos,

Tenho uma lista de questões em um prova , onde está lista pode ter questões já validadas pelo administrador como também questões novas pendentes de validação.

Caso o administrador ache que a prova não é válida, o sistema deleta a prova e apenas as questões que ñ foram validadas ainda.

O codigo abaixo simplifica isso.

Prova prova = daoProva.find(idProva);
		List<ProvaQuestao>listaQuestoesValidas = new ArrayList<ProvaQuestao>();
		for (ProvaQuestao provaQuestao : prova.getListaDeQuestoes()) {
			Boolean isFalso = provaQuestao.getQuestao().getFlAtiva();
			if(!Boolean.FALSE.equals(isFalso))
				listaQuestoesValidas.add(provaQuestao);
		}
		
		prova.getListaDeQuestoes().removeAll(listaQuestoesValidas);
		Prova provaAtualizada = daoProva.merge(prova);
		daoProva.delete(provaAtualizada);

O relacionamento está assim:

PROVA

@OneToMany(fetch = FetchType.EAGER, mappedBy = "prova",cascade=CascadeType.ALL)
	 private List<ProvaQuestao> listaDeQuestoes;
	@Column(name = "fl_ativa")
	private Boolean flAtiva;

PROVAQUESTAO

@ManyToOne(cascade = CascadeType.ALL,fetch=FetchType.LAZY)
	@JoinColumn(name = "id_prova", referencedColumnName = "id_prova",nullable = false)
	private Prova prova;

	@ManyToOne(cascade = CascadeType.ALL,fetch=FetchType.EAGER)
	@JoinColumn(name = "id_questao", referencedColumnName = "id_questao",nullable = false)
	private QuestoesAvulsas questao;

	private Integer num_questao;

O problema é que quando dou um merge ,ñ deveria remover os relacionamentos com as questões validas ?

Mas ele ñ faz isso , o JPA deleta todas as questões inválidas,mas na hora de remover a prova da erro de integridade referencial, pois na tabela ainda continua a referencia das questões validas com a prova.

Alguém sabe como posso fazer isso ?, remover a prova e questões inválidas em cascade sem deletar as questões válidas

5 Respostas

ralphsilver

Você tem que especificar que quer remover orfãos… qual a versão do seu JPA? se for a 2.0 basta setar orphanRemoval=true nas annotations @OneToMany

D

Entende

Acho que a minha ñ é 2.0, pois ñ tem essa opção para mim

Como estou usando eclipseLink vi que tinha uma anotação @PrivateOwned que equivale ao orphanRemoval

Neste caso teria colocar em todas OnetoMany ?

@OneToMany(fetch = FetchType.EAGER, mappedBy = "prova",cascade=CascadeType.ALL)  
@PrivateOwned
private List<ProvaQuestao> listaDeQuestoes;  
@Column(name = "fl_ativa")  
private Boolean flAtiva;  


@ManyToOne(cascade = CascadeType.ALL,fetch=FetchType.LAZY)  
@PrivateOwned
@JoinColumn(name = "id_prova", referencedColumnName = "id_prova",nullable = false)  
private Prova prova;  
  
@ManyToOne(cascade = CascadeType.ALL,fetch=FetchType.EAGER)  
@PrivateOwned
@JoinColumn(name = "id_questao", referencedColumnName = "id_questao",nullable = false)  
private QuestoesAvulsas questao;
ralphsilver
dfnfilipe:
Entende

Acho que a minha ñ é 2.0, pois ñ tem essa opção para mim

Como estou usando eclipseLink vi que tinha uma anotação @PrivateOwned que equivale ao orphanRemoval

Neste caso teria colocar em todas OnetoMany ?

@OneToMany(fetch = FetchType.EAGER, mappedBy = "prova",cascade=CascadeType.ALL)  
@PrivateOwned
private List<ProvaQuestao> listaDeQuestoes;  
@Column(name = "fl_ativa")  
private Boolean flAtiva;  


@ManyToOne(cascade = CascadeType.ALL,fetch=FetchType.LAZY)  
@PrivateOwned
@JoinColumn(name = "id_prova", referencedColumnName = "id_prova",nullable = false)  
private Prova prova;  
  
@ManyToOne(cascade = CascadeType.ALL,fetch=FetchType.EAGER)  
@PrivateOwned
@JoinColumn(name = "id_questao", referencedColumnName = "id_questao",nullable = false)  
private QuestoesAvulsas questao;

Então.. é o seguinte: você colocou cascade em todas as opções, o que não é muito legal... o certo é vc colocar cascade apenas onde vc quer propagar o UPDATE... esses que é @ManyToOne por exemplo não é necessário por um cascade...
outra coisa: o @PrivateOwned remove orfão, ou seja, essa annotation só é válida em relacionamento @OneToMany... provavelmente vai dar erro se vc deixar no @ManytoOne
Agora aonde vc deve por a annotation.. fica na sua necessidade.. qual ou quais relacionamentos que vc está propagando o UPDATE vc quer que remova os objetos qeu não se encontram na lista? entendeu?

D

Puts que cabaço que fui , jurava que estava vendo tudo OneToMany,

Mas então consegui resolver, coloquei @PrivateOwned no unico OneToMany que tinha no relacionamento, no caso uma prova tem muitas questões…

@OneToMany(fetch = FetchType.EAGER, mappedBy = "prova",cascade=CascadeType.ALL)    
@PrivateOwned  
private List<ProvaQuestao> listaDeQuestoes;    
@Column(name = "fl_ativa")    
private Boolean flAtiva;

E vlw sobre a dica do cascade .

Abraços

ralphsilver

dfnfilipe:
Puts que cabaço que fui , jurava que estava vendo tudo OneToMany,

Mas então consegui resolver, coloquei @PrivateOwned no unico OneToMany que tinha no relacionamento, no caso uma prova tem muitas questões…

@OneToMany(fetch = FetchType.EAGER, mappedBy = "prova",cascade=CascadeType.ALL)    
@PrivateOwned  
private List<ProvaQuestao> listaDeQuestoes;    
@Column(name = "fl_ativa")    
private Boolean flAtiva;

E vlw sobre a dica do cascade .

Abraços

Vlew… põe [RESOLVIDO] no título pro pessoal pesquisar e ver que o tópico já está resolvido…

Criado 3 de setembro de 2012
Ultima resposta 3 de set. de 2012
Respostas 5
Participantes 2