Vrapor e JPA e Hibernate, erro ao salvar FK como null [RESOLVIDO]

6 respostas
vasilvei

Bom dia tenho duas tabelas em meu sistema que são:

Cliente e Convenio = um convenio pode estar em muito clientes.

só que as vezes tem cliente que não tem nenhum convenio, estão deve ser null, e salvar ele esta dando um erro:
diz que é preciso salvar a transação do objeto convenio antes do cliente, mas eu não quero isso pois esta vindo nulo.

org.hibernate.TransientObjectException: object is an unsaved transient instance - save the transient instance before merging: br.com.coliseu.model.Convenio

Minhas classes:

Cliente:

@Entity
@Table(name = "cliente", schema = "coliseusys")
@SequenceGenerator(name = "coliseusys.gen_idcliente", sequenceName = "coliseusys.gen_idcliente")
public class Cliente implements java.io.Serializable {

.....	

	private Convenio convenio;
	
.....

	public Cliente() {
	}

	
	public Cliente(...
			Convenio convenio, ....) {
	...
		this.convenio = convenio;
	....
	}

	.....

	@ManyToOne
	@JoinColumn(name = "idconvenio", nullable=true)
	public Convenio getConvenio() {
		return this.convenio;
	}

	public void setConvenio(Convenio convenio) {
		this.convenio = convenio;
	}

      ....

Classe Convenio:

@Entity
@Table(name = "convenio", schema = "coliseusys")
@SequenceGenerator(name = "coliseusys.gen_idconvenio", sequenceName = "coliseusys.gen_idconvenio")
public class Convenio implements java.io.Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Long idconvenio;
 ....
	private Set<Cliente> clientes = new HashSet<Cliente>(0);

	public Convenio() {
	}

	public Convenio(Long idconvenio, String descricao) {
		this.idconvenio = idconvenio;
		this.descricao = descricao;
	}

	public Convenio(Long idconvenio, Filial filial, String descricao,
			Set<Cliente> clientes) {
		this.idconvenio = idconvenio;
		this.filial = filial;
		this.descricao = descricao;
		this.clientes = clientes;
	}

	@OneToMany(mappedBy = "convenio")
	public Set<Cliente> getClientes() {
		return this.clientes;
	}

	public void setClientes(Set<Cliente> clientes) {
		this.clientes = clientes;
	}

minha JSP, eu uso um combobox, para visualizar os meus convenios, aqui se eu tirar o name=“cliente.convenio.idconvenio”, ele não mando no caso o objeto convenio
daí salva normalmente, eu pensei em fazer um tratamento em javascript quando eu não selecionar nada tirar o name, mas achei isso meio que gambiara:

<select name="cliente.convenio.idconvenio"
                                            onkeypress="return desabilitaEnter(this, event);"
                                            class="limpar inputForm" id="idconvenio" required>
                                        <option >Selecione</option>
                                        <c:forEach var="lista" items="${cmbConvenio}">
                                            <c:if
                                                test="${lista.idconvenio == cliente.convenio.idconvenio}">
                                                <option value="${lista.idconvenio}" selected="selected">${lista.descricao}</option>
                                            </c:if>
                                            <c:if
                                                test="${lista.idconvenio != cliente.convenio.idconvenio}">
                                                <option value="${lista.idconvenio}">${lista.descricao}</option>
                                            </c:if>
                                        </c:forEach>
                                    </select>

Alguém já passou por isso, qual a melhor solução para isso, no banco de dados ele salva como null, ou seja ele não é NOTNULL.

Obrigado!

6 Respostas

Tiburcio_Mancha

coloca essa propriedade no mapeamento la na sua coleção de clientes na entidade convenio.

vasilvei

Olá, mas o que você quis dizer com?

cascade = CascadeType.ALL

pois até onde eu sei se colocar esse propriedade, ele faz tudo em cascata, ou seja quando eu deletar um convenio ele vai tentar deletar o cliente relacionado…

Lucas_Cavalcanti

cuidado… se vc não selecionar nada nesse select, vai vir um cliente, com um convênio sem id preenchido, por isso o erro.

ou seja tem um objeto lá vazio e o hibernate tenta salvar.

pra corrigir isso vc pode no controller remover o relacionamento se o id do convenio for null

vasilvei

Olá Lucas.

eu fiz isso :

if(cliente.getConvenio().getIdconvenio()==null){				
				cliente.setConvenio(null);				
			}

ele salva de boa, só que eu estou usando o para redirecionar o seguinte:

result.redirectTo(this).lista();

e daí ele fala para eu usar o validator do vraptor mas eu não quero usar.

br.com.caelum.vraptor.InterceptionException: There are validation errors and you forgot to specify where to go. Please add in your method something like:
validator.onErrorUse(page()).of(AnyController.class).anyMethod();
or any view that you like.
If you didn't add any validation error, it is possible that a conversion error had happened.

e se eu colocar ele diz que o Convenio não é um valor inteiro valido, haja visto que é null.

como eu faço para ignorar esse validator?

Lucas_Cavalcanti

qdo vc coloca isso:

<option >Selecione</option>

e seleciona essa opção, o select vai com o valor “Selecione”, por isso o erro de conversão…

vc precisa colocar Selecione

vasilvei

Era isso mesmo, value Lucas.

Criado 2 de abril de 2012
Ultima resposta 2 de abr. de 2012
Respostas 6
Participantes 3