Mapeamento @ID @OneToOne

é possivel deixar o proprio @ID como FK ?
exemplo:

[code]@Entity
@Table(name = “Pessoa”)
public class Pessoa {

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name  = "id_pessoa")
private int idPessoa;[/code]

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

@Id
@OneToOne
@Cascade(value = CascadeType.SAVE_UPDATE)
@JoinColumn(name="id_cliente")
@ForeignKey(name="cliente_pessoa_fk")
private Pessoa pessoa = new Pessoa();[/code]

As tabelas sao geradas, porem ao persistir um cliente, mesmo setando uma pessoa já persistida na base, ou uma nova pessoa, ele retorna o erro:

Caused by: java.sql.BatchUpdateException: Column 'id_pessoa' cannot be null
 at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:2020)
 at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1451)
 at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:1723)
 at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
 at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)

Mano posta seu codigo completo do cliente,mas pelo o que eu ai vc não criou nenhum atributo na classe cliente.



import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.hibernate.annotations.ForeignKey;

@Entity
@Table(name = "Pessoa")
public class Pessoa {

	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	@Column(name  = "id_pessoa")
	private int idPessoa;
	
	@Column(name = "nome_fantasia", length=50)
	private String nomeFantasia;
	
	@Column(name="razao_social", length = 50, nullable = false)
	private String razaoSocial;
	
	@Column(name = "endereco", length = 200, nullable = false)
	private String endereco;
	
	@Column(name = "bairro", length = 30, nullable = false)
	private String bairro;
	
	@ManyToOne(optional = false)
	@JoinColumn(name="id_cidade")
	@ForeignKey(name= "pessoa_cidade_fk")
	private Cidade cidade;
	
	@Column(name = "cep", length = 10, nullable = false)
	private String cep;
	
	@Column(name= "caixa_postal")
	private Integer caixaPostal;
	
	@Column(name ="telefone", length = 15)
	private String telefone;
	
	@Column(name="fax", length=15)
	private String fax;
	
	@Column(name="celular", length=15)
	private String celular;
	
	@Column(name = "cpf_cnpj", length = 18, nullable = false, unique = true)
	private String cpfCnpj;
	
	@Column(name = "rg_ie", length = 20, nullable = false)
	private String rgIe;
	
	@Column(name ="email", length = 60)
	private String email;
	
	@Column(name = "home_page", length=50)
	private String homePage;
	
	@Temporal(TemporalType.TIMESTAMP)
	@Column(name = "data_cadastro")
	private Date dataCadastro  = new Date();
	
	@Column(name="endereco_numero", length = 11, nullable = false)
	private String enderecoNumero;
	
	@Column(name= "endereco_complemento", length = 30)
	private String enderecoComplemento;

//get set

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + idPessoa;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Pessoa other = (Pessoa) obj;
		if (idPessoa != other.idPessoa)
			return false;
		return true;
	}
	
}

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.ForeignKey;
import org.hibernate.annotations.Generated;

import br.com.nimiam.enumerated.ClienteSituacaoEnum;

@Entity
@Table(name="cliente")
public class Cliente implements Serializable {
	
	private static final long serialVersionUID = 1L;

	@Id
	@OneToOne
	@Cascade(value = CascadeType.SAVE_UPDATE)
	@JoinColumn(name="id_cliente")
	@ForeignKey(name="cliente_pessoa_fk")
	
	private Pessoa pessoa = new Pessoa();
	
	@ManyToOne()
	@JoinColumn(name="id_grupo_pessoa")
	@ForeignKey(name="cliente_grupoPessoa_fk")
	private GrupoPessoa grupoPessoa;
	
	@ManyToOne()
	@JoinColumn(name="id_vendedor")
	@ForeignKey(name="cliente_vendedor_fk")
	private Vendedor vendedor;
	
	@ManyToOne()
	@JoinColumn(name="id_conceito")
	@ForeignKey(name="cliente_conceito_fk")
	private Conceito conceito;
	
	@Column(name="endereco_cobranca" , length=200)
	private String enderecoCobranca;
	
	@Column(name= "bairro_cobranca" ,  length=30)
	private String bairroCobranca;
	
