Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/ConnectionRecoveryManager.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/ConnectionRecoveryManager.java	(revision 660920)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/ConnectionRecoveryManager.java	Sat May 31 16:24:20 CAT 2008
@@ -74,6 +74,11 @@
     private final String password;
 
     /**
+     * The check valid connection sql statement
+     */
+    private final String checkValidConnectionSql;
+
+    /**
      * The database connection that is managed by this {@link ConnectionRecoveryManager}.
      */
     private Connection connection;
@@ -125,14 +130,16 @@
      * @param url the url to use for the connection
      * @param user the user to use for the connection
      * @param password the password to use for the connection
+     * @param checkValidConnectionSql the sql statement to execute to validate a connection before use
      * @throws RepositoryException if the database driver could not be loaded
      */
-    public ConnectionRecoveryManager(boolean block, String driver, String url, String user, String password) throws RepositoryException {
+    public ConnectionRecoveryManager(boolean block, String driver, String url, String user, String password, String checkValidConnectionSql) throws RepositoryException {
         this.block = block;
         this.driver = driver;
         this.url = url;
         this.user = user;
         this.password = password;
+        this.checkValidConnectionSql = checkValidConnectionSql;
         try {
             setupConnection();
             isClosed = false;
@@ -147,6 +154,9 @@
      * connection has been closed, and autoReconnect==true
      * then an attempt is made to reestablish the connection.
      *
+     * Checks the connection for validity if it is enabled
+     * and autoReconnect==true
+     *
      * @return the database connection that is managed
      * @throws SQLException on error
      * @throws RepositoryException if the database driver could not be loaded
@@ -159,6 +169,7 @@
                 throw new SQLException("connection has been closed and autoReconnect == false");
             }
         }
+        checkConnection();
         return connection;
     }
 
@@ -318,6 +329,34 @@
     }
 
     /**
+     * if autoReconnect==false and checkValidConnectionSql is not empty
+     * the sql statement is executed on the connection, if any exception
+     * is thrown the connection is re-established
+     * @throws SQLException if reconnecting fails
+     */
+    public void checkConnection() throws SQLException, RepositoryException {
+        if (autoReconnect && (isClosed || connection == null)) {
+           reestablishConnection();
+           return;
+        }
+        if (!autoReconnect || checkValidConnectionSql == null || checkValidConnectionSql.trim().length() == 0) {
+            return;
+        }
+        PreparedStatement prep;
+        try {
+           prep = (PreparedStatement) preparedStatements.get(checkValidConnectionSql);
+            if (prep == null) {
+                prep = connection.prepareStatement(checkValidConnectionSql);
+                preparedStatements.put(checkValidConnectionSql, prep);
+            }
+            prep.execute();
+        } catch (SQLException e) {
+            log.warn("check valid connection sql statement failed: " + e.getMessage());
+            reestablishConnection();
+        }
+    }
+
+    /**
      * Creates the database connection.
      *
      * @throws SQLException on error
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleDbPersistenceManager.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleDbPersistenceManager.java	(revision 660920)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleDbPersistenceManager.java	Fri May 30 17:14:10 CAT 2008
@@ -83,6 +83,7 @@
  * <li>&lt;param name="{@link #setUrl(String) url}" value=""/>
  * <li>&lt;param name="{@link #setUser(String) user}" value=""/>
  * <li>&lt;param name="{@link #setPassword(String) password}" value=""/>
+ * <li>&lt;param name="{@link #setCheckValidConnectionSql(String) sql} " value=""/>
  * <li>&lt;param name="{@link #setSchema(String) schema}" value=""/>
  * <li>&lt;param name="{@link #setSchemaObjectPrefix(String) schemaObjectPrefix}" value=""/>
  * <li>&lt;param name="{@link #setErrorHandling(String) errorHandling}" value=""/>
@@ -122,6 +123,9 @@
     /** the jdbc password */
     protected String password;
 
+     /** A SQL statement that executes before a connection is used to make sure it is still valid */
+    protected String checkValidConnectionSql;
+
     /** the schema identifier */
     protected String schema;
 
@@ -262,7 +266,24 @@
         this.driver = driver;
     }
 
