JPA - Set que referencia chave composta de três campos

5 respostas
spranta

Pessoal, estou utilizando JPA em um projeto daqui, quando tenho uma classe (Turma por exemplo) que faz um relacionamento com uma outra tabela de ‘n para n’, ou seja, tenho uma associação de chave composto dupla então costumo fazer o seguinte no meu POJO de Turma:

@ManyToMany(cascade={CascadeType.ALL}, fetch=FetchType.LAZY)
    @JoinTable(name="RL_MATERIAL_TURMA",  joinColumns = { 
        @JoinColumn(name="co_seq_turma", unique=false, nullable=false, insertable=true, updatable=false) }, inverseJoinColumns = { 
        @JoinColumn(name="co_seq_material", unique=false, nullable=false, insertable=true, updatable=false) })

    public Set<Material> getMateriais() {
        return this.materiais;
    }

Desta forma, no meu POJO de Turma eu consiguo buscar todos os MATERIAIS associados a ela.

Isto funciona perfeitamente, no entanto, minha necessidade agora está em fazer um relacionamento de turma com uma outra tabela associativa que já possui uma chave composta dupla, gerando portanto uma chave composta com tres chaves primarias (todas elas foreing key), ou seja, de um lado eu tenho minha tabela de Turma com sua chave primaria, de outro lado eu tenho um tabela associativa que reune as chaves de Disciplina e Professor (atraves desta tabela eu consiguo saber para quais disciplinas o professor leciona), e dai eu preciso de ter uma Tabela de relacionamento composta por tres chaves primarias, pois eu preciso saber em uma data turma quais professores dão aula, mas para qual disciplina, entenderam?
Resumindo, preciso em Turma referenciar via JPA uma tabela associativa cuja chave composta possui tres campos, como faço isso?

5 Respostas

AvilaCS

Veja o exemplo:

@Entity
@Table(name = "FORNECEDOR")
public class Fornecedor implements Serializable {

    /**
     * Lista de todas cidades de atuação deste fornecedor
     */
    @ManyToMany
    @JoinTable(
        name="LOCAL_ATUACAO",
        joinColumns= @JoinColumn(name="CD_FORNEC", referencedColumnName="CD_FORNEC"),
        inverseJoinColumns= {
            @JoinColumn(name="CD_PAIS", referencedColumnName="CD_PAIS"), 
            @JoinColumn(name="CD_ESTADO", referencedColumnName="CD_ESTADO"),
            @JoinColumn(name="CD_CIDADE", referencedColumnName="CD_CIDADE")}
    )	
	private Collection<Cidade> cidadesAtuacao;
F

Tipo se você relacionar a Turma com a Disciplina não fica mais facil depois a implementação, porque a partir dessa tabela onde você vai ter a chave composta(Turma, Disciplina) você chega ate Disciplinas e ate o/s Professores que ministram ela… é só uma sugestão

spranta

Frazzato, o problema é que a disciplina pode estar associada a varios professores, ou seja, um professor está apto a coordenar varias disciplinas (relacionamento n x n), dai que uma turma pode ter varios professores, cada um para uma disciplina (n x n), só que eu preciso saber para cada disciplina qual o professor selecionado, visto que em uma dada disciplina eu tenho varios professores a disposição, ou seja, eu preciso dai ter uma tabela com chave composta do id da Turma, da Disciplina e do Professor. Ao meu ver, eu preciso criar uma classe que represente este relacionamento né, ou será possivel representar isso em JPA através de um Set sem criar uma classe, essa é ainda a minha dúvida?
A sugestão do Avila ao meu ver não me atende, visto que a Cidade que ele representou não é uma tabela de relacionamento entre entidades, mas sim uma entidade de dominio mesmo.

R

Pessoal, o eu e o Spranta trabalhamos juntos e ainda não tivemos sucesso na implementação de chave composta com Foreign Key.

Achei um artigo dando um exemplo e "na teoria" parece funcionar, mas a "lei de murf" insiste em prevalecer!!
O erro que está ocorrendo agora é daqueles "fatos inexplicáveis da vida de um programador":

Unknown column 'disciplina_co_seq_disciplina' in 'field list'

O Hibernate deveria montar: disciplina.co_seq_disciplina . Alguém já passou por isso? Como isso pode ocorrer?

Algum filho de DEUS poderia nos ajudar!!

Segue abaixo a nossa implementação:

@Entity
@Table(name = "RL_TURMA_PROF", uniqueConstraints = {})
public class TurmaProfessor implements java.io.Serializable {
	
	@Id
	private TurmaProfessorId id = new TurmaProfessorId();
	
	//bidirectional association
    @SuppressWarnings("unused")
    @Column(name="co_seq_disciplina", nullable=false, updatable=false, insertable=false)
    private Integer disciplina;

    @SuppressWarnings("unused")
    @Column(name="co_seq_professor", nullable=false, updatable=false, insertable=false)
    private Integer professor;

    @SuppressWarnings("unused")
    @Column(name="co_seq_turma", nullable=false, updatable=false, insertable=false)
    private Integer turma;

	public Disciplina getDisciplina() {
		return id.getDisciplina();
	}

	public void setDisciplina(Disciplina disciplina) {
		id.setDisciplina(disciplina);
	}

	public Professor getProfessor() {
		return id.getProfessor();
	}

	public void setProfessor(Professor professor) {
		id.setProfessor(professor);
	}

	public Turma getTurma() {
		return id.getTurma();
	}

	public void setTurma(Turma turma) {
		id.setTurma(turma);
	}


}
@Embeddable
public class TurmaProfessorId implements java.io.Serializable {

	@ManyToOne
	private Professor professor;
	
	@ManyToOne
	private Disciplina disciplina;
	
	@ManyToOne
	private Turma turma;

	public Professor getProfessor() {
		return professor;
	}

	public void setProfessor(Professor professor) {
		this.professor = professor;
	}

	public Disciplina getDisciplina() {
		return disciplina;
	}

	public void setDisciplina(Disciplina disciplina) {
		this.disciplina = disciplina;
	}

	public Turma getTurma() {
		return turma;
	}

	public void setTurma(Turma turma) {
		this.turma = turma;
	}

}
alves.Felipe

Conseguiram resolver isso??
se conseguiram, deem umas dicas ai… estou na mesma situação…

abraco

Criado 7 de novembro de 2007
Ultima resposta 24 de out. de 2008
Respostas 5
Participantes 5