Newsgroup: it.comp.java
Titolo: Consiglio sul mapping di hibernate

Salve a tutti...
Sto iniziando a lavorare con hibernate e JSF ed ho un piccolo problemino 
che non riesco a risolvere, nel senso che non so proprio come fare... 
credo che sia perchè non sono entrato ancora nell'ottica hibernate al 
100%...
comunque vi spiego il caso:
Ho 3 classi, Dottore, Paziente e Caso
Dottore e Pazienti sono legate fra loro tramite una relazione 
<many-to-many> con una tabella nel DB chiamata Dottori_Pazienti.
Ora mi servirebbe creare il legame tra il dottore il paziente e il 
caso... avevo pensato di usare una tabella Dott_Paz_Casi, o almeno cosi 
avrei fatto senza hibernate, ma non so come creare il mapping nei file 
hbm...
non so se sono stato chiaro... qualcuno sa darmi una mano?
grazie in anticipo :)

 hbm...
Per me sbagli proprio a fare la prima mappatura: i pazienti sono legati ai
dottori proprio tramite i casi. Perchè ti servono due mappature? Per la
seconda mappatura non hai sicuramente difficoltà a creare le many-to-one,
per il resto dipende anche dalle query che poi vorrai farci sopra.

kala ha scritto:

non sbaglio a fare la prima mappatura... i pazienti potrebbero anche non 
avere dei casi per niente ma essere solo presenti in anagrafica e 
collegati al dottore... comunque, tu come li mapperesti allora?
avrei pensato comunque di fare una funzione getCasi nella classe 
Paziente che mi restituisca i casi del paziente per il dottore attivo ma 
non credo che sia la prassi da seguire...
grazie dei consigli :)

 >> hbm...
Una possibilità è una relazione 0:n tra la tabella di relazione
Pazienti-Medici (la cardinalità minima 0 rappresenta il caso di
paziente in anagrafica senza "casi").
In questo caso puoi fare una mappatura per ognuna delle tabelle:
Paziente
Medico
PazienteMedico
Caso
Dunque 4 mappature, considerando la tabella di relazione Pazienti-
Medici un'entità a sé stante. Si tratta ovviamente di un'entità
debole, in cui la chiave primaria è costituita dalle chiavi primarie
del paziente e del medico.
Un consiglio sulle chiavi primarie per un utilizzo più efficiente di
Hibernate: ti suggerisco per la tabella in questione una chiave
primaria surrogata, ovvero una chiave numerica generata
automaticamente dal rDBMS, e poi un vincolo di univocità sulla coppia
di chiavi (PazientePK,MedicoPK).
La tabella dei casi può essere resa come un'entità forte, con un suo
identificativo univoco, con chiave esterna corrispondente alla chiave
primaria della tabella di relazione tra medici e pazienti.
Un'osservazione: la relazione tra pazienti è medici è proprio m:n?
Perché se si tratta del medico di base, allora il medico di base è
univoco per il singolo paziente, e quindi la relazione è 1:n tra
medico e pazienti (cardinalità minima 1, perché il sistema gestisce
legami medico-paziente, per cui se il paziente c'è, ha anche un medico
di base).
Nel caso in cui invece si tratta di una struttura ospedaliera, in cui
si vuole tener traccia di visite e ricoveri, allora la cardinalità tra
tabella di relazione medici-pazienti e tabella dei casi è 1:n (un
paziente è nel sistema perché è oggetto di almeno un caso clinico).
Questa è esperienza personale, perché, pur avendo un medico di base,
finché non ho fatto una visita all'ospedale, all'ospedale non
risultavo, anche se nell'anagrafica dell'ASL risultavo associato al
mio medico di base.
Ciao
Daniele

 mio medico di base.
il medico non è inteso come medico di base, la struttura è una struttura 
ospedaliera e ho pensato di creare una relazione m:n perchè un paziente 
può essere paziente di più dottori... però ora mi hai fatto venire il 
dubbio e rifarò un'analisi dei casi... grazie ancora :)

 dubbio e rifarò un'analisi dei casi... grazie ancora :)
