[RESOLVIDO]Update oneToMany

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

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

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; 

[quote=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 ?

[code]

@OneToMany(fetch = FetchType.EAGER, mappedBy = “prova”,cascade=CascadeType.ALL)
@PrivateOwned
private List 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;
[/code][/quote]

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?

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

[quote=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[/quote]

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