Newsgroup: it.comp.java
Titolo: JPA semplice relazione

Ciao a tutti,
non riesco a risolvere banalissimo.
Ipotizziamo di avere due tabelle
Tab1 e Tab2
la Tab1 è in relazione 1:1 con la Tab2 attraverso un campo con lo
stesso nome "codcli".
Non riesco ad inserire la relazione corretta @OneToOne (spero che sia
giusta)
Questa relazione deve funzionare solo con SELECT, se aggiungo,
modifico, elimino record da Tab1 non deve modificarsi nulla nella Tab2
Forse non si può tramite l'annotazione e quindi devo usare la sintassi
SQL standard ?
Grazie
Biagio

 elimino record da Tab1 non deve modificarsi nulla nella Tab2
[Tab1Class]
@OneToOne
@JoinColumn(name="codcli", unique=true, nullable=false, updatable=false)
public Tab2Class getTab2Class() 
{
...
[Tab2Class]
@OneToOne(mappedBy="tab2Class")
public Tab1Class getTab1Class() 
{
...
ti vorrei far notare però che le relazioni dovrebbero essere per chiave 
primaria, non per due campi qualsiasi (seppur univoci). tipicamente fra 
gli esempi one-to-one trovi il classico cliente -> dettaglio-cliente. se 
non ricadi in un caso simile il one-to-one non è il tuo caso.


Grazie rootkit la query funziona benissimo. Ho solo un problema che
molto probabilmente deriva dalla mia pesante inesperienza.
La query con le due tabelle in relazione la uso per popolare una
JTable.
Per costruire il tablemodel ho creato una classe ereditata dalla
AbstractTableModel. Devendo gestire molte tabelle, volevo evitare di
scrivere del codice ripetitivo ed usare del codice dinamico,
richiamando i metodi getXXXX  attraverso la reflection con questo
codice:
public class JPATableModel<T> extends AbstractTableModel {
    public JPATableModel(List<T> list, Class class1) {
        data = list;
        cl = class1;
    }
    public void setColumns(Vector v) {
        colonne = v;
    }
..... Altri metodi ....
public Object getValueAt(int row, int col) {
        try {
            tabella = cl.cast(data.get(row));
            String colonna = colonne.get(col).toString().split(":")
[1];
            Method m = tabella.getClass().getMethod(colonna);
            return m.invoke(tabella);
        } catch (IllegalAccessException ex) {
 
Logger.getLogger(JPATableModel.class.getName()).log(Level.SEVERE,
null, ex);
        } catch (IllegalArgumentException ex) {
 
Logger.getLogger(JPATableModel.class.getName()).log(Level.SEVERE,
null, ex);
        } catch (InvocationTargetException ex) {
 
Logger.getLogger(JPATableModel.class.getName()).log(Level.SEVERE,
null, ex);
        } catch (NoSuchMethodException ex) {
 
Logger.getLogger(JPATableModel.class.getName()).log(Level.SEVERE,
null, ex);
        } catch (SecurityException ex) {
 
Logger.getLogger(JPATableModel.class.getName()).log(Level.SEVERE,
null, ex);
        }
        return null;
    }
nel vettore colonne ho la riga (nomecampo:nomemetodo).
Quando visualizzo la JTable è perfetta.
La Jtable è contenuta in una JDialog che ospita anche i JButton
"Nuovo" e "Modifica".
Quando modifico un record (apro una seconda JDialog alla quale passo
il riferimento della row selezionata), modifico il record e dopo aver
salvato (em.merge) rileggo il database per aggiornare la JTable.
Funziona tutto bene per la prima modifica, se modifico nuovamente lo
stesso record mi appare un errore
28-mar-2010 14.11.55 notapplib1.JPATableModel getValueAt
GRAVE: null
java.lang.reflect.InvocationTargetException
        at sun.reflect.GeneratedMethodAccessor8.invoke(Unknown Source)
Non capisco perché questo errore si verifica dopo la seconda modifica
del record. Eppure se controllo il database con un client esterno vedo
che la tabella per ogni em.merge viene correttamente aggiornata.
Quindi il commit esegue la modifica.
Infatti, se chiudo l'applicazioe e la riapro, la Jtable mi mostra il
record modificato correttamente.
Spero di essere stato chiaro, anche se capisco che non postando tutto
il codice non è cosa semplice.
Grazie
Biagio


Ho notato una cosa.
Quando la JTable non è aggiornata correttamente se chiudo la JDialog e
la riapro il problema rimane.
Aspetto pochi secondi, chiudo e riapro nuovamente ed il problema
scompare.
Sembra quasi che sia dovuto ad un effetto ritardato. Devo forzare
l'aggiornamento di qualcosa prima di ricreare il TableModel, ma non so
cosa.
Grazie
Biagio


RISOLTO !!!!!
Il problema non era il mio codice ma il provider della persistenza
eclipelink.
Ho cambiato il provider passando a Hybernate e lo stesso codice
funziona alla perfezione.
Per chi dovesse avvicinarsi a Hybernate (ho perso un'intera giornata
sbattendo la testa) se vi da errore con em.persist(vostratable) .....
usate pure em.merge(vostratable). ;-)