From aa7325b24960aa9810399737050af366bfcb2abb Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Mon, 15 Oct 2018 22:12:39 +1300 Subject: [PATCH] #1507 - SqlUpdate.execute PersistenceException is not translated into more specific exception (like DuplicateKeyException) --- .../server/core/PersistRequest.java | 10 +++ .../server/persist/ExeUpdateSql.java | 4 +- .../tests/update/TestSqlUpdateExceptions.java | 72 +++++++++++++++++++ 3 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 src/test/java/org/tests/update/TestSqlUpdateExceptions.java diff --git a/src/main/java/io/ebeaninternal/server/core/PersistRequest.java b/src/main/java/io/ebeaninternal/server/core/PersistRequest.java index 102bfa07d..42b8efae0 100644 --- a/src/main/java/io/ebeaninternal/server/core/PersistRequest.java +++ b/src/main/java/io/ebeaninternal/server/core/PersistRequest.java @@ -8,6 +8,9 @@ import io.ebeaninternal.server.persist.BatchPostExecute; import io.ebeaninternal.server.persist.BatchedSqlException; import io.ebeaninternal.server.persist.PersistExecute; +import javax.persistence.PersistenceException; +import java.sql.SQLException; + /** * Wraps all the objects used to persist a bean. */ @@ -95,6 +98,13 @@ public abstract class PersistRequest extends BeanRequest implements BatchPostExe return transaction.isBatchThisRequest(); } + /** + * Translate the SQLException into a specific exception given the platform. + */ + public PersistenceException translateSqlException(SQLException e) { + return transaction.translate(e.getMessage(), e); + } + /** * Execute the statement. */ diff --git a/src/main/java/io/ebeaninternal/server/persist/ExeUpdateSql.java b/src/main/java/io/ebeaninternal/server/persist/ExeUpdateSql.java index 88879458d..01bacb57b 100644 --- a/src/main/java/io/ebeaninternal/server/persist/ExeUpdateSql.java +++ b/src/main/java/io/ebeaninternal/server/persist/ExeUpdateSql.java @@ -55,8 +55,8 @@ class ExeUpdateSql { request.postExecute(); return rowCount; } - } catch (SQLException ex) { - throw new PersistenceException(ex); + } catch (SQLException e) { + throw request.translateSqlException(e); } finally { if (!batchThisRequest) { diff --git a/src/test/java/org/tests/update/TestSqlUpdateExceptions.java b/src/test/java/org/tests/update/TestSqlUpdateExceptions.java new file mode 100644 index 000000000..20007ce7e --- /dev/null +++ b/src/test/java/org/tests/update/TestSqlUpdateExceptions.java @@ -0,0 +1,72 @@ +package org.tests.update; + +import io.ebean.BaseTestCase; +import io.ebean.DuplicateKeyException; +import io.ebean.Ebean; +import io.ebean.SqlUpdate; +import io.ebean.Transaction; +import org.junit.Test; + +import java.util.UUID; + +public class TestSqlUpdateExceptions extends BaseTestCase { + + private String sql = "insert into uuone (id, name, version) values (?,?,?)"; + + @Test(expected = DuplicateKeyException.class) + public void duplicateKey() { + + UUID id = UUID.randomUUID(); + + SqlUpdate sqlUpdate = Ebean.createSqlUpdate(sql); + sqlUpdate.setParameter(1, id); + sqlUpdate.setParameter(2, "hi"); + sqlUpdate.setParameter(3, 1); + sqlUpdate.execute(); + + sqlUpdate.setParameter(1, id); + sqlUpdate.setParameter(2, "fail"); + sqlUpdate.setParameter(3, 1); + sqlUpdate.execute(); + } + + @Test(expected = DuplicateKeyException.class) + public void duplicateKey_executeNow() { + + + UUID id = UUID.randomUUID(); + + SqlUpdate sqlUpdate = Ebean.createSqlUpdate(sql); + sqlUpdate.setParameter(1, id); + sqlUpdate.setParameter(2, "hi"); + sqlUpdate.setParameter(3, 1); + sqlUpdate.executeNow(); + + sqlUpdate.setParameter(1, id); + sqlUpdate.setParameter(2, "fail"); + sqlUpdate.setParameter(3, 1); + sqlUpdate.executeNow(); + } + + @Test(expected = DuplicateKeyException.class) + public void duplicateKey_inBatch() { + + UUID id = UUID.randomUUID(); + + try (Transaction transaction = Ebean.beginTransaction()) { + + SqlUpdate sqlUpdate = Ebean.createSqlUpdate(sql); + sqlUpdate.setParameter(1, id); + sqlUpdate.setParameter(2, "hi in batch"); + sqlUpdate.setParameter(3, 1); + sqlUpdate.addBatch(); + + sqlUpdate.setParameter(1, id); + sqlUpdate.setParameter(2, "fail in batch"); + sqlUpdate.setParameter(3, 1); + sqlUpdate.addBatch(); + + transaction.commit(); + } + } +}