Connect the SQLException getNextException as the cause

This way when we get stack traces like the following, we actually
see the cause:

Exception in thread "main" com.google.gwtorm.client.OrmException: Insert failure: account_groups
        at com.google.gwtorm.jdbc.JdbcAccess.doInsert(JdbcAccess.java:171)
        at com.google.gwtorm.jdbc.JdbcAccess.doInsert(JdbcAccess.java:31)
        at com.google.gwtorm.client.impl.AbstractAccess.insert(AbstractAccess.java:55)
        at com.google.gerrit.server.GerritServer.initSystemConfig(GerritServer.java:193)
        at com.google.gerrit.server.GerritServer.loadSystemConfig(GerritServer.java:343)
        at com.google.gerrit.server.GerritServer.<init>(GerritServer.java:96)
        at com.google.gerrit.server.GerritServer.getInstance(GerritServer.java:78)
        at com.google.gerrit.pgm.CreateSchema.main(CreateSchema.java:28)
Caused by: java.sql.BatchUpdateException: Batch entry 0 INSERT INTO account_groups(name,owner_group_id,description,group_id)VALUES(Administrators,15,Gerrit Site Administrators,15) was aborted. Call getNextException to see the cause.
        at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2537)
        at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1328)
        at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:351)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2674)
        at com.google.gwtorm.jdbc.JdbcAccess.execute(JdbcAccess.java:227)
        at com.google.gwtorm.jdbc.JdbcAccess.doInsert(JdbcAccess.java:166)
        ... 7 more

Signed-off-by: Shawn O. Pearce <sop@google.com>
diff --git a/src/main/java/com/google/gwtorm/jdbc/JdbcAccess.java b/src/main/java/com/google/gwtorm/jdbc/JdbcAccess.java
index 8bb668b..4cc35e5 100644
--- a/src/main/java/com/google/gwtorm/jdbc/JdbcAccess.java
+++ b/src/main/java/com/google/gwtorm/jdbc/JdbcAccess.java
@@ -80,6 +80,7 @@
     try {
       return schema.getConnection().prepareStatement(sql);
     } catch (SQLException e) {
+      linkCause(e);
       throw new OrmException("Prepare failure\n" + sql, e);
     }
   }
@@ -121,6 +122,7 @@
         ps.close();
       }
     } catch (SQLException e) {
+      linkCause(e);
       throw new OrmException("Fetch failure: " + getRelationName(), e);
     }
   }
@@ -145,6 +147,7 @@
         ps.close();
       }
     } catch (SQLException e) {
+      linkCause(e);
       throw new OrmException("Fetch failure: " + getRelationName(), e);
     }
   }
@@ -168,6 +171,7 @@
         ps.close();
       }
     } catch (SQLException e) {
+      linkCause(e);
       throw new OrmException("Insert failure: " + getRelationName(), e);
     }
   }
@@ -191,6 +195,7 @@
         ps.close();
       }
     } catch (SQLException e) {
+      linkCause(e);
       throw new OrmException("Update failure: " + getRelationName(), e);
     }
   }
@@ -214,6 +219,7 @@
         ps.close();
       }
     } catch (SQLException e) {
+      linkCause(e);
       throw new OrmException("Delete failure: " + getRelationName(), e);
     }
   }
@@ -239,6 +245,12 @@
     }
   }
 
+  private static void linkCause(final SQLException e) {
+    if (e.getCause() == null && e.getNextException() != null) {
+      e.initCause(e.getNextException());
+    }
+  }
+
   protected abstract T newEntityInstance();
 
   protected abstract String getRelationName();