Mapear dois atributos em uma foreign no Hibernate

10 respostas
Noturno192

tenho um relâcionamento envolvendo três tabelas, cen_ligacao, cen_ligacao_pacote_prospecto e com_pacote_prospecto

CREATE TABLE cen_ligacao(
id serial primary key,
id_usuario int REFERENCES bas_usuario(id),
tempo int not null,
relato varchar
);
CREATE TABLE cen_ligacao_pacote_prospecto(
id_ligacao int,
id_pacote int,
id_prospecto int,
PRIMARY KEY(id_ligacao, id_pacote, id_prospecto),
FOREIGN KEY(id_ligacao) REFERENCES cen_ligacao(id)
);

estou usando hibernate e fazendo essa ligação da seguinte forma

@Table(name = "cen_ligacao")
@Entity
public class Ligacao {
	
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Integer id;
	
	@ManyToOne
	@JoinColumns( {@JoinColumn(name="id_ligacao"),
					@JoinColumn (name = "id_prospecto"), 
					@JoinColumn(name = "id_pacote" )}
	)
	private PacoteProspecto pacoteProspecto;
	
	@ManyToOne
	@JoinColumn(name = "id_usuario")
	private Usuario usuario;
	
	private Integer tempo;
	
	private String relato;
meu pacote prospecto está assim
@Id
	@ManyToOne
	@JoinColumn(name = "id_pacote")
	private Pacote pacote;
	
	@Id
	@ManyToOne
	@JoinColumn(name = "id_prospecto")
	private Prospecto prospecto;

	private Boolean disponivel;

Ao rodar o sistema ocorre o seguinte bug: [color=red]cannot simultaneously fetch multiple bags[/color]

Se alguem puder me ajudar como fazer esse mapeamento de 2 chaves estrangeiras, agradeço desde já.

10 Respostas

Rafael_Guerreiro

Tente algo assim:

@JoinColumns({ @JoinColumn(name = "id_ligacao", referencedColumnName = "id_ligacao"), @JoinColumn(name = "id_prospecto", referencedColumnName = "id_prospecto"), @JoinColumn(name = "id_pacote", referencedColumnName = "id_pacote") })
Ou assim:

@ManyToOne
@JoinColumn(name = "id_ligacao", referencedColumnName = "id")
private PacoteProspecto pacote;
d34d_d3v1l

Rafael Guerreiro:
Tente algo assim:

@JoinColumns({ @JoinColumn(name = "id_ligacao", referencedColumnName = "id_ligacao"), @JoinColumn(name = "id_prospecto", referencedColumnName = "id_prospecto"), @JoinColumn(name = "id_pacote", referencedColumnName = "id_pacote") })
Ou assim:

@ManyToOne @JoinColumn(name = "id_ligacao", referencedColumnName = "id") private PacoteProspecto pacote;

Humm… Mas onde que ele diz que a tabela é “cen_ligacao_pacote_prospecto” ?
Existe essa tabela intermediaria.

Ou ele deve mudar as tabelas dele e colocar o “Prospecto” e “Pacote” como atributo e referenciá-lo direto na tabela ? Assim:

CREATE TABLE cen_ligacao(  
id serial primary key,  
//...
id_pacote int,
id_prospecto int,
FOREIGN KEY (id_pacote,id_prospecto) references com_pacote_prospecto(id_pacote,id_prospecto)
);

?

Rafael_Guerreiro

Não. Se não uma ligação só poderá ter um pacote e um prospecto.

Ele sabe que é a tabela cen_ligacao_pacote_prospecto por que ela está anotada no PacoteProspecto, não está?

d34d_d3v1l

Rafael Guerreiro:
Não. Se não uma ligação só poderá ter um pacote e um prospecto.

Ele sabe que é a tabela cen_ligacao_pacote_prospecto por que ela está anotada no PacoteProspecto, não está?

1 ligação - 1 PacoteProspecto
1 PacoteProspecto - N ligações

Sim, sabe sim!

Rafael_Guerreiro

Tente isso:

@ManyToOne
	@JoinTable(name = "cen_ligacao_pacote_prospecto", joinColumns = { @JoinColumn(name = "id_ligacao", referencedColumnName = "id") }, inverseJoinColumns = {
			@JoinColumn(name = "id_prospecto"), @JoinColumn(name = "id_pacote") })
	private PacoteProspecto pacoteProspecto;

e isso:

@Id  
	@ManyToOne  
	@JoinTable(name = "cen_ligacao_pacote_prospecto", joinColumns = { @JoinColumn(name = "id_pacote", referencedColumnName = "id_pacote") }, inverseJoinColumns = {
			@JoinColumn(name = "id_prospecto"), @JoinColumn(name = "id_ligacao") })
	private Pacote pacote;  
	  
