Para iniciar, vamos definir o modelo de dados relacional através de um diagrama entidade-relacionamento (figura abaixo).

Para melhor visualização clique na imagem
Através do diagrama entidade-relacionamento acima, podemos extrair alguns casos a serem mapeados.
- Herança – Entidades envolvidas: aluno, professor, pessoa;
- N : M sem atributos intermediários – Entidades envolvidas: disciplina_professor, professor, disciplina;
- 1 : N – Entidades envolvidas: turma, aluno;
- N : M com atributo intermediário – Entidades envolvidas: professor_turma, turma, professor.
Mapeamento de Pessoa:
import static javax.persistence.GenerationType.IDENTITY; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.Table; @SuppressWarnings("serial") @Entity @Table(name = "pessoa", catalog = "mapeamentohibernate") @Inheritance(strategy = InheritanceType.JOINED) public class Pessoa implements Serializable { @Id @GeneratedValue(strategy = IDENTITY) @Column(name = "id", unique = true, nullable = false) private Integer id; @Column(name = "nome") private String nome; // getters e setters omitidos }
Mapeamento de Aluno:
import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.Table; @SuppressWarnings("serial") @Entity @Table(name = "aluno", catalog = "mapeamentohibernate") @PrimaryKeyJoinColumn(name = "id") // id da tabela aluno public class Aluno extends Pessoa implements Serializable { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "idturma") private Turma turma; @Column(name = "matricula") private String matricula; // getters e setters omitidos }
Mapeamento de Professor:
import java.io.Serializable; import java.util.HashSet; import java.util.Set; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.OneToMany; import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.Table; @SuppressWarnings("serial") @Entity @Table(name = "professor", catalog = "mapeamentohibernate") @PrimaryKeyJoinColumn(name = "id") // id da tabela professor public class Professor extends Pessoa implements Serializable { @Column(name = "formacao") private String formacao; @OneToMany(fetch = FetchType.LAZY, mappedBy = "professor") private Set<ProfessorTurma> professorTurma = new HashSet<ProfessorTurma>(0); @ManyToMany(fetch = FetchType.LAZY) @JoinTable(name = "disciplina_professor", catalog = "mapeamentohibernate", joinColumns = { @JoinColumn(name = "idprofessor", nullable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name = "iddisciplina", nullable = false, updatable = false) }) private Set<Disciplina> disciplinas = new HashSet<Disciplina>(0); // getters e setters omitidos }
Mapeamento de Disciplina:
import static javax.persistence.GenerationType.IDENTITY; import java.io.Serializable; import java.util.HashSet; import java.util.Set; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.Table; @SuppressWarnings("serial") @Entity @Table(name = "disciplina", catalog = "mapeamentohibernate") public class Disciplina implements Serializable { @Id @GeneratedValue(strategy = IDENTITY) @Column(name = "id", unique = true, nullable = false) private Integer id; @Column(name = "nome") private String nome; @ManyToMany(fetch = FetchType.LAZY) @JoinTable(name = "disciplina_professor", catalog = "mapeamentohibernate", joinColumns = { @JoinColumn(name = "iddisciplina", nullable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name = "idprofessor", nullable = false, updatable = false) }) private Set<Professor> professores = new HashSet<Professor>(0); // getters e setters omitidos }
Mapeamento de Turma:
import static javax.persistence.GenerationType.IDENTITY; import java.io.Serializable; import java.util.HashSet; import java.util.Set; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; @SuppressWarnings("serial") @Entity @Table(name = "turma", catalog = "mapeamentohibernate") public class Turma implements Serializable { @Id @GeneratedValue(strategy = IDENTITY) @Column(name = "id", unique = true, nullable = false) private Integer id; @Column(name = "descricao") private String descricao; @OneToMany(fetch = FetchType.LAZY, mappedBy = "turma") private Set<ProfessorTurma> professorTurma = new HashSet<ProfessorTurma>(0); @OneToMany(fetch = FetchType.LAZY, mappedBy = "turma") private Set<Aluno> alunos = new HashSet<Aluno>(0); // getters e setters omitidos }
Mapeamento de ProfessorTurma:
import java.io.Serializable; import java.util.Date; import javax.persistence.AttributeOverride; import javax.persistence.AttributeOverrides; import javax.persistence.Column; import javax.persistence.Embeddable; import javax.persistence.EmbeddedId; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; @SuppressWarnings("serial") @Entity @Table(name = "professor_turma", catalog = "mapeamentohibernate") public class ProfessorTurma implements Serializable { @EmbeddedId @AttributeOverrides( { @AttributeOverride(name = "idturma", column = @Column(name = "idturma", nullable = false)), @AttributeOverride(name = "idprofessor", column = @Column(name = "idprofessor", nullable = false)) }) private Id id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "idturma", nullable = false, insertable = false, updatable = false) private Turma turma; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "idprofessor", nullable = false, insertable = false, updatable = false) private Professor professor; @Temporal(TemporalType.TIMESTAMP) @Column(name = "horario", length = 19) private Date horario; // getters e setters omitidos //Id da associacao (chave composta no banco) @Embeddable public static class Id implements Serializable { @Column(name = "idTurma", nullable = false) private Integer idTurma; @Column(name = "idProfessor", nullable = false) private Integer idProfessor; public Integer getIdTurma() { return this.idTurma; } public void setIdTurma(Integer idturma) { this.idTurma = idturma; } public Integer getIdProfessor() { return this.idProfessor; } public void setIdProfessor(Integer idprofessor) { this.idProfessor = idprofessor; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + idProfessor; result = prime * result + idTurma; return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Id other = (Id) obj; if (idProfessor != other.idProfessor) return false; if (idTurma != other.idTurma) return false; return true; } } }
Note que, no caso N:M que não tem atributo intermediário (tabela disciplina_professor) , não há necessidade de uma classe para representar a associação. No caso em que há atributos intermediários, como o da tabela professor_turma, temos que criar uma classe para representar a associação (classe ProfessorTurma).
O banco de dados utilizado no exemplo foi o MySQL. Quem quiser fazer o download do script do banco basta acessar o link:
http://sites.google.com/site/csscode/Home/mapeamentohibernate.sql
Uma dica para quem não tem muita familiaridade com o mapeamento objeto-relacional é usar o hibernate tools. O hibernate tools trata-se de um plugin do eclipse que auxilia na árdua e massante tarefa de mapear. Vale a pena conferir!!!
Thiago Baesso Procaci