Newsgroup: it.comp.java
Titolo: "trasportare" errore tra strati architettura

sto facendo un progetto che implementa il design pattern Model View 
Controller ed abbia un DataBase Access Object (DAO).
ho uno strato ha funzioni che gestiscono la parte del db e poi salendo 
vi saranno funzioni proxy e facade che permetteranno di disaccoppiare 
l'applicazione dal db.
ora però vorrei che al presentarsi di un errore in operazioni sul db la 
mia applicazione facesse determinate azioni.
poichè il passaggio di valori tra le funzioni di strati adiacenti 
avviene tramite un determinato tipo di dato (definito 
nell'applicazione),un metodo per "trasportare" l'errore potrebbe essere 
quello di associare al valore null di questo tipo oggetto l'avvenimento 
dell'errore?
e quindi quando  tutto è ok l'oggetto passato agli strati superiori sarà 
  diverso da null, ed invece in caso di errore sarà uguale.
che ne dite?
oppure c'è un metodo migliore?

 oppure c'è un metodo migliore?
Si, si chiama gestione delle eccezioni, mai sentito parlare di 
try/catch, throw/throws, Exception e robe simili ?

"iblinku" <NOSPAMM...@genie.itNOSPAMM> ha scritto nel messaggio 
news:34msnuF...@individual.net...

usare le eccezioni...ad esempio:
tipico metodoDAO (esempio di codice con hibernate ma non è importante):
public Area loadById(Long id) throws DataAccessException {
        Session session = 
SessionFactoryUtils.getSession(getSessionFactory(),
                false);
        try {
            return (Area) session.load(Area.class, id);
        } catch (HibernateException e) {
            throw SessionFactoryUtils.convertHibernateAccessException(e);
        }
    }
tipico metodo business:
public Area load(java.lang.Long id) throws ServiceException {
        try {
            return areaDao.loadById(id);
        } catch (DataAccessException ex) {
            throw new ServiceException(ex);
        }
    }
oppure puoi anche assorbirlo, o rilanciare la stessa eccezione, o wrapparlo 
in un eccezione piu significativa...

 tipico metodoDAO (esempio di codice con hibernate ma non è importante):
intanto mi informo a proposito del tuo consiglio.grazie
in ogni caso volevo dire che l'applicazione ha un file che ne definisce 
le funzioni per ogni strato, quindi non saprei in quale strato inserire 
il controllo da te suggeritomi.

"iblinku" <NOSPAMM...@genie.itNOSPAMM> ha scritto nel messaggio 
news:34ndi2F...@individual.net...

non ho capito in che situazioni stai programmando... 

 
un sito web che gestisca un db.
il tutto è fatto con un db in mysql gestito tramite un'interfaccia con 
un Database Access Object.
l'altro "strato applicativo" consiste nella parte che prende i dati e li 
da alle pagine jsp.qui ho creato una specie di "tunnel" per 
disaccoppiare il db dal resto, tramite funzioni tipo proxy e facade,e 
quindi sopra vi è tutta la parte di pagine jsp.
ognuna di queste funzioni l'ho definita in un file a parte (per 
migliorarne la chiarezza), quindi il mio problema sarà "trasportare",nel 
vero senso della parola, l'errore dallo strato db più basso allo strato 
+ alto per permettere di far aprire per esempio una pagina quando c'è 
qualche prob.

 qualche prob.
si ma non capisco perché non andava bene come te lo avevo suggerito 

 
ma non ho detto che nn andasse bene.dato che ho diversi file,non avevo 
capito in quale potevo inserire quel controllo sull'errore

 
ma non ho detto che fosse sbagliata.avendo a che fare con + file non 
sapevo in quale potevo inserire il controllo sull'errore (strato 
db,strato jsp,strato interfaccia,etc...)

"iblinku" <NOSPAMM...@genie.itNOSPAMM> ha scritto nel messaggio 
news:34nu6mF...@individual.net...

