[RESOLVIDO] Hibernate - Problema de mapeamento com chave composta

6 respostas
von.juliano

Boa tarde galera, estou com o seguinte problema:

Tenho as entidades Status, Pedido e StatusPedido:
@Entity
@Table(name = "TB_STATUS")
public class Status {

	@Id
	@Column(name = "CD_STATUS")
	private Integer id;

	@OneToMany(mappedBy = "status")
	@JoinColumn(name="CD_PEDIDO")
	private List<StatusPedido> statusPedidos = new ArrayList<StatusPedido>();
}

@Entity
@Table(name = "TB_PEDIDO")
public class Pedido {

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

	@ManyToOne
	private StatusPedido status;
}

@Entity
@Table(name = "TB_STATUS_PEDIDO")
public class StatusPedido {

	@EmbeddedId
	private StatusPedidoId id;

	@ManyToOne
	@JoinColumn(name = "CD_STATUS")
	private Status status;

	@OneToMany(mappedBy = "status")
	private List<Pedido> pedidos = new ArrayList<Pedido>();
}

// A chave composta de StatusPedido
@Embeddable
public class StatusPedidoId {

	@Column(name = "CD_STATUS")
	private Integer idStatus;

	@Column(name = "CD_PEDIDO")
	private Long idPedido;
}
Status é um-para-muitos com StatusPedido, que é um-para-muitos com Pedido. Devido à chave composta de StatusPedido, estou tendo problemas. Na forma como está, recebo a seguinte exception:
Exception in thread "main" org.hibernate.AnnotationException: A Foreign key refering br.com.xxxx.StatusPedido from br.com.xxxx.Pedido has the wrong number of column. should be 2
	at org.hibernate.cfg.annotations.TableBinder.bindFk(TableBinder.java:276)
	at org.hibernate.cfg.annotations.CollectionBinder.bindCollectionSecondPass(CollectionBinder.java:1322)
	at org.hibernate.cfg.annotations.CollectionBinder.bindOneToManySecondPass(CollectionBinder.java:655)
	at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:587)
	at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:541)
	at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:43)
Alguém sabe a forma correta de fazer esse mapeamento? Obrigado! :thumbup:

6 Respostas

von.juliano

Estudando aqui, vi que posso user a anotação @JoinTable e tornar o relacionamento muitos-para-muitos, indicando a tabela criada por StatusPedido como tabela associativa, mas aí tem outros problemas, pois perco a referência pelo código, e além disso tenho outras colunas nessa tabela.

Alguém tem alguma sugestão? Obrigado! :thumbup:

S

acredito que vc está duplicando o campo CD_STATUS na classe PedidoStatus, já que ele está definido na própria classe e na Pk. Tente colocar:

@ManyToOne  
     @JoinColumn(name = "CD_STATUS")  
     private Status status;

na classe StatusPedidoId e retirar de StatusPedido…

von.juliano

Oi scheide, obrigado pela dica, mas resolvi de outra forma.

Verifiquei que havia um erro no DER que me passaram, assim que ele foi corrigido, StatusPedido passou a ser mesmo uma tabela associativa, e como existem alguns outros atributos nela, ficou assim:

@Entity
@Table(name = "TB_STATUS_PEDIDO")
public class StatusPedido {

	@ManyToOne
	@JoinColumn(name = "CD_STATUS")
	private Status status;

	@ManyToOne
	@JoinColumn(name = "CD_PEDIDO")
	private Pedido pedido;

	// outros 
}
E nas entidades relacionadas foi só mapear o lado fraco.

Obrigado! Flw! :D

S

De nada, sem chave composta fica mais fácil hehe. :slight_smile:

von.juliano
scheide:
De nada, sem chave composta fica mais fácil hehe. :)
Na verdade, eu resolvi e a chave composta permaneceu como mostrei antes, mas no último post eu tinha omitido :mrgreen:
@Entity
@Table(name = "TB_UFN_STATUS_PEDIDO")
public class StatusPedido {

	@EmbeddedId
	private StatusPedidoId id;

	@ManyToOne
	@JoinColumn(name = "CD_STATUS")
	private Status status;

	@ManyToOne
	@JoinColumn(name = "CD_PEDIDO")
	private Pedido pedido;
}
Flw! :thumbup:
S

Ah tá (hehe).
Achei que desse jeito não funcionaria, já que os campos CD_STATUS e CD_PEDIDO estão mapeados 2x, mas se tá funcionando então blz.
[]'s

Criado 17 de março de 2009
Ultima resposta 18 de mar. de 2009
Respostas 6
Participantes 2