Org.hibernate.PropertyValueException: not-null property references a null or transient value

2 respostas
MandicaBrito

Oi gente,

Andei pesquisando Google a fora e pelos fóruns e não achei uma solução que me ajudasse. Tenho meu projeto web, usando Jsf 2.0, primefaces 3.2 e JPA 2.0
Estou querendo salvar um objeto Organização no banco, e uma organização possui um gestor, que é um objeto do tipo Usuário. Certo, quando tento salvar, ocorre a seguinte exceção: org.hibernate.PropertyValueException: not-null property references a null or transient value: modelo.Usuario.email
Creio que eles esteja tentando salvar um usuário antes de salvar a organização, só que eu já possuo os usuários cadastrados e só queria associar um deles à organização que está sendo salva, só que sem sucesso.

Organização:
@Entity
@Table(name="organizacao")
public class Organizacao {
	
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="id", nullable=false)
	private int id;
	
	@Column(name="cnpj", nullable=false)
	private String cnpj;
	
	@Column(name="nome_fantasia", nullable=false)
	private String nomeFantasia;
	
	@OneToOne(cascade=CascadeType.ALL)
	@JoinColumn
	private Usuario gestor;
	
	@OneToMany(fetch=FetchType.EAGER)
	private List<Usuario> usuarios;
Uusário:
@Entity
@Table(name="usuario")
public class Usuario {
	
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="id", nullable=false)
	private int id;
	
	@Column(name="matricula", nullable=false)
	private String matricula;
	
	@Column(name="gestor", nullable=false)
	private boolean gestor;
	
	@Column(name="nome", nullable=false)
	private String nome;
	
	@Column(name="funcao")
	private String funcao;
	
	@Column(name="setor")
	private String setor;
	
	@Column(name="cargo")
	private String cargo;
	
	@Column(name="email", nullable=false)
	private String email;
	
	@Column(name="senha", nullable=false)
	private String senha;
Minha classe Converter, para trabalhar com o selectOneMenu da tela:
@FacesConverter("StringConverter")
public class UsuarioConverter implements Converter {

	@Override
	public Object getAsObject(FacesContext facesContext,
			UIComponent uiComponent, String usuarioObj) {
		if (usuarioObj != null && !usuarioObj.equals("")) {

			String usuario = String.valueOf(usuarioObj);

			try {
				UsuarioDao dao = new UsuarioDao();
				return dao.listarUm(usuario);

			} catch (Exception e) {
				throw new ConverterException(
						"Nao foi possivel converter Usuário:" + usuarioObj
								+ "." + e.getMessage());
			}
		}

		return null;
	}

	@Override
	public String getAsString(FacesContext facesContext,
			UIComponent uiComponent, Object object) {

		if (object != null) {
			return object.toString();
		} else {
			return "";
		}

	}
E finalmente, minha OrganizacaoControle:
@ManagedBean
@SessionScoped
public class OrganizacaoControle {

	private Organizacao organizacao;
	private Usuario gestor;
	private OrganizacaoDao dao = new OrganizacaoDao();
	private List<Organizacao> organizacoes = new ArrayList<Organizacao>(dao.listar());
	
	public OrganizacaoControle(){
		this.organizacao = new Organizacao();
		this.gestor = new Usuario();
	}
	
	public void salvar() {
		OrganizacaoDao organizacaoDao = new OrganizacaoDao();
		organizacao.setGestor(gestor); // esse Gestor é o objeto Usuario retornado da classe Converter. Já vi que ele vem preenchido corretamente.
		organizacaoDao.inserir(organizacao);
		organizacao = new Organizacao();
		FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Organização: ", "Registro cadastrado com sucesso!"));

	}

	public List<Organizacao> listar() {
		OrganizacaoDao organizacaoDao = new OrganizacaoDao();
		organizacoes = new ArrayList<Organizacao>(organizacaoDao.listar());
		return organizacoes;

	}

	public void alterar() {
		OrganizacaoDao organizacaoDao = new OrganizacaoDao();
		organizacaoDao.alterar(organizacao);
		organizacao = new Organizacao();
		FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Organização: ", "Registro alterado com sucesso!"));
	}

	public void excluir() {
		OrganizacaoDao organizacaoDao = new OrganizacaoDao();
		organizacaoDao.excluir(organizacao);
		organizacao = new Organizacao();
		FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Organização: ", "Registro excluido com sucesso!"));
	}

Agradeço quem puder me ajudar ^^

2 Respostas

Hebert_Coelho

org.hibernate.PropertyValueException: not-null property references a null or transient value: modelo.Usuario.email

Veja c na hora que o usuário é trazido se o email não está null.

Quanto a ele estar transiente, aqui explica o problema: JPA: Mini Livro - Primeiros passos e conceitos detalhados.

MandicaBrito

Bem, desculpa a demora, mas tem sido corrido por aqui ^^
De qualquer forma, consegui resolver o problema, espero que ajude quem precisar.
Na verdade era questão da transação do EntityManager.
Toda ação que for feita tem que usar a mesma ‘sessão’, o que acontecia era que eu abria para recuperar meu Usuário e fechava depois, então quando eu tentava setar Usuário em Organização ele não reconhecia meu objeto, pois era aberta uma outra, só para Organização.
Usando um único : begin e commit para toda a ação funciona perfeitamente.

Obrigada pela ajuda :slight_smile:

Criado 2 de novembro de 2012
Ultima resposta 18 de nov. de 2012
Respostas 2
Participantes 2