secondo me, e secondo quello che faccio io se usi pattern MVC nello strato 
db e superiori  fino alle servlet escluse (e nemmeno nelle jsp). Non nelle 
servlet, almeno non solitamente.
Nelle servlet dovresti finalmente assorbire le eccezioni, con un try catch e 
redirigere alla pagina di errore con un messaggio opportuno. E' possibile a 
dire il vero anche configurare il container in modo che controlli lui le 
eccezioni con la redirezione a una pagina di errore...dipende insomma 
dall'eccezione. 

 
gentilmente potresti spiegarmi come devo fare?!?! :-) grazie mille

"iblinku" <NOSPAMM...@genie.itNOSPAMM> ha scritto nel messaggio 
news:34qgo7F...@individual.net...

...studiati le eccezioni prima!
devi fare una cosa del tipo:
public void functionA() throws MyException {
...
//se si verifica qualche problema
throw new MyExpcetion();
}
public void functionB() {
    try {
        functionA();
    } catch(MyException ex) {
        //si é verificato l'errore..scrivi qua li codice per il controllo 
dell'errore!
    }
}
oppure se functionB non vuole "assoribire" l'eccezione rilanciala!
...hai 2 modi per farlo:
[PRIMO MODO]
public void functionB() throws MyException() {
        functionA();
}
a questo punto una ipotetica funcionC può assorbire l'errore (come descritto 
sopra) oppure rilanciarlo a sua volta...
altro modo consiste sempre nel rilancialre l'eccezione ma con tipo diverso 
(solitamente di piu alto livello):
[SECONDO MODO]
public void functionB() throws MyException2 {
try {
fiunctionA();
} catch(MyException ex) {
    throw new MyException2(ex);
}
}
nel caso delle applicazioni web di solito i DAO lanciano le eccezioni di 
basso livello (SQLException ad esempio). Gli oggetti che usano i dao 
decidono cosa fare...rilanciare l'eccezione con tipo diverso (ad esempio 
ServiceException come a dire il livello soprastante al dao ha avuto un 
problema), oppure catturare l'eccezione e gestirla per conto loro (nel caso 
di SQLException potrebbe esserci poco da gestire in effetti..dovresti 
rilanciare l'eccezione a catturarla all'interno della servlet e nella 
servlet una volta che sai che si é verificato il problema usare un 
dispatcher per mandare alla pagina di errore con relativo messaggio(se 
vuoi).)

 
so usare 1 pò le eccezioni e quello che mi hai detto l'avevo già fatto.
nello strato del db in ogni funzione ho inserito un try-catch.
il mio problema, e forse è perchè nn ho ancora capito bene tutta 
l'architettura,è come far a far "salire" l'eccezione.
quando per esempio una funzione dello strato db va a buon fine ritorna 
un valore che a me servirà nello strato di sopra. pensavo di far tornare 
anche la possibile eccezione così da poterla "portare su", ma mi hai 
detto che nn va bene e quindi nn capisco in quale altro modo possa fare.
nn ho capito bene il modo con cui l'eccezione viene portata allo strato 
superiore, nel tuo metodo con le varie funzioni.

 superiore, nel tuo metodo con le varie funzioni.
ad esempio
public class Dao {
    public Utente loadById(Long id) throws SQLException {
        Connection conn = null;
        ResultSet rs = null;
        PreparedStatment ps = null;
        try {
            ...
            ...
        } catch(SQLException sqle) {
            //chiudi le connessioni e e risorse correlate..rollback se 
necessario
            throw new SQLException(sqle);
        }
    }
}
public class MiaServlet extends HttpServlet {
....processRequest(...) throws ServletException {
       try {
            Dao dao = new Dao();
            Utente utente = dao.loadById(new Long(1));
            request.setAttribute("utente", utente);
        } catch(SQLException sqle) {
            request.setAttribute("message", "errore interno all' 
applicazione");
            request.getRequestDispatcher("/error.jsp").forward(request, 
response);
        }
    }
}
ovviamente é solo un esempio semplificato, (possono esserci altri strati tra 
dao e le servlet), e SQLException potresti rimpiazzarla con una tua 
eccezione anche.