	@ManyToOne
	@JoinColumn(name = "id_cidade_cobranca")
	@ForeignKey(name="cliente_cidadeCobranca_fk")
	private Cidade cidade;
	
	@Column(name="cep_cobranca" , length=10)
	private String cepCobranca; 
	
	@Column(name="caixa_postal_cobranca")
	private Integer caixaPostalCobranca;
	
	@Column(name="telefone_cobranca" ,  length=15)
	private String telefoneCobranca;
	
	@Enumerated(EnumType.STRING)
	@Column(name="situacao")
	private ClienteSituacaoEnum situacao;
	
	@Column(name="cpf_cnpj_entrega" , length=10)
	private String cpf_cnpj_entrega;
	
	@Column(name="limite_credito" , scale=15 , precision=2 , columnDefinition="NUMERIC(15,2)")
	private Double limiteCredito;

	@Temporal(TemporalType.TIMESTAMP)
	@Column(name= "data_validade_sintegra")
	private Date dataValidadeSintegra;
	
	@Column(name  = "suframa", length=15)
	private String suframa;
	
	@Temporal(TemporalType.TIMESTAMP)
	@Column(name="data_suframa")
	private Date data_suframa;
	
	@Temporal(TemporalType.TIMESTAMP)
	@Column(name="data_fundacao")
	private Date data_fundacao;
	
	@Column(name="perc_desconto"  , scale=5 , precision=2 , columnDefinition="NUMERIC(5,2)")
	private Double percDesconto;
	
	
	@Column(name="comissao_negociada"  , scale=5 , precision=2 , columnDefinition="NUMERIC(5,2)")
	private Double comissaoNegociada;
	
	@ManyToOne
	@JoinColumn(name="id_transportador")
	@ForeignKey(name  = "cliente_transportador_fk")
	private Transportador transportador;
	
	@ManyToOne
	@JoinColumn(name ="id_transp_redespacho_fk")
	@ForeignKey(name ="cliente_transpRedesp_fk")
	private Transportador transportadorRedespacho;

	@Column(name="observacao" , length=4000)
	private String observacao;
	
	@Column(name="observacao_entrega" , length=4000)
	private String observacaoEntrega;

	//get set

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((pessoa == null) ? 0 : pessoa.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Cliente other = (Cliente) obj;
		if (pessoa == null) {
			if (other.pessoa != null)
				return false;
		} else if (!pessoa.equals(other.pessoa))
			return false;
		return true;
	}

}

postei apenas o relacionamento em cima, nao sei se funciona, é que nao quero trabalhar com herança devido a n problemas com polimorfismo que o hibernate tem. entao fiz meio que uma “gambiarra” para manter o id co cliente como ID e FK para pessoa, mas nao sei se o hibernate aceita isso.

Mano cade o seu “id_cliente”?

a propria Pessoa sacou ?

Preciso que o id do cliente seja PK da tabela e FK para Pessoa.idPessoa.

Mano não to entendendo???

--------------------------------------------------- @Id @OneToOne @Cascade(value = CascadeType.SAVE_UPDATE) @JoinColumn(name="id_cliente") @ForeignKey(name="cliente_pessoa_fk") -----------------------------------------------------
Pq vc quer q o id_cliente seja chave primaria de uma classe e Fk de outra certo?
Então vc precissa criar o Id_cliente na classe cliente e pelo relacionamento vc dizer que este campo sera chave estrangeira na outra tabela em q vc colocou o relacionamento.

Quero isso pois é uma herança e não quero usar extends!(Já tive problemas com isso no hibernate quando precisa usar polimorfismo com herança );

é mais facil executar buscas se os id do cliente for o mesmo da pessoa, e se são iguais não tem necessidade de dois campos na tabela, pra que um id_cliente e um id_pessoa na tabela cliente se vou manter no id_cliente sempre o mesmo valor do id_pessoa. um unico campo sendo PK da tabela cliente e FK para pessoa já resolve. o problema está em fazer o mapeamento disso.

Atenciosamente;

Use a anotação @PrimaryKeyJoinColumn:

@PrimaryKeyJoinColumn(name="id_pessoa")
private Pessoa pessoa;