Hibernate @OneToOne não funciona

5 respostas
R

Tenho duas tabelas tabfun(CODFUN Number PK, …) e tabsal(CODFUN Number PK, SALARIO Number)
Estou tendando persistir dados nas tabelas acima, porém não estou conseguindo one-to-one. Quando tento persistir apenas Funcionário, tenho exito.

Um Funcionário tem um Salario

@javax.persistence.Entity

@Table(name=TABFUN)

public class Funcionario implements Serializable

{

@Id @javax.annotation.Generated(value={assign})

int codFun; //código do funcionário
@Column(name="CODDEP")
int codDep; //código do departamento

@Column(name="NOMEFUN")
String  nomeFun; //nome do funcionárion

@Column(name="RG")
int  rg; //rg do funcionário   

@OneToOne
Salario salario;
  //getters e setters

}

@javax.persistence.Entity

@Table(name=TABSAL)

public class Salario implements Serializable {
@Id @javax.annotation.Generated(value={"assign"})
int codFun;     //código do funcionário

@Column(name="SALARIO")
double salario;
    //getters e setters

}

select salario_.codFun, salario_.SALARIO as SALARIO2_ from TABSAL salario_ where salario_.codFun=?
Hibernate: insert into TABFUN (CODDEP, NOMEFUN, RG, salario_codFun, codFun) values (?, ?, ?, ?, ?)
Exception in thread “main” br.com.hibernate.DataAccessLayerException: org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update
java.sql.BatchUpdateException: ORA-00904: “SALARIO_CODFUN”: identificador inválido

Desde já obrigado
:?:

5 Respostas

marcusmage

Para mapear One-To-One corretamente, vc precisa anotar o “campo” salario na classe Funcionario com @JoinColumn(name=“codFun”), essa coluna é a para realização da junção entre as tabelas, funcionario e Salario. Sugiro que vc mude o nome do campo chave (Id) da tabela de salario.

Ex: @OneToOne
@JoinColumn(name=“SALARIO_ID”)
private Salario salario

R

marcusmage o erro parrou de acontecer após @JoinColumn(name=“SALARIO_ID”)

Mais os dados só estão sendo persistidos para a tabela tabfun, a tabsal não esta salvando nada

paulovittor23

Dá uma olhada no cascade do relacionamento.

marcusmage

Como o paulovittor23 sugeriu e eu esqueci de mencionar. Vc tem que fornece a opção de cascade para o relacionamento.

Ex:

@OneToOne(cascade={CascadeType.ALL})

@JoinColumn(name=SALARIO_ID)

private Salario salario

O atributo cascade foi configurado como ALL, faz om que a criação de um Salario seja em cascata qunado a entidade Funcionario é persistida.

Isso deve funcionar! :slight_smile:

R

O relacionamento OneToOne do Hibernate não permite ou desencoraja o uso de entidades fracas, neste mesmo exemplo, a Classe Salário não é mandatória em relação a Classe Funcionário mas, ao contrário do que parece, é requisito necessário para a existência da Classe Funcionário, tanto que a chave estrangeira fica em Funcionário e não em Salário.

Nem sempre o problema é do Hibernate, mas tem a ver com estas metodologias mirabolantes de revistinha JAVA, acontece que em relacionamentos deste tipo, o armazenamento é realizado em duas etapas, primeiro Funcionario e depois o Salario. Agora que começa a bagaça: A classe Funcionário tem o atributo Salario, senão tivesse não ficaria no padrão. Também não tem a menor graça a classe Salario ter um atributo Funcionario, isso não seria DDD. Ao mesmo tempo, salvar a classe Funcionario de forma quebrada com salário faz o RepositorioDao ficar deselegante. Mais uma vez, é criação de um conceito que se contradiz com conceitos pre-existentes.

Em tempo de JAVA, isso parece que não tem o menor problema, mas experimente fazer uma importação de dados, ou qualquer outra grande operação de banco com estas particularidades? Vira uma meleca.

Pior que isso, é esta postura arrogante dos “criadores do futuro”, certamente inventaram uma histórinha de que entidade fraca ou é bobagem ou é antigo e obsoleto.

Criado 7 de fevereiro de 2008
Ultima resposta 10 de dez. de 2011
Respostas 5
Participantes 4