Wednesday 16 June 2010

Specificarea relaţiilor dintre entităţile JPA

Există patru tipuri de relaţii între entităţile JPA, şi anume:

Relaţii ``unul cu unul'' (One-to-One)
Relaţii ``unul cu mai mulţi''(One-to-Many)
Relaţii ``mai mulţi cu unul''(Many-to-One)
Relaţii ``mai mulţi cu mai mulţi'' (Many-to-Many)

O relaţie poate fi unidirecţională sau bidirecţională. Într-o relaţie unidirecţională, una şi numai una dintre entităţi conţine un câmp care se referă la cealaltă entitate. Într-o relaţie bidirecţională, fiecare dintre entităţi conţine un câmp care se referă la cealaltă. Direcţia relaţiei dintre două entităţi determină posibilitatea unei interogări (query) de a naviga de la o entitate la cealaltă. Implementarea relaţiilor în contextul de persistenţă, care determină modul în care se fac actualizările în baza de date, se realizează prin adnotarea câmpurilor care se referă la entităţile relaţionate, în funcţie de tipul relaţiei, cu @OneToOne, @ManyToOne@OneToMany, @ManyToMany, @JoinColumn, @JoinTable, etc.

Exemple

@Entity
@Table(name="CURSURI")

@NamedQueries({
@NamedQuery(name="Cursuri.numeTitular",
    query="select o.profesor from Cursuri o " +
          "where o.cursId = :param"),
@NamedQuery(name="Cursuri.studentiInscrisi",
        query="select o.studenti from Cursuri o " +
          "where o.cursId = :param")
})

public class Cursuri implements Serializable{

@Id
@Column(name="CURSID", nullable=false)
private int cursId;

@Column(name="NUME")
private String nume;

//mai multe cursuri la un profesor

@ManyToOne
@JoinColumn(name="PROFESORID",referencedColumnName="PROFESORID")
private Profesori profesor;


//mai multe cursuri la un student, mai multi studenti la un curs
@ManyToMany
@JoinTable(name="STUD_CURS",
       joinColumns=
           @JoinColumn(name="CURSID",referencedColumnName="CURSID"),
       inverseJoinColumns=
           @JoinColumn(name="STUDENTID",referencedColumnName="STUDENTID"))
//name=numele coloanei din tabela STUD_CURS (tabela de join)
//referencedColumnName=numele coloanelor din tabelele CURSURI, respectiv STUDENTI
private List studenti;

...

@Entity
@Table(name="STUDENTI")

@NamedQuery(name="Studenti.note",
    query="select o.note from Studenti o " +
          "where o.studentId = :param")

public class Studenti implements Serializable{

@Id
@Column(name="STUDENTID", nullable=false)
private int studentId;

@Column(name="NUME")
private String nume;

@Column(name="PRENUME")
private String prenume;

@Column(name="EMAIL")
private String email;

@OneToOne
@JoinColumn(name="STUDENTID",referencedColumnName="STUDENTID")
private Note note;

...

@Stateless(name="FatadaCursuri")
public class FatadaCursuriBean implements FatadaCursuri{

@PersistenceContext(unitName="CelestePersistUnit")
EntityManager em;

public String cautaTitular(int id){

Profesori titular = (Profesori)em.createNamedQuery("Cursuri.numeTitular").
            setParameter("param",id).getSingleResult();

return titular.citesteNume();

}

public List cautaStudenti(int idCurs){

List listaStudenti = (List)em.createNamedQuery("Cursuri.studentiInscrisi").setParameter("param",idCurs).getResultList();
return listaStudenti;

}

public Note cautaNote(int idStud){

Note note = (Note)em.createNamedQuery("Studenti.note").
            setParameter("param",idStud).getSingleResult();

return note;

}

public List getGradesforOneStudent(int idStud){
List note = (List)em.createNamedQuery("Grades.forOneStudent").
            setParameter("param",idStud).getResultList();

return note;
}

}

1 comment:

Bogdan Marian said...

Articolul e scurt si la obiect, usor de citit. As sugera mai multe detalii referitor la ce fac atributele anotatiilor utilizate. Nu ar fi rau nici o diagrama cu tabele bazei de date relationare.