OneToOne Unidirecional

Meu problema e o seguinte tenho uma classe pessoa que eu generalizo para a classe instituicao, aluno, professor e outras, porem no momento estou com problemas na classe instituicao pois estou implementando um cadastro em jsf + ejb + jpa2 com eclipslink.

Segue abaixo as minhas classes enxugadas

[code]
@Entity
@Table(name = “pessoa”)
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = “pes_tipo”, discriminatorType = DiscriminatorType.STRING, length = 1)
@DiscriminatorValue(“0”)
public class Pessoa implements Serializable {

private static final long serialVersionUID = 1;

@Id
@Column(name = "pes_codigo")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer idPessoa;

@Column(name = "pes_tipo")
private String tipo;

@OneToOne(cascade=CascadeType.ALL, fetch=FetchType.LAZY)    
@PrimaryKeyJoinColumn(name="pes_codigo")
Endereco endereco;

//get sets
}[/code]

[code]
@Entity
@Table(name = “endereco”)
public class Endereco implements Serializable {

private static final long serialVersionUID = 1;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "end_codigo")
private Integer idEndereco;

@Column(name = "end_numero")
private int numero;

@Column(name = "end_complemento")
private String complemento;

@OneToOne(mappedBy="endereco", cascade=CascadeType.ALL, fetch=FetchType.LAZY)
@JoinColumn(name="pes_codigo", insertable=true, updatable=true, nullable=false)
private Pessoa pessoa;

//get sets
}[/code]

[code]@Entity
@Table(name=“instituicao”)
@PrimaryKeyJoinColumn(name=“pes_codigo”)
@DiscriminatorValue(“I”)
public class Instituicao extends Pessoa{

@Column(name="ins_cnpj")
private String cnpj;

@Column(name="ins_razao_social")
private String razaoSocial;

@Column(name="ins_inscricao_estadual")
private String inscricaoEstadual;

}[/code]

Eu retirei alguns atributos das classes para ficar mais facil de ler o codigo.
Como voces podem ver existe uma classe insitituicao que herda de pessoa e a classe pessoa tem uma associacoa OneToOne para a classe Endereco.
Logo abaixo eu exportei as tabelas do banco de dados MySQL para que voces cosigam ter uma breve nocao de como estao as tabelas

