Fala galera, andei pesquisando mais não encontrei solução.
A minha dúvida é o seguinte, tenho 2 tabelas, empresa e usuario, porém na tabela empresa minha pk é o codigo_usuario que vem da tabela usuario, ou seja uma fk, no mysql consegui fazer isso sem problemas, mas quando crio a entidade ele me fala que não existe identificador na tabela empresa.
Alguém já passou por isso ou chuta alguma solução?
Abraço.
No caso sua pk vai ser o objeto da tabela que tem a relação, vai usar um embeddableId, veja:
http://docs.oracle.com/cd/B32110_01/web.1013/b28221/cmp30cfg001.htm
[]s
Cara, desculpe a ignorância, mas sempre utilizei embeddableId para chave composta, não entendi como vai funcionar para pk/fk.
Pode dar um exemplo de como ficaria.
Obrigado.
Se eu entendi bem, você tem um campo codigo_usuario na tabela empresa que referencia o campo codigo_usuario da tabela usuario (fk). Neste caso, tente assim:
@Entity
public class Empresa {
@Id
@Column(name = "codigo_usuario")
private Integer codigo;
@PrimaryKeyJoinColumn //ligando as tabelas pela pk
@OneToOne //ou outro mapamento
private Usuario;
}
Nesse caso sua tabela empresa tem uma coluna chamada codigo_usuario que referencia o codigo_usuario da tabela Usuario. O mapeamento @OneToOne serve apenas para poder carregar o usuario da empresa
Falou.
Wagner,
Eu até cheguei a fazer isso , mas minha dúvida é na tabela empresa, pois quando eu subo o JBOSS aparece um erro dizendo que não exite ID para tabela empresa.
Se não tem que aparecer esse erro, como ficaria a tabela empresa?
Abraço!
Para o mapeamento que eu falei, basta a tabela empresa ter um campo chamado codigo_usuario, uma restrição de PK e uma foreign key apontando pra tabela usuario.
Bota os campos relevantes das tuas tabelas aí pra gente ver como deve ficar. 
Wagner, coloquei assim:
[code]@Entity
@Table(name = “empresa”)
public class Empresa {
@Id
@Column(name = "codigo_usuario")
private Integer codigo;
@PrimaryKeyJoinColumn
@OneToOne(mappedBy = "empresa")
private Usuario usuario;[/code]
[code]@Entity
@Table(name = “cadastro_usuario”)
public class Usuario {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "codigo_usuario")
private Integer codigo;
@OneToOne
private Empresa empresa;[/code]
Porém na hora de inserir ele apresenta a seguinte mensagem:
20:36:45,812 WARN [org.hibernate.util.JDBCExceptionReporter] SQL Error: 1054, SQLState: 42S22
20:36:45,812 ERROR [org.hibernate.util.JDBCExceptionReporter] Unknown column ‘empresa_codigo_usuario’ in 'field list’
20:36:45,812 INFO [STDOUT] org.hibernate.exception.SQLGrammarException: could not insert: [com.leilaopecuario.entidades.Usuario]
Tenta algo assim:
@Entity
@Table(name = "empresa")
public class Empresa {
@Id
@Column(name = "codigo_usuario")
private Integer codigo;
@PrimaryKeyJoinColumn
@OneToOne
private Usuario usuario;
@Entity
@Table(name = "cadastro_usuario")
public class Usuario {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "codigo_usuario")
private Integer codigo;
@PrimaryKeyJoinColumn
@OneToOne
private Empresa empresa;
Wagner,
o problema agora ta sendo na persistencia, ta dizendo que a empresa está transiente, o que é verdade, porem era pra gerar o mesmo código de usuário que gera pra entidade usuário.
Tem alguma ideia como resolver?
Agradeço desde já.
object references an unsaved transient instance - save the transient instance before flushing: com.leilaopecuario.entidades.Usuario.empresa -> com.leilaopecuario.entidades.Empresa
Eu fiz um exemplo e percebi o problema. Consegui resolver desta maneira:
@Entity
@Table(name = "usuarios")
public class Usuario {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "codigo_usuario")
private Integer codigo;
@OneToOne(cascade=CascadeType.ALL)
@PrimaryKeyJoinColumn
private Empresa empresa;
}
@Entity
@Table(name = "empresas")
public class Empresa {
@Id
@Column(name = "codigo_usuario")
@GeneratedValue(generator = "foreign")
@GenericGenerator(name = "foreign", strategy = "foreign", parameters = { @Parameter(name = "property", value = "usuario") })
private Integer codigo;
@OneToOne(mappedBy="empresa")
private Usuario usuario;
}
class Teste {
@Test
public void shouldPersistUsuarioWithEmpresa() {
Usuario u1 = new Usuario();
u1.setDescricao("theUser");
Empresa e1 = new Empresa();
e1.setDescricao("theCompany");
u1.setEmpresa(e1);
e1.setUsuario(u1);
Session currentSession = sessionFactory.getCurrentSession();
Transaction transaction = currentSession.beginTransaction();
currentSession.save(u1);
transaction.commit();
}
}
Deu certinho aqui, vê aí como ficou. Agora, este mapeamento é estranho… hehe, eu criaria uma fk se pudesse, mas sei que as vezes não dá pra mexer no banco
Wagner,
Fiz exatamente isso, mas ta dando o seguinte erro:
null id generated for:class com.leilaopecuario.entidades.Empresa
Eu posso mexer no banco sim, mas queria usar uma pk/fk para forçar o usuário ter só um endereço, assim não tendo que criar uma chave na tabela endereço.
não entendi essa parte
Pode explicar? Presumo que é para gerar a chave de acordo com a chave da tabela usuário é isso?
segue meu código:
[code]@Entity
@Table(name = “cadastro_usuario”)
public class Usuario {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "codigo_usuario")
private Integer codigo;
@PrimaryKeyJoinColumn
@OneToOne(cascade=CascadeType.ALL)
private Empresa empresa;[/code]
[code]@Entity
@Table(name = “cadastro_empresa”)
public class Empresa {
@Id
@Column(name = "empresa_codigo_usuario")
@GeneratedValue(generator = "foreign")
@GenericGenerator(name = "foreign", strategy = "foreign", parameters = { @Parameter(name = "property", value = "usuario") })
private Integer codigoUsuario;
@PrimaryKeyJoinColumn
@OneToOne(mappedBy = "empresa")
private Usuario usuario;[/code]
desde já, agradeço!
Só pra checar, você associou a entidade ao usuário e o usuário à entidade? Assim:
Usuario u1 = new Usuario();
u1.setDescricao("theUser");
Empresa e1 = new Empresa();
e1.setDescricao("theCompany");
u1.setEmpresa(e1); // setando usuario da empresa
e1.setUsuario(u1); // e empresa do usuario
Veja se isso resolve, eu tb tive algum problema assim e era isso que faltava…
O GenericGenerator no caso é pra isso mesmo. No parâmetro nós especificamos que o id virá da propriedade usuario. Eu acredito que tenha até mais possibilidades, definir geradores customizados e coisas do gênero, mas confesso que aí já não entendo mais… hehe
Estranho , está exatamente igual porém continuo recebendo o erro.
Você pode mostrar como estão suas tabelas do banco?
Que raiva, to quase desistindo e colocando um id na tabela empresa…
Tabela usuarios
codigo_usuario (PK)
Tabela empresas
codigo_usuario (PK)
FK codigo_usuario para usuarios.codigo_usuario
hibernate_sequence pra gerar os ids de codigo_usuario.
Bom, tentei mudar o banco e nada, você pode copiar e colar o comando para gerar o banco a partir das Entity’s?
Fazendo assim não tem como eu errar.
Acredito que é a última vez que peço ajuda, desculpa ai…
Abraço!
Opa… segue a parte relevante do dump (tirei apenas esquema de permissões e coisas assim):
CREATE TABLE empresas (
codigo_usuario integer NOT NULL,
descricao text
);
CREATE SEQUENCE hibernate_sequence
START WITH 1
INCREMENT BY 1
NO MAXVALUE
NO MINVALUE
CACHE 1;
CREATE TABLE usuarios (
codigo_usuario integer NOT NULL,
descricao text
);
ALTER TABLE ONLY empresas
ADD CONSTRAINT empresas_pkey PRIMARY KEY (codigo_usuario);
ALTER TABLE ONLY usuarios
ADD CONSTRAINT usuarios_pkey PRIMARY KEY (codigo_usuario);
ALTER TABLE ONLY empresas
ADD CONSTRAINT empresas_codigo_usuario_fkey FOREIGN KEY (codigo_usuario) REFERENCES usuarios(codigo_usuario);
Falou!
Wagner, gerei o banco novamente, e verifiquei cada anotation para ver como ele gerava a FK.
Fiz uns testes e funcionou aqui, muito obrigado pela ajuda, caso precise espero poder ajudar um dia também.
Abraço!
Bacana, que bom que conseguiu!