Franzisk wrote:
> I need to know how to show to my user just the message sent from the database
> when persisting, I dont want to the whole stacktrace.
>
> This is my method to save:
> public boolean inserir(T obj) throws HorusDAOException {
> EntityTransaction transaction = this.manager.getTransaction();
> transaction.begin();
> try {
> this.manager.persist(obj);
> transaction.commit();
> } catch (RuntimeException ex) {
> if (transaction.isActive()) {
> try {
> transaction.rollback();
> } catch (RuntimeException e) {
> }
> }
> throw new HorusDAOException("Error saving: "+ex.getMessage());
> } finally {
> manager.close();
> }
> return true;
> }
>
> This is the message sent to View:
> Error saving: Exception [TOPLINK-4002] (Oracle TopLink Essentials - 2.0.1
> (Build b09d-fcs (12/06/2007))):
> oracle.toplink.essentials.exceptions.DatabaseException
> Internal Exception: java.sql.SQLException: Duplicate key or integrity
> constraint violation message from server: "Duplicate entry '115.393.028-57'
> for key 'CPF'"
> Error Code: 1062
> Call: INSERT INTO VENDEDOR (CALCULAR_SOBRE_VALOR_FRETE, OBSERVACAO,
> TELEFONE, LOGRADOURO, CPF, NUMERO, PERCENTUAL_COMISSAO, BAIRRO, NOME,
> CIDADE, RG, ESTADO, EMAIL, COMPLEMENTO, INCLUIR_TAXAS, CEP) VALUES (?, ?, ?,
> ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
> bind => [true, , , , 115.393.028-57, 0, 15.0, , PEDRO, , , SP, , null,
> true, ]
> Query: InsertObjectQuery([ Cadastro de Vendedor ])
>
> I this case I would like to show only this message:
> "Duplicate entry '115.393.028-57' for key 'CPF'"
Since you're catching a RuntimeException, the contents of
ex.getMessage() could be anything at all -- it might have nothing to do
with the database.
To do this, you'd have to start by first determining whether your
RuntimeException is or is caused by the DatabaseException, either by
checking its type or following the chain of getCause()'s.
Once you've determined that it's an exception caused by a DB error, you
don't have much choice but to parse the string returned by getMessage().
Error messages returned by databases differ wildly, and are often
difficult to parse reliably, so this isn't trivial. If you can be
certain that the message always has the structure shown above, you'll
have to parse it for the text after the third semicolon following
"Internal Exception".
Since you're getting a
oracle.toplink.essentials.exceptions.DatabaseException, you could also
call getInternalException(), which would yield the SQLException, and
then return the part of its message that follows the second semicolon.
All of this assumes that you're using Oracle Toplink as the persistence
provider (the default in Glassfish). If you use any other provider, then
the exceptions and messages will almost certainly have a completely
different structure. In that case, it might be a good idea to
encapsulate the code you use to decode the exceptions, so that it hides
the implementation details.
Best,
Geoff
--
Sun Microsystems GmbH Geoffrey Simmons
Nagelsweg 55 Java Architect, Professional Services Delivery
D-20097 Hamburg Tel: +49 (0)40 25 15 23-479
Germany Fax: +49 (0)40 25 15 23-425
http://www.sun.de/ Mob: +49 (0)172 831 7895
mailto: Geoffrey.Simmons_at_sun.com
Sitz der Gesellschaft:
Sun Microsystems GmbH, Sonnenallee 1, D-85551 Kirchheim-Heimstetten
Amtsgericht Muenchen: HRB 16102
Geschaeftsfuehrer: Thomas Schroeder, Wolfgang Engels, Dr. Roland Boemer
Vorsitzender des Aufsichtsrates: Martin Haering