non avere dubbi.
Qualche mese fa ho avuto un problema.
Ero un paziente, ero un caso, mi hanno visitato 27 dottori diversi. ;-{)
E lo stesso e' successo nelle sequele, cavoli amari se le devi tenere 
sotto controllo, altra mappatura poiche' dovrebbe essere lo stesso caso.
--
ac

Alessandro Cara ha scritto:

ho una classe Visita in relazione 1:n con Caso (Caso 1:n Visita) ma non 
prevedo che le visite (e quindi i casi) possano essere effettuate da 
dottori diversi... non mi è stato richiesto :)


Ciao, purtroppo il tempo che ho a disposizione è ridotto al lumino. Ho
pensato un po' alla faccenda e ho pensato ad un dominio così
costituito:
LocalHealthUnit (ASL)
Patient
Doctor
Case
Examination
La ASL contiene pazienti e medici.
Un paziente è in legame 0:n con i casi.
Un caso è in legame 0:n con le visite mediche.
Un medico è in legame 0:n con le visite mediche.
In questo modo hai una flessibilità maggiore e gestisci anche il fatto
che un paziente possa passare sotto più medici.
Ho buttato giù un diagramma delle classi (just for fun: ho usato
ArgoUML come tool) , domani aggiungo qualche indicazione sulla
mappatura con Hibernate.
Nel frattempo, per familiarizzare con Hibernate e le mappature ti
consiglio la sezione iniziale della guida di riferimento, che trovi
assieme alla libreria in un unico file compresso (da scaricare dal
sito di Hibernate). C'è un esempio di una relazione n:m che ti
fornisce indicazioni utili.
Per il momento buona serata
Daniele

Daniele Gagliardi ha scritto:

grazie mille dei consigli... buona serata anche a te :)

Ogni promessa è debito....
Considerala uno spunto di partenza (non ho provato nulla, considerala
una traccia):
Classi:
PAZIENTE
Patient.java
import java.util.Set;
public class Patient {
  private long id;
  private String fiscalCode;
  private Set<Case> cases;
  public LocalHealthUnit asl;
   ....
  public Patient(String code) {
     fiscalCode = code;
  }
  public Set<Case> getCases() {
      return cases;
  }
   .....
}
Doctor.java
import java.util.Set;
public class Doctor {
  private long id;
  private String fiscalCode;
  private String serialNumber;
  private String[] specialization;
...
  public Set<Examination> examinations;
    public LocalHealthUnit asl;
  public Doctor(String code, String sn) {
      fiscalCode = code;
      serialNumber = sn;
  }
  public Set<Examination> getExaminations() {
  return examinations;
  }
...
}
Case.java
import java.util.Set;
public class Case {
  private long id;
 public Patient patient;
  public Set<Examination> examinations;
...
  public Case(long caseId) {
   id = caseId;
  }
  public Set<Examination> getExaminations() {
  return examinations;
  }
  public Patient getPatient() {
  return patient;
  }
...
}
Examination.java
import java.util.Date;
public class Examination {
  private long id;
  private Date date;
  private float cost;
    public Doctor doctor;
    public Case case;
....
  public Examination(long protocol) {
   id = protocol;
  }
  public Doctor getDoctor() {
  return doctor;
  }
  public Case getCase() {
  return case;
  }
....
}
LocalHealthUnit.java
import java.util.Set;
public class LocalHealthUnit {
  private int number;
    public Set<Patient> patients;
    public Set<Doctor> doctors;
  public LocalHealthUnit(int unitNumber) {
     number = unitNumber;
  }
  public Set<Patient> getPatients() {
  return patients;
  }
  public Set<Doctor> getDoctors() {
  return doctors;
  }
}
Mappature:
LocalHealthUnit.hbm.xml
<hibernate-mapping>
    <class name="LocalHealthUnit" table="LOCAL_HEALTH_UNITS">
        <id name="number" type="integer">
            <column name="ID" />
            <generator class="...">