-    /**
+     /**
+     * Get the check valid connection sql
+     * @return the sql statement
+     */
+    public String getCheckValidConnectionSql() {
+        return checkValidConnectionSql;
+    }
+
+    /**
+     * Set the check valid connection sql
+     * Example: Select 1
+     * @param checkValidConnectionSql
+     */
+    public void setCheckValidConnectionSql(final String checkValidConnectionSql) {
+        this.checkValidConnectionSql = checkValidConnectionSql;
+    }
+
+    /**
      * Returns the configured schema object prefix.
      * @return the configured schema object prefix.
      */
@@ -520,7 +541,7 @@
             trials--;
             Connection con = null;
             try {
-                con = connectionManager.getConnection();
+                con = connectionManager.getConnection();                  
                 connectionManager.setAutoReconnect(false);
                 con.setAutoCommit(false);
                 super.store(changeLog);
@@ -558,7 +579,7 @@
         this.name = context.getHomeDir().getName();
 
         connectionManager = new ConnectionRecoveryManager(blockOnConnectionLoss,
-                getDriver(), getUrl(), getUser(), getPassword());
+                getDriver(), getUrl(), getUser(), getPassword(), getCheckValidConnectionSql());
 
         // make sure schemaObjectPrefix consists of legal name characters only
         prepareSchemaObjectPrefix();
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/DbDataStore.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/DbDataStore.java	(revision 660920)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/DbDataStore.java	Sat May 31 16:24:09 CAT 2008
@@ -57,6 +57,7 @@
  * <li>&lt;param name="{@link #setUrl(String) url}" value="jdbc:postgresql:test"/>
  * <li>&lt;param name="{@link #setUser(String) user}" value="sa"/>
  * <li>&lt;param name="{@link #setPassword(String) password}" value="sa"/>
+ * <li>&lt;param name="{@link #setCheckValidConnectionSql(String) sql} " value=""/>
  * <li>&lt;param name="{@link #setDatabaseType(String) databaseType}" value="postgresql"/>
  * <li>&lt;param name="{@link #setDriver(String) driver}" value="org.postgresql.Driver"/>
  * <li>&lt;param name="{@link #setMinRecordLength(int) minRecordLength}" value="1024"/>
@@ -122,9 +123,14 @@
     /**
      * The user name.
      */
-    protected String user;
-    
+    protected String user;      
+
     /**
+     * A SQL statement that executes before a connection is used to make sure it is still valid
+     */
+    protected String checkValidConnectionSql;
+    
+    /**
      * The password
      */
     protected String password;
@@ -275,6 +281,7 @@
         TempFileInputStream fileInput = null;
         ConnectionRecoveryManager conn = getConnection();
         try {
+            conn.checkConnection();
             conn.setAutoReconnect(false);
             String id = null, tempId = null;            
             long now;            
@@ -348,12 +355,12 @@
                 }
             }
             usesIdentifier(identifier);
-            DbDataRecord record = new DbDataRecord(this, identifier, length, now);
+            DbDataRecord record = new DbDataRecord(this, identifier, length, now);            
-            conn.setAutoReconnect(true);
             return record;
         } catch (Exception e) {
             throw convert("Can not insert new record", e);
         } finally {
+            conn.setAutoReconnect(true);
             conn.closeSilently(rs);
             putBack(conn);
             if (fileInput != null) {
@@ -747,8 +754,26 @@
     public void setUser(String user) {
         this.user = user;
     }
-    
-    /**
+
+       /**
+     * Get the check valid connection sql
+     * @return the sql statement
+     */
+    public String getCheckValidConnectionSql() {
+        return checkValidConnectionSql;
+    }
+
+    /**
+     * Set the check valid connection sql
+     * Example: Select 1
+     * @param checkValidConnectionSql
+     */
+
+    public void setCheckValidConnectionSql(final String checkValidConnectionSql) {
+        this.checkValidConnectionSql = checkValidConnectionSql;
+    }
+    
+    /**
      * {@inheritDoc}
      */
     public synchronized void close() {
@@ -823,7 +848,7 @@
      * @return the new connection
      */
     public ConnectionRecoveryManager createNewConnection() throws RepositoryException {
-        ConnectionRecoveryManager conn = new ConnectionRecoveryManager(false, driver, url, user, password);
+        ConnectionRecoveryManager conn = new ConnectionRecoveryManager(false, driver, url, user, password, checkValidConnectionSql);
         return conn;
     }
 
