Tenho aqui um método no qual gostaria de fazer dentro dele o tratamento para uma possível excessão apenas em um caso específico. Caso a excessão não se enquadre na condição que eu gostaria de passar, eu gostaria que o tratamento da mesma fosse delegado para a origem da chamada do método.
Isso é possível? Como eu Faço?
Segue um exemplo:
private void save3dHeader(){
try {
Database.getConnection().createStatement().execute("insert into header_3d "
+ "values ((select nvl(max(header_id)+1,0) from header_3d), "
+ "1, "
+ "0, "
+ "'Integer 4-Byte', "
+ "0, "
+ "'Integer 4-Byte')");
} catch (SQLException ex) {
if (ex.getErrorCode() == 1) {
// TRATAR A EXCESSAO AQUI
} else {
// DELEGAR O TRATAMENTO DA EXCESSAO PARA A ORIGEM DA CHAMADA
}
}
}
catch (SQLException ex) {
if (ex.getErrorCode() == 1) {
// TRATAR A EXCESSAO AQUI
} else {
// DELEGAR O TRATAMENTO DA EXCESSAO PARA A ORIGEM DA CHAMADA
throw ex;
}
}
Você quer tratar justamente uma SQLException ?
Normalmente é lançada uma RuntimeException quando ela ocorre, devido ao fato de que há n fatores que pode implicar nessa exceção.
Observe que há uma subsconsulta no insert para que o ID do registro inserido seja um número acima do último ID da tabela.
Entretanto, se em algum lugar alguém tiver feito esse insert e mesmo que por décimos de segundos o commit ficar pendente, quando o commit acontecer, meu insert tentará repetir uma chave primária gerando uma SQLException. A ideia seria repetir a tentativa caso isso ocorra.
Nesse caso a sugestão do Humberto parece resolver meu problema.
private void save3dHeader(){
try {
Database.getConnection().createStatement().execute("insert into header_3d "
+ "values ((select nvl(max(header_id)+1,0) from header_3d), "
+ "1, "
+ "0, "
+ "'Integer 4-Byte', "
+ "0, "
+ "'Integer 4-Byte')");
} catch (SQLException ex) {
if (ex.getErrorCode() == 1) {
// TRATAR A EXCESSAO AQUI
} else {
// DELEGAR O TRATAMENTO DA EXCESSAO PARA A ORIGEM DA CHAMADA
}
}
}
Obrigado![/quote]
A forma geral que vc sempre pode usar é assim (padrão Exception Handler)
private void save3dHeader(){
try {
Database.getConnection().createStatement().execute("insert into header_3d "
+ "values ((select nvl(max(header_id)+1,0) from header_3d), "
+ "1, "
+ "0, "
+ "'Integer 4-Byte', "
+ "0, "
+ "'Integer 4-Byte')");
} catch (Exception ex) {
throw handleException(ex);
}
}
private DataAccessException handleException(Exception e){
if (e instanceof SQLException){
if (ex.getErrorCode() == 1) {
return ExcecaoQueSignificaQueEsteCodigoAconteceu(e);
}
}
// outros ifs
return new DataAccessException (e);
}
Se vc além de detactar vc precisa fazer alguma coisa real , por exemplo fazer query de outra forma vc faria assim (pode fazer como humberto.lima falou também. Esta opção aqui é mais geral e vc pode usar mesmo quando não é um SQLException)
private void save3dHeader(){
try {
Database.getConnection().createStatement().execute("insert into header_3d "
+ "values ((select nvl(max(header_id)+1,0) from header_3d), "
+ "1, "
+ "0, "
+ "'Integer 4-Byte', "
+ "0, "
+ "'Integer 4-Byte')");
} catch (Exception ex) {
DataAccessException e = handleException(ex);
if (e instanceof ExcecaoQueSignificaQueEsteCodigoAconteceu){
// faz a query de outra forma
} else {
throw e;
}
}
}
Assim vc separa a detecção da exceção e o tratamento da exceção. Em outros métodos da mesma classe vc usaria o mesmo handleException que iria detectar o mesmo problema caso ocorra, mas nem sempre vc que dar um tratamento especifico.