....
            </generator>
        </id>
        <set name="patients" inverse="true">
        	<key>
        		<column name="LHU_ID" not-null="true" />
        	</key>
        	<one-to-many
        		class="Patient" />
        </set>
        <set name="doctors" inverse="true">
        	<key>
        		<column name="DOCTOR_ID" not-null="true" />
        	</key>
        	<one-to-many
        		class="Doctor" />
        </set>
    </class>
</hibernate-mapping>
Patient.hbm.xml
<hibernate-mapping>
    <class name="Patient" table="PATIENTS">
        <id name="number" type="long">
            <column name="PATIENT_ID" />
            <generator class="...">
....
            </generator>
        </id>
       <many-to-one name="asl" class="LocalHealthUnit">
            <column name="LHU_ID" not-null="true" />
        </many-to-one>
        <property name="fiscalCode" type="string">
            <column name="FISCAL_CODE" not-null="true" />
        </property>
        <set name="cases" inverse="true">
        	<key>
        		<column name="PATIENT_ID" not-null="true" />
        	</key>
        	<one-to-many
        		class="Case" />
        </set>
    </class>
</hibernate-mapping>
Doctor.hbm.xml
<hibernate-mapping>
    <class name="Doctor" table="DOCTORS">
        <id name="number" type="long">
            <column name="DOCTOR_ID" />
            <generator class="...">
....
            </generator>
        </id>
       <many-to-one name="asl" class="LocalHealthUnit">
            <column name="LHU_ID" not-null="true" />
        </many-to-one>
        <property name="fiscalCode" type="string">
            <column name="FISCAL_CODE" not-null="true" />
        </property>
        <property name="serialNumber" type="string">
            <column name="SERIAL_NUMBER" not-null="true" />
        </property>
        <set name="examinations" inverse="true">
        	<key>
        		<column name="DOCTOR_ID" not-null="true" />
        	</key>
        	<one-to-many
        		class="Case" />
        </set>
    </class>
</hibernate-mapping>
Case.hbm.xml
<hibernate-mapping>
    <class name="Case" table="CASES">
        <id name="number" type="long">
            <column name="CASE_ID" />
            <generator class="...">
....
            </generator>
        </id>
       <many-to-one name="patient" class="Patient">
            <column name="PATIENT_ID" not-null="true" />
        </many-to-one>
        <set name="examinations" inverse="true">
        	<key>
        		<column name="CASE_ID" not-null="true" />
        	</key>
        	<one-to-many
        		class="Case" />
        </set>
    </class>
</hibernate-mapping>
Examination.hbm.xml
<hibernate-mapping>
    <class name="Examination" table="EXAMINATIONS">
        <id name="number" type="long">
            <column name="CASE_ID" />
            <generator class="...">
....
            </generator>
        </id>
       <many-to-one name="doctor" class="Doctor">
            <column name="DOCTOR_ID" not-null="true" />
        </many-to-one>
       <many-to-one name="case" class="Case">
            <column name="CASE_ID" not-null="true" />
        </many-to-one>
        <property name="date" type="timestamp">
            <column name="EXAMINATION_DATE" not-null="true" />
        </property>
        <property name="cost" type="float">
            <column name="EXAMINATION_COST" not-null="true" />
        </property>
...
    </class>
</hibernate-mapping>
TABELLE
LOCAL_HEALTH_UNITS(ID)
PATIENTS(PATIENTS_ID,LHU_ID,FISCAL_CODE)
DOCTOR(PATIENTS_ID,LHU_ID,FISCAL_CODE,SERIAL_NUMBER)
CASES(CASE_ID,PATIENT_ID)
EXAMINATIONS
(EXAMINATION_ID,CASE_ID,DOCTOR_ID,EXAMINATION_DATE,EXAMINATION_COST)
Ciao
Daniele

 [CUT]
grazie 1000, ora ho diversa roba da cui prendere spunto! :-)