	@Id  
	@ManyToOne  
	@JoinTable(name = "cen_ligacao_pacote_prospecto", joinColumns = { @JoinColumn(name = "id_prospecto", referencedColumnName = "id_prospecto") }, inverseJoinColumns = {
			@JoinColumn(name = "id_pacote"), @JoinColumn(name = "id_ligacao") })
	private Prospecto prospecto;
d34d_d3v1l
Rafael Guerreiro:
e isso:
@Id  
	@ManyToOne  
	@JoinTable(name = "cen_ligacao_pacote_prospecto", joinColumns = { @JoinColumn(name = "id_pacote", referencedColumnName = "id_pacote") }, inverseJoinColumns = {
			@JoinColumn(name = "id_prospecto"), @JoinColumn(name = "id_ligacao") })
	private Pacote pacote;  
	  
	@Id  
	@ManyToOne  
	@JoinTable(name = "cen_ligacao_pacote_prospecto", joinColumns = { @JoinColumn(name = "id_prospecto", referencedColumnName = "id_prospecto") }, inverseJoinColumns = {
			@JoinColumn(name = "id_pacote"), @JoinColumn(name = "id_ligacao") })
	private Prospecto prospecto;

Não entendi essa parte!
A ligação de PacoteProspecto só existe porque eu tenho um outro atributo ali..."Disponivel"...
O relacionamento desses atributos devem ser com as respectivas tabelas. Não tem nada a ver com a ligação

Noturno192

Tentando com:

@ManyToOne @JoinTable(name = "cen_ligacao_pacote_prospecto", joinColumns = { @JoinColumn(name = "id_ligacao", referencedColumnName = "id") }, inverseJoinColumns = { @JoinColumn(name = "id_prospecto"), @JoinColumn(name = "id_pacote") }) private PacoteProspecto pacoteProspecto;

Ocorreu o seguinte erro:
[color=red]Caused by: org.hibernate.AnnotationException: A Foreign key refering br.com.sol7.olimpio.model.entity.comercial.PacoteProspecto from br.com.sol7.olimpio.model.entity.central.callcenter.Ligacao has the wrong number of column. should be 3
at org.hibernate.cfg.annotations.TableBinder.bindFk(TableBinder.java:420)[/color]

Rafael_Guerreiro

Mostrem as duas entidades com os @table

Noturno192
@Table(name = "cen_ligacao")
@Entity
public class Ligacao {
	
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Integer id;
	
	@ManyToOne  
    @JoinTable(name = "cen_ligacao_pacote_prospecto", joinColumns = { @JoinColumn(name = "id_ligacao", referencedColumnName = "id_ligacao") }, inverseJoinColumns = {  
            @JoinColumn(name = "id_prospecto"), @JoinColumn(name = "id_pacote") })  
    private PacoteProspecto pacoteProspecto;  
	
	@ManyToOne
	@JoinColumn(name = "id_usuario")
	private Usuario usuario;
	
	private Integer tempo;
	
	private String relato;
@Table(name = "com_pacote_prospecto")
@Entity
@IdClass(PacoteProspecto.class)
public class PacoteProspecto implements Serializable {

	private static final long serialVersionUID = 1L;

	@Id
	@ManyToOne
	@JoinColumn(name = "id_pacote")
	private Pacote pacote;
	
	@Id
	@ManyToOne
	@JoinColumn(name = "id_prospecto")
	private Prospecto prospecto;

	private Boolean disponivel;
Rafael_Guerreiro
Rafael Guerreiro:
Tente isso:
@ManyToOne
	@JoinTable(name = "cen_ligacao_pacote_prospecto", joinColumns = { @JoinColumn(name = "id_ligacao", referencedColumnName = "id") }, inverseJoinColumns = {
			@JoinColumn(name = "id_prospecto"), @JoinColumn(name = "id_pacote") })
	private PacoteProspecto pacoteProspecto;
e isso:
@Id  
	@ManyToOne  
	@JoinTable(name = "cen_ligacao_pacote_prospecto", joinColumns = { @JoinColumn(name = "id_pacote", referencedColumnName = "id_pacote") }, inverseJoinColumns = {
			@JoinColumn(name = "id_prospecto"), @JoinColumn(name = "id_ligacao") })
	private Pacote pacote;  
	  
	@Id  
	@ManyToOne  
	@JoinTable(name = "cen_ligacao_pacote_prospecto", joinColumns = { @JoinColumn(name = "id_prospecto", referencedColumnName = "id_prospecto") }, inverseJoinColumns = {
			@JoinColumn(name = "id_pacote"), @JoinColumn(name = "id_ligacao") })
	private Prospecto prospecto;
Coloque esses dois blocos...
Criado 22 de março de 2013
Ultima resposta 22 de mar. de 2013
Respostas 10
Participantes 3