Pessoal tou iniciando o aprendizado do Hibernate juntamente com JSF.
Tenho uma listagem bem básica de uma tabela "Pessoa" que contém um campo id_responsavel que é uma auto-referencia.
Nesta listagem ao chamar a ação de deletar no ManagedBean a seguinte excessão é lançada:
org.hibernate.TransientObjectException - object references an unsaved transient instance - save the transient instance before flushing:
Pessoa.java
@Entity
@Table(name="pessoa")
public class Pessoa implements Serializable {
private static final long serialVersionUID = 2174678509151116408L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="pessoa_id")
private Long id;
@Column(name="nome")
private String nome;
@Column(name="email")
private String email;
@Column(name="cpf")
private String cpf;
@Temporal(TemporalType.DATE)
@Column(name="data_nasc")
private Date dataNascimento;
@Column(name="telefone")
private String telefoneCelular;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "id_responsavel")
private Pessoa responsavel;
public void setId(Long id) {
this.id = id;
}
public Long getId() {
return id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
System.out.println("Pessoa >> nome : " + this.nome);
this.nome = nome;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getCpf() {
return cpf;
}
public void setCpf(String cpf) {
this.cpf = cpf;
}
public Date getDataNascimento() {
return dataNascimento;
}
public void setDataNascimento(Date dataNascimento) {
this.dataNascimento = dataNascimento;
}
public String getTelefoneCelular() {
return telefoneCelular;
}
public void setTelefoneCelular(String telefoneCelular) {
this.telefoneCelular = telefoneCelular;
}
public Pessoa getResponsavel(){
return this.responsavel;
}
public void setResponsavel(Pessoa responsavel){
this.responsavel = responsavel;
}
@Override
public int hashCode(){
return this.nome.length() * 23;
}
@Override
public String toString(){
return nome;
}
@Override
public boolean equals(Object obj){
if( (obj instanceof Pessoa) && ( ((Pessoa)obj).getCpf().equals(this.cpf)) ){
return true;
}else{
return false;
}
}
}
PessoaMB.java
public class PessoaMB implements Serializable {
private static final long serialVersionUID = -333995781063775201L;
private Pessoa pessoa = new Pessoa();{
pessoa.setResponsavel(new Pessoa());
}
private Long id;
private List<SelectItem> comboPessoa = getListaComboPessoa();
public List<SelectItem> getComboPessoa() {
return comboPessoa;
}
public void setComboPessoa(List<SelectItem> comboPessoa) {
this.comboPessoa = comboPessoa;
}
public PessoaMB(){
if(this.pessoa == null){
this.pessoa = new Pessoa();
}
}
public String save(){
PessoaFacade pessoaService = new PessoaFacadeImpl();
pessoaService.salva(this.pessoa);
this.pessoa = new Pessoa();
return "listar";
}
public String delete(){
PessoaFacade pessoaService = new PessoaFacadeImpl();
this.pessoa.setId(id);
pessoaService.remove(this.pessoa);
this.pessoa = new Pessoa();
return "removeSucesso";
}
public String merge(){
PessoaFacade pessoaService = new PessoaFacadeImpl();
pessoaService.atualiza(this.pessoa);
this.pessoa = new Pessoa();
return "atualizaSucesso";
}
public String prepareUpdate(){
return "update";
}
public String load(){
PessoaFacade pessoaService = new PessoaFacadeImpl();
this.pessoa = pessoaService.procura(this.id);
return "pesquisaSucesso";
}
public String pesquisaByNome(){
PessoaFacadeImpl pessoaService = new PessoaFacadeImpl();
this.pessoa = pessoaService.procuraByNome(this.pessoa.getNome());
return "pesquisaByNomeSucesso";
}
public List<Pessoa> getPessoas(){
PessoaFacade pessoaService = new PessoaFacadeImpl();
return pessoaService.lista();
}
public List<SelectItem> getListaComboPessoa(){
List<SelectItem> lista = new ArrayList<SelectItem>();
List<Pessoa> l = getPessoas();
for(Pessoa p : l){
SelectItem item = new SelectItem(p.getId().toString(), p.getNome());
lista.add(item);
}
return lista;
}
public List<Pessoa> getPessoasByNome(){
PessoaFacade pessoaService = new PessoaFacadeImpl();
List<Pessoa> lista = pessoaService.pesquisaPessoasByNome(this.pessoa.getNome());
return lista;
}
public Pessoa getPessoa() {
return pessoa;
}
public void setPessoa(Pessoa pessoa) {
this.pessoa = pessoa;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
listaPessoa.jsf
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Lista Pessoas</title>
<script type="text/javascript">
function openLink(link){
window.location.href = link;
}
</script>
</head>
<body>
<f:view>
<h:form>
<legend>Lista de Pessoas</legend>
<h:dataTable id="pessoas" value="#{pessoaMB.pessoas}" var="p">
<h:column>
<f:facet name="header">
<h:outputText value="Nome" />
</f:facet>
<h:outputFormat value="#{p.nome}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Dt. Nascimento" />
</f:facet>
<h:outputText value="#{p.dataNascimento}">
<f:convertDateTime pattern="dd/MM/yyyy" />
</h:outputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="CPF" />
</f:facet>
<h:outputText value="#{p.cpf}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Telefone" />
</f:facet>
<h:outputText value="#{p.telefoneCelular}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="E-mail" />
</f:facet>
<h:outputText value="#{p.email}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Responsavel" />
</f:facet>
<h:outputText value="#{p.responsavel.nome}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="" />
</f:facet>
<h:commandLink action="#{pessoaMB.prepareUpdate}">
<h:graphicImage height="15" id="img_update" alt="Alterar"
url="../_images/edit_people.png">
</h:graphicImage>
<f:setPropertyActionListener value="#{p}" target="#{pessoaMB.pessoa}"/>
</h:commandLink>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="" />
</f:facet>
<h:commandLink action="#{pessoaMB.delete}">
<h:graphicImage height="15" id="img_delete" alt="Excluir" url="../_images/delete.png">
</h:graphicImage>
<f:setPropertyActionListener value="#{p.id}" target="#{pessoaMB.id}" />
</h:commandLink>
</h:column>
</h:dataTable>
</h:form>
<input type="button" value="Novo" onclick="openLink('cadastraPessoa.jsf')" />
</f:view>
</body>
</html>
Fico grato aos amigos que puderem ajudar.