JPA @OneToOne PK-&gt FK

Tenho duas tabelas:

// Tabela Fonecedor
CREATE TABLE 'fornecedor(idint(10) unsigned NOT NULL auto_increment,nomevarchar(45) NOT NULL default '', PRIMARY KEY (id`)
);

// Tabela endereco
CREATE TABLE endereco (
id_fornec int(10) unsigned NOT NULL default ‘0’,
rua varchar(45) NOT NULL default ‘’,
PRIMARY KEY (id_fornec),
CONSTRAINT FK_ender_1 FOREIGN KEY (id_fornec) REFERENCES fornecedor (id) ON DELETE CASCADE ON UPDATE CASCADE
);

// Objeto Fornecedor
@Entity
public class Fornecedor implements Serializable {

@Id
@Column(name = "id", nullable = false)
private Integer id;

@Column(name = "nome", nullable = false)
private String nome;

@OneToOne(cascade = CascadeType.ALL, mappedBy = "fornecedor")
private Endereco endereco;

// Objeto Endereco
@Entity
public class Endereco implements Serializable {

@Id
@Column(name = "id_fornec", nullable = false)
private Integer idFornec;

@Column(name = "rua", nullable = false)
private String rua;

@JoinColumn(name = "id_fornec", referencedColumnName = "id", insertable = false, updatable = false)
@OneToOne
private Fornecedor fornecedor;

Quando vou persistir o objeto Fornecedor uma exceptions e gerada dizendo, que o id_fornec nao pode ser nulo, ou seja o JPA nao esta usando automaticamente o ID gerado pelo fornecedor para definir a FK automaticamente.
Alguem pode me ajudar?

Ola pessoal. Ainda não consegui resolver o problema acima.
Não estou conseguindo fazer a anotação corretamente para que na FK seja atribuido o valor da PK gerada automaticamente pelo mysql.

Olaa Pessoal estou reabrindo o tópico pq estou exatamente com o mesmo problema???
Alguém tem alguma dica para a solução???

Obrigado =D

Problema chato pra caramba. A JPA pura não vai conseguir te ajudar. Se estiver usando Hibernate, tens uma chance:

    @Id
    @Column(name = "worder_id")
    @GeneratedValue(generator = "foreign")
    @GenericGenerator(name = "foreign", strategy = "foreign", 
    parameters = {@Parameter(name = "property", value = "workOrder")})
    public Integer getId() {
        return id;
    }

Procure, portanto por generic generator no hibernate.

Cara valeu pela dica… Mas vc poderia me explicar a parte dos parameters?

parameters = {@Parameter(name = "property", value = "workOrder")}

o que eu coloco no value = “workOrder” ???

Valeu
Obrigado =D

Esse é o seu relacionamento. Eu peguei um exemplo pronto aqui do trabalho, na pressa. ‘workOrder’ é a propriedade que é de fato a entidade relacionada a seu POJO, a qual ele usa como valor da chave.

Opaaa desculpa a demoraaaq…
Mas cara acho que nao funcionou nao… =///
vou postar como fiz no meu código…

Do lado da classe onde NAO fica nenhuma coluna ficou assim:

Classe A:

@Id 
@Column(name="ID")
private Long id;


@OneToOne()
@PrimaryKeyJoinColumn
private ClasseB total = new ClasseB();

e do lado da classe onde eu gostaria de gerar o ID da classe A ficou assim

Classe B:

        @Id
	@Column(name="ID_A")
	@GeneratedValue(generator = "foreign")  
	@GenericGenerator(name = "foreign", strategy = "foreign",   
			parameters = {@Parameter(name = "property", value = "idNotaFiscal")})
	private Long id;
	
	@OneToOne(fetch=FetchType.LAZY)
	@JoinColumn(name="ID_A")
	private ClasseA nota;

ele da esse erro aqui:

Erro: java.lang.IllegalStateException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.br.ClasseB

alguem tem mais alguma dica ou eu estou fazendo algo de errado??? ainda nao conseguii

abraçosss e desculpa pela demora tive que viajar =\

Classe “A”

        @PrimaryKeyJoinColumn
	@LazyToOne(LazyToOneOption.PROXY)
	@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
	public WorkOrderDetail getDetails() {
		return details;
	}

Classe “B”

    @Id
    @Column(name = "worder_id")
    @GeneratedValue(generator = "foreign")
    @GenericGenerator(name = "foreign", strategy = "foreign", 
    parameters = {@Parameter(name = "property", value = "workOrder")})
    public Integer getId() {
        return id;
    }

    @OneToOne(mappedBy = "details", fetch = FetchType.LAZY)
    public WorkOrder getWorkOrder() {
        return workOrder;
    }

Antes de persistir uma instância de “A”, eu faço o relacionamento entre “A” e “B” via “a.set(b)”.

Então tentei novamente agora o erro foi na outra classe… vou dar mais uma pesquisada =\
Será que ainda continua algo de errado?

Olha o Erro:

Erro: java.lang.IllegalStateException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.br.ClasseA

Agora deu na ClasseA e nao na ClasseB… Vou dar mais uma pesquisada aqui…
Que negócio chato

=//

Obrigado pela ajuda

MInhas classes como ficaram?

ClasseA:

 @Id   
 @Column(name="ID")  
 private Long id;  
   
   
 @OneToOne(fetch = FetchType.LAZY, cascade = {CascadeType.ALL})
 @PrimaryKeyJoinColumn  
 private ClasseB total = new ClasseB(); 

ClasseB:

 @Id   
 @Column(name="ID")  
	@GeneratedValue(generator = "foreign")  
	@GenericGenerator(name = "foreign", strategy = "foreign",   
			parameters = {@Parameter(name = "property", value = "nota")})
 private Long id;  
   
   
@OneToOne(fetch=FetchType.LAZY, mappedBy="total")
 private ClasseA nota;  

Amigo, o meu mapeamento está funcionando sem nenhum problema. Acredito que você esteja enfrentando problemas não relacionados ao mapeamento em si. Sugiro testar o mapeamento separadamente, e depois incluir no seu caso de uso e tentar identificar problemas.

Desculpe não poder ajudar muito =)

Okk Vou pesquisar mais aqui… Minha classe está muito grande também…
Quando tiver um resposta eu coloco aqui…
Mas valeu pela ajudo… Me ajudou bastante ja!!!

=D

Bom eu consegui!!!
Na realidade a anotação está correta sim… O problema que estava fazendo é o seguinte:

qndo for gravar tenho que setar o objeto ClasseA no objeto total: por exmeplo

[code]
ClasseA obj = new ClasseA();
… fazer oq eu tenho que fazer…

ClasseB obj2 = new ClasseB();

// AQUIIII
obj2.setClasseA(obj);

obj.setClasseB(obj2);[/code]

daí eu mando salvar…

É isso aeww

Obrigado…

Qualquwer coisa estou aqui pra ajudar se alguem ainda nao conseguir

Abraçoss

marque com @javax.persistence.GeneratedValue informando a estratégia utilizada por você para gerar IDs

http://java.sun.com/javaee/5/docs/api/javax/persistence/GeneratedValue.html