[code]
CREATE TABLE endereco (
end_codigo int(11) NOT NULL AUTO_INCREMENT,
end_numero int(11) NOT NULL,
end_complemento varchar(255) NOT NULL,
log_codigo int(11) NOT NULL,
pes_codigo int(11) DEFAULT NULL,
PRIMARY KEY (end_codigo),
KEY FK_ENDERECO_LOGRADOURO (log_codigo),
KEY FK672D67C9FF00390 (pes_codigo),
KEY FK672D67C9AEE113F7 (log_codigo),
CONSTRAINT FK_ENDERECO_LOGRADOURO FOREIGN KEY (log_codigo) REFERENCES logradouro (log_codigo) ON UPDATE CASCADE,
CONSTRAINT FK_ENDERECO_PESSOA FOREIGN KEY (pes_codigo) REFERENCES pessoa (pes_codigo) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

CREATE TABLE pessoa (
pes_codigo int(11) NOT NULL AUTO_INCREMENT,
pes_nome varchar(50) NOT NULL,
pes_telefone varchar(15) DEFAULT NULL,
pes_email varchar(100) DEFAULT NULL,
pes_login varchar(50) NOT NULL,
pes_senha varchar(20) NOT NULL,
pes_bloqueado varchar(1) NOT NULL DEFAULT ‘N’,
PRIMARY KEY (pes_codigo)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;

CREATE TABLE instituicao (
pes_codigo int(11) NOT NULL,
ins_razao_social varchar(100) NOT NULL,
ins_cnpj varchar(14) NOT NULL,
ins_inscricao_estadual varchar(20) NOT NULL,
PRIMARY KEY (pes_codigo),
KEY PK_EMPRESA (pes_codigo),
CONSTRAINT FK_INSTITUICAO_PESSOA FOREIGN KEY (pes_codigo) REFERENCES pessoa (pes_codigo) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;[/code]

O meu grande problema esta na hora de salvar a Instituicao pois o JPA insere tudo na tabela instituicao, pessoa, e na tabela endereco fica faltando fazer o relacionamento com pessoa ou seja o campo pes_codigo fica vazio.
Ja fiz de tudo quanto e anotacao possivel nessas entidades e nao consegui fazer salvar, alguem aqui poderia me dar uma luz no fim do tunel…???
A ultima tentativa foi inserir primeiro instituicao sem endereco e depois alterar o objeto com a instituicao ja com o idPessoa criado e altera-la e mesmo assim nao houve sucesso algum continuei sem ver o pes_codigo dentro da tabela endereco.
Alguem pode me ajudar urgente com esse problema…

Pessoal com certeza alguem por aqui ja passou por esse problema pois vi diversos posts aqui mas nada deu certo alguem poderia me dizer o que estou fazendo errado pois nao sei masi como resolver esse problema e ja estou batendo cabeca a no minimo uns 3 dias

Thiano se o relacionamento unidirecional

A entidade endereço não precisa de uma referencia para Pessoa, agora se for bidirecional precisa

Olha eu fiz um exemplo aqui no meu pc e deu certo, vou te passar

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
public class Pessoa {

	@Id
	@GeneratedValue
	private int id;
	private String nome;
	
	@OneToOne
	Endereco endereco;
	
	public Endereco getEndereco() {
		return endereco;
	}
	public void setEndereco(Endereco endereco) {
		this.endereco = endereco;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getNome() {
		return nome;
	}
	public void setNome(String nome) {
		this.nome = nome;
	}
	
}

@Entity
public class Cliente extends Pessoa{

	private String codigo;

	public String getCodigo() {
		return codigo;
	}

	public void setCodigo(String codigo) {
		this.codigo = codigo;
	}
}

@Entity
public class Endereco {

	@Id
	@GeneratedValue
	private int id;
	private String endereco;
	
	@OneToOne(mappedBy="endereco")
	private Pessoa pessoa;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getEndereco() {
		return endereco;
	}

	public void setEndereco(String endereco) {
		this.endereco = endereco;
	}

	public Pessoa getPessoa() {
		return pessoa;
	}

	public void setPessoa(Pessoa pessoa) {
		this.pessoa = pessoa;
	}
}

public void gravar(){
		
		Endereco e = new Endereco();
		e.setEndereco("Rua das graças");
		
		Cliente p = new Cliente();
		p.setNome("Bruno");
		p.setCodigo("dds5ad64a");
		
		em.persist(e);
		em.persist(p);
		
		e.setPessoa(p);
		p.setEndereco(e);
	}

Não sei oq tem de errado com o seu código, mais desse jeito que eu fiz deu certo

Valew

Nao sei porque mais algo esta me dizendo que tem alguma coisa haver com o EJB
Eu nao usava a anotacao @PrimaryKeyJoinColumn e nao estava colocalndo o CascadeType e dai me gerava varios erros dessa forma que esta meu codigo agora com coisas que eu nem sei mais para que serve…rs ele nao gera erro mas nao salva a chave do da pessoa dentro da tabela endereco.
Você poderia me passar a estrutura do seu banco de dados para eu comparar com a minha.
Deixa eu perguntar o mappedBy é o nome do atributo na classe que esta mapeado, o nome da classe, ou o nome da tabela no banco de dados?
Vou tentar refazer tudo mais tarde e posto aqui se deu certo ou errado.
Obrigado pela ajuda, se alguem saber o erro do codigo por favor me ajude…

O mappedBy diz que o cabrinha referênciado por ele é o dono do relacionamento em um relacionamento bidirecional

vamos lah a tabela cliente tem

codigo
id

a tabela endereco tem

id
endereco

e a tabela pessoa tem

id
nome
endereco_id

Tudo preenchido normal

Voce esta salvando endereco dentro de pessoa no meu caso eu faço o inverso mas vou rever o mapeamento chegando em casa e posto aqui para ver se voce consegui me ajudar com esse negocio que ta me deixando maluco jah.
To quase para matar a tabela endereco e jogar tudo dentro de pessoa…rs

O pq vc tem que salvar a pessoa dentro do endereço?

Eh relevante a classe endereço ter conhecimento da classe Pessoa?

Pq ae vc pode fazer um relacionamento Unirecional mesmo

Ae é só vc fazer

public class Pessoa{

@OneToOne
Endereco endereco;
}

e a tabela Endereco não precisa ter uma referência pra Pessoa

Eu não vejo motivo pra mapeamento pra endereço ser um mapeamento bidirecional, a nao ser que você tenha um motivo bem específico

E que eu estava pensando em reaprovaitar esse modelo para um outro projeto onde precisaria dessa estrtura pois uma pessoa poderia ter N endereços, porem acho que nesse projeto isso nunca vai acontecer todas pessoas precisaram de 1 unico endereco.
Vou alterar isso no meu banco e fazer um teste.
Mas dessa forma eu primeiro vou precisar salvar o objeto endereco e so depois o objeto pessoa certo?
Ou se eu enviar o objeto herdado de pessoa para salvar pelo JPA ele ja vai se encarregar de fazer isso?

Então, você pode anotar o objeto endereço na classe Pessoa com cascating, porém, tem muita gente que não gosta de usar tal funcionalidade porque dizem que acaba com o desempenho do sistema, então muita gente prefere salvar no dedo hehehe

Mais no caso se cada cliente poderia ter vários endereços o código ficaria assim, um relacionamento OneToMany unidirecional

@Entity
public class Pessoa{

@OneToMany
List<Endereco> enderecos;

}

@Entity
public class Endereco{

private int codigo;
private String rua;

repare que a classe Endereco não precisa ter uma referência para a classe Pessoa.

E a classe pessoa pode ter N endereços, em um relacionamento OneToMany unidirecional

Valeww

Ola pessoal tudo bem?

Estou enfrentando um problema em relação a OneToOne Unidirecional.
Trabalho há um bom tempo com a IDE NetBeans, e agora estou iniciando com o eclipse, começando com um projeto JPA + HiberNate e MySql.

Importando as entidades do banco de dados no netbeans não tenho problema algum, mas no eclipse com o plugin do JPA, ele gera um erro, imagem anexada a baixo:


Ola pessoal tudo bem?

Estou enfrentando um problema em relação a OneToOne Unidirecional.
Trabalho há um bom tempo com a IDE NetBeans, e agora estou iniciando com o eclipse, começando com um projeto JPA + HiberNate e MySql.

Importando as entidades do banco de dados no netbeans não tenho problema algum, mas no eclipse com o plugin do JPA, ele gera um erro, imagem anexada a baixo.

Estou usando chave primária dupla, Id e Id_empresa, nas tabelas.

Já procurei em vários fóruns sobre relacionamento com JPA + HIBERNATE, mas não tive sucesso.

Agradeço pela a atenção.

vlw :smiley: