OneToOne Unidirecional

10 respostas
thianolima

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

@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
}
@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
}
@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;

}

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

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 */;

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....

peco para o moderador apagar o topico igual criado na secao de jdbc e jpa pois ninguem respondeu la entao resolvi mover para esta parte que tem mais visualizacao.

10 Respostas

thianolima

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

brunorota

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

thianolima

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…

brunorota

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

thianolima

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

brunorota

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

thianolima

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?

brunorota

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

C

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:


C

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:






Criado 4 de maio de 2011
Ultima resposta 13 de dez. de 2011
Respostas 10
Participantes 3