Open GoogleCodeExporter opened 9 years ago
Original comment by FabioNapoli34
on 23 Nov 2012 at 1:35
Allora. Possiamo seguire questa organizzazione.
1) Rivedere tutte le classi in modo da capire se necessitano di altri metodi.
2) Iniziare ad implementare i metodi ereditati dalla classe DBBeans(in fase di
modifica)
3) Implementare i metodi specifici delle classi.
Ovviamente c'è da fare in primis la javadoc.
Original comment by lomastol...@gmail.com
on 23 Nov 2012 at 1:46
Aspetto News da Giulio e Luigi
Original comment by FabioNapoli34
on 23 Nov 2012 at 3:25
Credo che possiate incominciare. La classe DBBeans ha un interfaccia che credo
sia stabile, ed è documentata in modo, secondo me, abbastanza buono.
Quindi, trasformo questo in un task, e vi do le istruzioni per farlo:
https://groups.google.com/d/topic/at-silo/M34qfJP_6Hc/discussion
Original comment by blunotte...@gmail.com
on 23 Nov 2012 at 4:16
Giulio_Franco: Bisognerebbe modificare i nomi degli attributi delle classi del
package entity. Se ricordi ci sono parecchi nomi che non vanno. Ho trovato
anche userName e passWord... non so se vanno bene.
Original comment by lomastol...@gmail.com
on 24 Nov 2012 at 9:41
I nomi tra database e Java devono coincidere, fatte salve le convenzioni.
In pratica, se hai userName in java, devi avere user_name nel database. Oppure
puoi fare username e username.
Se hai password nel database, devi avere password in Java. Oppure fai pass_word
e passWord.
Original comment by blunotte...@gmail.com
on 24 Nov 2012 at 1:19
Ho completato e committato le mie benedette classi di storage!
Devo solo mettere alcuni set di liste in creaBeans per Genitore e registro
Original comment by ferdi...@gmail.com
on 28 Nov 2012 at 7:04
In merito al problema individuato da Luigi sulle entità deboli:
se la chiave primaria contiene una chiave esterna, inserite nel mapping un
campo fittizio, il cui nome inizia con "-" (es. "-bambino"), e che mappa sulla
colonna di cui avete bisogno (es: "-bambino" -> "Bambino") e inserite questo
campo fittizio anche nella List restituita da getKeyFields.
Infine, sovrascrivete il metodo getAssegnazioni, in modo da restituire
l'Assegnazione corretta per la colonna della chiave primaria.
Original comment by blunotte...@gmail.com
on 28 Nov 2012 at 7:20
Quale è lo status delle classi storage? Avete realizzato le classi JUnit
associate per testare ciò che avete implementato?
Original comment by funfor...@gmail.com
on 30 Nov 2012 at 3:02
Stavamo io e luigi cercando di capire come usare Junit.
Original comment by FabioNapoli34
on 30 Nov 2012 at 3:05
l'implementazioni delle classi test ancora non è iniziata.
Original comment by lomastol...@gmail.com
on 30 Nov 2012 at 3:05
Sto vedendo alcune cose che non vanno nel codice. Le dico in generale, così lo
capiscono tutti.
1) Accesso a variabili null-----------------------------------------
Il seguente codice non va bene:
----------------------BUGGY-JAVA-CODE------------------------------------
Psicopedagogo p = null; //p inizializzato a null
if(r.next()){
p.setNumeroClassi(r.getInt("numero_classi")); //p vale ancora null
-------------------------------------------------------------------------
perché se eseguito, lancerà sicuramente una NullPointerException.
Le variabili vanno sempre inizializzate. La versione corretta del codice è:
----------------------JAVA-CODE------------------------------------------
Psicopedagogo p = new Psicopedagogo(); //p inizializzato
if(r.next()){
p.setNumeroClassi(r.getInt("numero_classi"));
-------------------------------------------------------------------------
2) Database.directQuery--------------------------------------------------
Come è scritto nella documentazione del metodo, "Utilizzare con molta cautela,
solo quando i metodi forniti da Tabella e DBBeans sono insufficienti, e non e'
possibile aggiungervi funzionalità."
Il seguente codice non va bene:
----------------------BUGGY-JAVA-CODE------------------------------------
ResultSet res = tabella.getDatabase().directQuery(
"SELECT * FROM " + tabella.getNomeTabella()
+ "WHERE username =" + user);
-------------------------------------------------------------------------
La colonna username è una stringa. La query, così formattata, verrebbe:
"WHERE username = nomeutente". Invece, dovrebbe essere "WHERE username =
'nomeutente'". Inoltre, eventuali apici singoli e doppi presenti nella stringa
dovrebbero essere sottoposte ad escape.
Per ovviare al problema, la cosa più semplice è utilizzare i metodi messi a
disposizione da Tabella:
----------------------JAVA-CODE------------------------------------------
PreparedStatement stmt = tabella.prepareStatement(
"SELECT * FROM " + tabella.getNomeTabella() + "WHERE username = ?");
tabella.setParam(stmt, 1, "username", user);
ResultSet res = stmt.executeQuery();
-------------------------------------------------------------------------
3) colonne inesistenti---------------------------------------------------
q.setListaGenitori((List<Genitore>)r.getObject("lista_genitori"));
La colonna lista_genitori non esiste da nessuna parte,
in tutta la documentazione del sistema.
-------------------------------------------------------------------------
4) getObject-------------------------------------------------------------
Questo codice non va bene:
----------------------BUGGY-JAVA-CODE------------------------------------
protected Attivita creaBean(ResultSet r) throws SQLException {
Attivita a = new Attivita();
if(r.next())
{
a.setCategoria(r.getString("categoria"));
a.setDescrizione(r.getString("descrizione"));
a.setProgramma_educativo_settimanale(
(ProgrammaEducativoSettimanale)r.getObject("programma_educativo_settimanale"));
//....
-------------------------------------------------------------------------
La documentazione di getObject dice: "Il tipo concreto dell'oggetto Java
restituito sarà il tipo Java predefinito corrispondente al tipo della colonna
SQL".
In questo caso, programma_educativo_settimanale è un ID intero. Quindi,
getObject, restituirà una variabile di tipo Integer, non certo un
ProgrammaEducativoSettimanale bello e fatto (se bastasse fare così, le classi
di storage sarebbero inutili).
La cosa giusta da fare è istanziare un nuovo programma educativo, inserendovi
solo i campi disponibili nella chiave esterna:
----------------------JAVA-CODE------------------------------------------
protected Attivita creaBean(ResultSet r) throws SQLException {
Attivita a = new Attivita();
if(r.next())
{
a.setCategoria(r.getString("categoria"));
a.setDescrizione(r.getString("descrizione"));
a.setProgramma_educativo_settimanale(
new ProgrammaEducativoSettimanale());
a.getProgramma_educativo_settimanale().
setId(r.getInt("programma_educativo_settimanale"));
//....
-------------------------------------------------------------------------
5) Nomi------------------------------------------------------------------
Le variabili e i metodi Java si chiamano con le convenzioni Java.
Le colonne del database si chiamano con le convenzioni del database.
Come descritto nelle convenzioni di codifica, il cui mancato rispetto incide
sulla valutazione finale da parte dei PM.
Se la colonna del database si chiama programma_educativo_settimanale, la
variabile Java deve chiamarsi programmaEducativoSettimanale, ed il metodo
accessore deve chiamarsi
getProgrammaEducativoSettimanale/setProgrammaEducativoSettimanale.
Se i nomi lunghi non vi piacciono, potete pure chiamarli getPES e setPES, per
quanto mi riguarda. L'importante è che la documentazione chiarisca ogni dubbio
e che il nome rispetti le convenzioni.
A questo proposito, dovreste tutti installare in Eclipse il plugin di
validazione che vi ho già indicato:
http://eclipse-cs.sourceforge.net/downloads.html
-------------------------------------------------------------------------
6) Documentazioni assenti------------------------------------------------
C'è gente che deve USARE i vostri metodi. Possibilmente, dovrebbe essere in
grado di farlo SENZA andarsi a leggere il codice. Quindi, dovete documentare i
metodi che implementate in modo esaustivo.
-------------------------------------------------------------------------
6) Documentazioni carenti------------------------------------------------
Questa non è una documentazione sufficiente (però è una delle poche
presenti):
----------------------BUGGY-JAVADOC--------------------------------------
/**
*
* @param user
* @return un account con username=a oppure null
* @throws SQLException
*/
public Account ricercaPerUsername(String user) throws SQLException
-------------------------------------------------------------------------
- Cosa rappresenta la stringa user?? Uno username?
- Che succede se la stringa user è null?
- Che succede se la connessione al database fallisce?
- Che succede se nel database non è presente l'utente indicato?
- Che succede se nel database è presente più di un utente che corrisponde ai
criteri?
- In che circostanze il metodo restituisce un account piuttosto che null?
- In che circostanze viene lanciata una SQLException?
- Come sono avvalorati i campi interni all'Account?
Una versione più esaustiva della documentazione potrebbe essere come segue:
----------------------------JAVADOC--------------------------------------
/**
* Ricerca e restituisce, se presente, un Account il cui username
* corrisponde a quello passato in input.
* @param user Username dell'Account ricercato.
* @return l'unico Account esistente con username==user
* oppure null, se tale Account non esiste.
* L'Account restituito include un'istanza di {@link Utente},
* in cui l'unica proprietà avvalorata e' CodiceFiscale.
* @throws SQLException se si verifica un'eccezione nella comunicazione
* con la base di dati.
*/
public Account ricercaPerUsername(String user) throws SQLException
-------------------------------------------------------------------------
Original comment by blunotte...@gmail.com
on 30 Nov 2012 at 3:45
Per una versione più leggibile, vedete qui:
https://groups.google.com/d/topic/at-silo/ZEtX07nNy-Y/discussion
Original comment by blunotte...@gmail.com
on 30 Nov 2012 at 3:53
Mi sono appena accorto che in atsilo Storage non ci sono implementate, nè
create le relazioni N a N che vengono a crearsi con lo schema Logico
Original comment by FabioNapoli34
on 30 Nov 2012 at 4:28
Le relazione N a N dovrebbero essere state risolte con una tabella di
smistamento.
Sarà compito delle classi che fanno riferimento alla relazione (non quindi
alla tabella di smistamento) prendere le info relative alla tabella nuova.
Spero di essere stata chiara
Original comment by hilin...@gmail.com
on 30 Nov 2012 at 7:34
in alternativa, potete fare un'altra classe derivata di DBBeans e metterla
package protected.
Original comment by blunotte...@gmail.com
on 30 Nov 2012 at 10:13
giulio potresti dircelo in modo piu dettagliato ? :D
Original comment by FabioNapoli34
on 30 Nov 2012 at 10:18
potete fare una classe di pacchetto (senza public) che estende DBBeans e si
lega alla tabella di smistamento. Come bean associato, potreste usare una
classe interna
class DBRelazioneNAN extends DBBeans<DBRelazioneNAN.Relazione> {
static final class Relazione {
private PrimoBean primoBean;
private SecondoBean secondoBean;
//getter e setter di Relazione
}
}
È solo un'altra opzione. Sinceramente, non so quale sia meglio.
Un'altra opzione potrebbe essere quella di inserire una ulteriore Tabella in
uno o entrambi i DB-Manager coinvolti nella relazione.
Original comment by blunotte...@gmail.com
on 30 Nov 2012 at 10:29
[deleted comment]
Dopo una discussione con Luigi , abbiamo pensato di procedere in questo modo
per le cosiddette tabelle di smistamento:
Nel mio esempio abbiamo la relazione Compila tra genitore e questionario
Quindi procederò così:
Creo prima un Bean in atsiloEntity chiamato CompilaQuestionario con i get e i
set,
quest'oggetto conterrà un campo int : idQuestionario( chiave del questionario)
e un campo String : codiceFiscale (chiave del genitore che compila)
Poi in atsiloStorage creo una classe che estende DBBeans chiamata
DBCompilaQuestionario che sarà la tabella del DB che conterrà gli oggetti
CompilaQuestionario
COsa ne pensate?
Original comment by FabioNapoli34
on 1 Dec 2012 at 11:12
secondo me può andare, aspetto però l'intervento di qualcuno più anziano di
me per sarerne un po' di più :-)
Original comment by cesarano...@gmail.com
on 1 Dec 2012 at 12:41
Non dire Anziano potrebbero offendersi :D
Original comment by FabioNapoli34
on 1 Dec 2012 at 12:42
Cosa ho detto l'altro giorno?? Terzo anno della triennale potete programmare,
non serve nessuno più anziano.
Personalmente, non metterei il bean in atsilo.entity, perché non è una vera
entity, ma solo un metadato, quindi propenderei per il metterlo come classe di
pacchetto dentro atsilo.storage. L'idea è che le classi fuori dal pacchetto
storage non hanno bisogno di sapere che questa classe esiste.
Però alla fine non è sbagliato se la mettete in entity.
Original comment by blunotte...@gmail.com
on 1 Dec 2012 at 10:45
Per il testing, vorrei farvi notare che ho creato una classe
test.storage.DBUtil, che contiene un metodo utile per eseguire uno script SQL
sul database.
Questo è utile in associazione al metodo di setUp del test. In pratica, l'idea
è che, prima di ogni metodo di test, resettate il database allo stato
iniziale, in modo da annullare eventuali modifiche (corrette o errate che
siano) apportate dai test precedenti (principio di isolamento dei test).
Per un esempio su come usarlo, potete guardare i metodi setUp e tearDown della
classe test.storage.TestDBBeans, però fate attenzione al fatto che lo script
testDB.sql NON è adatto ai vostri test, perché usa un db di prova giocattolo
con una struttura logica diversa dal db di @silo. Più probabilmente, a voi
interesserà usare "SDD/Dati Persistenti/atsilo popolato.sql".
Original comment by blunotte...@gmail.com
on 1 Dec 2012 at 11:56
Original issue reported on code.google.com by
FabioNapoli34
on 23 Nov 2012 at 1:33