Chave Composta Hibernate

7 respostas
A

Galera, vou começar dizendo o resultado que desejo ter:

tabela PlanoSaude:

id | cliente_id | outros campos...
1 | 1 | ...
1 | 2 | ...
2 | 1 | ...

(notem que o campo ID repete, mas não para o mesmo cliente_id... é gerado um novo ID para um outro Cliente_id....

Para tal, tenho as seguiintes entidades: Cliente:
@Entity
@Resource
public class Cliente {

	@Id
	@GeneratedValue
	private Long id;
	@Length(max = 50)
	@PrimaryKeyJoinColumn
	private String titular;
	@Length(max = 1)
	private String sexo;
	@CPF
	@Length(max = 11)
	private String cpf;
//...outros campos...

	@OneToMany(mappedBy = "cliente", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
	@Fetch(org.hibernate.annotations.FetchMode.SUBSELECT)
	private List<PlanoSaude> planoSaude;
PlanoSaude:
@Entity
@Resource
public class PlanoSaude {

	@Id
	@GeneratedValue
	private Long id;
	private Long cliente_id;
	@Length(max = 40)
	@NotNull
	private String planoSaude;
//...outros campos...
	@ManyToOne
	@JoinColumn(name = "cliente_id", insertable = false, updatable = false)
	private Cliente cliente;

Minha ideia inicial era anotar o campo cliente_id da classe PlanoSaude com @Id, porém da um erro dizendo para usar o "extends serializable".... até fiz umas tentativas e erros, e decidi pedir ajuda....

Para ficar bem claro a duvida, desejo saber a anotação que devo colocar para que a tabela PlanoSaude não gere um ID sequencial independente, mas um sequencial com base na chave (neste caso o cliente_id) assim como mencionei no inicio do post. Uma coisa eu sei que é necessário: definir cliente_id como chave também. Mas to perdidasso como fazer....

**Eclipse + Hibernate + Vraptor + JSP + Jquery ...

7 Respostas

C

Não faz muito sentido essa chave composta que tais querendo criar, por qual motivo teria que ser assim? não seria o caso fazer uma relação 1:n ou n:n da classe cliente com plano de saúde?!
No caso do id do cliente em plano de saúde não vai ser feito desta forma, é só criar uma relação entre cliente e plano de saúde e dizer que o objeto cliente é o id deste objeto que o hibernate já faz o mapeamento correto no banco assim

public class PlanoSaude {  
  
    @Id  
    @GeneratedValue  
    private long id;
    @Id  
    @ManyToOne
    private Cliente cliente;

[...]
}
J

Se você tem o poder de decidir como as tabelas serão criadas, para facilitar a vida não use chave composta. Para evitar duplicidade cria uma unique key. Chave composta só para tabelas puramente de relacionamentos, onde no Hibernate mapeia como many to many.

F

Se entendi bem oq vc quer: http://uaihebert.com/?p=1622&page=22

A
CharlesAlves:
Não faz muito sentido essa chave composta que tais querendo criar, por qual motivo teria que ser assim? não seria o caso fazer uma relação 1:n ou n:n da classe cliente com plano de saúde?! No caso do id do cliente em plano de saúde não vai ser feito desta forma, é só criar uma relação entre cliente e plano de saúde e dizer que o objeto cliente é o id deste objeto que o hibernate já faz o mapeamento correto no banco assim
public class PlanoSaude {  
  
    @Id  
    @GeneratedValue  
    private long id;
    @Id  
    @ManyToOne
    private Cliente cliente;

[...]
}

Sim, a relação Cliente -> PlanoSaude é 1:n.

Fiz a anotação do @Id como falou, e qdo a anotação @Id aparece 2 vezes na mesma classe, gera o seguinte erro:

composite-id class must implement Serializable: br.com.ajm.scdri.modelo.PlanoSaude

Este exemplo pode não lhe parecer muito apropriado, mas pense na relação PEDITO -> ITEM, também 1:n
Teriamos na tabela do pedido:
Pedido
1
2
3
E na tabela de item
Item / Pedido
1 / 1
2 / 1
3 / 1
4 / 2 ???? (isso quer dizer que para o Pedido 2 eu começo pelo item 4??? deveria começar pelo item 1... a representação disso na tela faria uma boa diferença
5 / 2 ????
no lugar disso, a tabela item deveria ser, no caso que quero montar:
1 / 1
2 / 1
3 / 1
1 / 2
2 / 2

.. eu poderia definir o campo cliente_id como primeira Chave e outro campo chave(item) para permitir duplicar esse campo pois a relação é 1:n, e definir uma regra de auto incremento.... ou qquer coisa do tipo parecida com isso...

Helps???

A

vou ver o link que vc mandou… se ajudar posto aki…

-EDIT-

Qse isso mano… mas ainda não é…
veja meu reply acima…

obrigado pela atenção…

F
andersonjm:
CharlesAlves:
Não faz muito sentido essa chave composta que tais querendo criar, por qual motivo teria que ser assim? não seria o caso fazer uma relação 1:n ou n:n da classe cliente com plano de saúde?! No caso do id do cliente em plano de saúde não vai ser feito desta forma, é só criar uma relação entre cliente e plano de saúde e dizer que o objeto cliente é o id deste objeto que o hibernate já faz o mapeamento correto no banco assim
public class PlanoSaude {  
  
    @Id  
    @GeneratedValue  
    private long id;
    @Id  
    @ManyToOne
    private Cliente cliente;

[...]
}

Sim, a relação Cliente -> PlanoSaude é 1:n.

Fiz a anotação do @Id como falou, e qdo a anotação @Id aparece 2 vezes na mesma classe, gera o seguinte erro:

composite-id class must implement Serializable: br.com.ajm.scdri.modelo.PlanoSaude

Este exemplo pode não lhe parecer muito apropriado, mas pense na relação PEDITO -> ITEM, também 1:n
Teriamos na tabela do pedido:
Pedido
1
2
3
E na tabela de item
Item / Pedido
1 / 1
2 / 1
3 / 1
4 / 2 ???? (isso quer dizer que para o Pedido 2 eu começo pelo item 4??? deveria começar pelo item 1... a representação disso na tela faria uma boa diferença
5 / 2 ????
no lugar disso, a tabela item deveria ser, no caso que quero montar:
1 / 1
2 / 1
3 / 1
1 / 2
2 / 2

.. eu poderia definir o campo cliente_id como primeira Chave e outro campo chave(item) para permitir duplicar esse campo pois a relação é 1:n, e definir uma regra de auto incremento.... ou qquer coisa do tipo parecida com isso...

Helps???

Cara, pelo q entendi do seu ultimo exemplo oq vc precisa é de um mapeamento @ManyToMany comum.

Vc não precisa q seja assim ?

Pedido / Item
1 / 1
1 / 2
1 / 3
2 / 1
2 / 5
3 / 2

etc...
public class Pedido()  {

     @Id    
     @GeneratedValue    
     private long id;  

     @ManyToMany
     @JoinTable(name = "pedido_item", joinColumns = @JoinColumn(name = "pedido_id"), inverseJoinColumns = @JoinColumn(name = "item_id"))
     private List<Item> items;

}

public class Item()  {

     @Id    
     @GeneratedValue    
     private long id;  

     @ManyToMany(mappedBy="items") //bidirecional, se precisar
     private List<Pedido> pedidos;

}
A
fdiaz2011:

Cara, pelo q entendi do seu ultimo exemplo oq vc precisa é de um mapeamento @ManyToMany comum.

Vc não precisa q seja assim ?

Pedido / Item
1 / 1
1 / 2
1 / 3
2 / 1
2 / 5
3 / 2

etc...
public class Pedido()  {

     @Id    
     @GeneratedValue    
     private long id;  

     @ManyToMany
     @JoinTable(name = "pedido_item", joinColumns = @JoinColumn(name = "pedido_id"), inverseJoinColumns = @JoinColumn(name = "item_id"))
     private List<Item> items;

}

public class Item()  {

     @Id    
     @GeneratedValue    
     private long id;  

     @ManyToMany(mappedBy="items") //bidirecional, se precisar
     private List<Pedido> pedidos;

}

eh.. pode ser que eu esteja equivocado quando a questão do @Onetomany e @Manytomany....
vou tentar como vc sugeriu e posto aqui se der certo....

Criado 16 de abril de 2013
Ultima resposta 17 de abr. de 2013
Respostas 7
Participantes 4