[infinispan-commits] Infinispan SVN: r2186 - in branches/4.1.x: cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/connectionfactory and 6 other directories.

infinispan-commits at lists.jboss.org infinispan-commits at lists.jboss.org
Tue Aug 10 12:19:31 EDT 2010


Author: mircea.markus
Date: 2010-08-10 12:19:29 -0400 (Tue, 10 Aug 2010)
New Revision: 2186

Added:
   branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/DefaultTwoWayKey2StringMapper.java
   branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/TwoWayKey2StringMapper.java
   branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/stringbased/DefaultTwoWayKey2StringMapperTest.java
   branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/stringbased/NonStringKeyPreloadTest.java
   branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/stringbased/NonStringKeyStateTransferTest.java
   branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/stringbased/TwoWayPersonKey2StringMapper.java
Modified:
   branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/AbstractJdbcCacheStoreConfig.java
   branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/AbstractNonDelegatingJdbcCacheStoreConfig.java
   branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/connectionfactory/PooledConnectionFactory.java
   branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/mixed/JdbcMixedCacheStore.java
   branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/DefaultKey2StringMapper.java
   branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStore.java
   branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStoreConfig.java
   branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/mixed/JdbcMixedCacheStoreConfigTest.java
   branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/mixed/JdbcMixedCacheStoreTest.java
   branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStoreTest.java
   branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStoreTest2.java
   branches/4.1.x/cachestore/jdbc/src/test/resources/log4j.xml
   branches/4.1.x/core/src/main/java/org/infinispan/loaders/LockSupportCacheStore.java
   branches/4.1.x/core/src/main/java/org/infinispan/loaders/LockSupportCacheStoreConfig.java
Log:
[ISPN-579] - implemented JdbcStringBasedCacheStore preloads data using wrong keys (it shouldn't preload)

Modified: branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/AbstractJdbcCacheStoreConfig.java
===================================================================
--- branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/AbstractJdbcCacheStoreConfig.java	2010-08-09 21:16:39 UTC (rev 2185)
+++ branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/AbstractJdbcCacheStoreConfig.java	2010-08-10 16:19:29 UTC (rev 2186)
@@ -67,4 +67,11 @@
       result.connectionFactoryConfig = connectionFactoryConfig.clone();
       return result;
    }
+
+   @Override
+   public String toString() {
+      return "AbstractJdbcCacheStoreConfig{" +
+            "connectionFactoryConfig=" + connectionFactoryConfig +
+            "} " + super.toString();
+   }
 }

Modified: branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/AbstractNonDelegatingJdbcCacheStoreConfig.java
===================================================================
--- branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/AbstractNonDelegatingJdbcCacheStoreConfig.java	2010-08-09 21:16:39 UTC (rev 2185)
+++ branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/AbstractNonDelegatingJdbcCacheStoreConfig.java	2010-08-10 16:19:29 UTC (rev 2186)
@@ -161,4 +161,14 @@
       result.tableManipulation = tableManipulation.clone();
       return result;
    }
+
+   @Override
+   public String toString() {
+      return "AbstractNonDelegatingJdbcCacheStoreConfig{" +
+            "lockConcurrencyLevel=" + lockConcurrencyLevel +
+            ", lockAcquistionTimeout=" + lockAcquistionTimeout +
+            ", tableManipulation=" + tableManipulation +
+            ", manageConnectionFactory=" + manageConnectionFactory +
+            "} " + super.toString();
+   }
 }

Modified: branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/connectionfactory/PooledConnectionFactory.java
===================================================================
--- branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/connectionfactory/PooledConnectionFactory.java	2010-08-09 21:16:39 UTC (rev 2185)
+++ branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/connectionfactory/PooledConnectionFactory.java	2010-08-10 16:19:29 UTC (rev 2186)
@@ -84,7 +84,7 @@
       try {
          DataSources.destroy(pooledDataSource);
          if (log.isTraceEnabled()) {
-            log.debug("Sucessfully stopped PooledConnectionFactory.");
+            log.debug("Successfully stopped PooledConnectionFactory.");
          }
       }
       catch (SQLException sqle) {
@@ -95,16 +95,9 @@
    @Override
    public Connection getConnection() throws CacheLoaderException {
       try {
-         if (log.isTraceEnabled()) {
-            log.trace("DataSource before checkout (NumBusyConnectionsAllUsers) : " + pooledDataSource.getNumBusyConnectionsAllUsers());
-            log.trace("DataSource before checkout (NumConnectionsAllUsers) : " + pooledDataSource.getNumConnectionsAllUsers());
-         }
+         logBefore(true);
          Connection connection = pooledDataSource.getConnection();
-         if (log.isTraceEnabled()) {
-            log.trace("DataSource after checkout (NumBusyConnectionsAllUsers) : " + pooledDataSource.getNumBusyConnectionsAllUsers());
-            log.trace("DataSource after checkout (NumConnectionsAllUsers) : " + pooledDataSource.getNumConnectionsAllUsers());
-            log.trace("Connection checked out: " + connection);
-         }
+         logAfter(connection, true);
          return connection;
       } catch (SQLException e) {
          throw new CacheLoaderException("Failed obtaining connection from PooledDataSource", e);
@@ -113,12 +106,35 @@
 
    @Override
    public void releaseConnection(Connection conn) {
+      logBefore(false);
       JdbcUtil.safeClose(conn);
+      logAfter(conn, false);
    }
 
    public ComboPooledDataSource getPooledDataSource() {
       return pooledDataSource;
    }
 
+   private void logBefore(boolean checkout) {
+      if (log.isTraceEnabled()) {
+         String operation = checkout ? "checkout" : "release";
+         try {
+            log.trace("DataSource before " + operation + " (NumBusyConnectionsAllUsers) : " + pooledDataSource.getNumBusyConnectionsAllUsers() + ", (NumConnectionsAllUsers) : " + pooledDataSource.getNumConnectionsAllUsers());
+         } catch (SQLException e) {                                                                                                                
+            log.warn("Unexpected", e);
+         }
+      }
+   }
 
+   private void logAfter(Connection connection, boolean checkout)  {
+      if (log.isTraceEnabled()) {
+         String operation = checkout ? "checkout" : "release";
+         try {
+            log.trace("DataSource after " + operation + " (NumBusyConnectionsAllUsers) : " + pooledDataSource.getNumBusyConnectionsAllUsers() + ", (NumConnectionsAllUsers) : " + pooledDataSource.getNumConnectionsAllUsers());
+         } catch (SQLException e) {
+            log.warn("Unexpected", e);
+         }
+         log.trace("Connection " + operation + " : " + connection);
+      }
+   }
 }

Modified: branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/mixed/JdbcMixedCacheStore.java
===================================================================
--- branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/mixed/JdbcMixedCacheStore.java	2010-08-09 21:16:39 UTC (rev 2185)
+++ branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/mixed/JdbcMixedCacheStore.java	2010-08-10 16:19:29 UTC (rev 2186)
@@ -33,6 +33,8 @@
 import org.infinispan.loaders.jdbc.connectionfactory.ConnectionFactoryConfig;
 import org.infinispan.loaders.jdbc.stringbased.JdbcStringBasedCacheStore;
 import org.infinispan.marshall.StreamingMarshaller;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
 
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
@@ -66,6 +68,8 @@
 @CacheLoaderMetadata(configurationClass = JdbcMixedCacheStoreConfig.class)
 public class JdbcMixedCacheStore extends AbstractCacheStore {
 
+   private static Log log = LogFactory.getLog(JdbcMixedCacheStore.class);
+
    private JdbcMixedCacheStoreConfig config;
    private JdbcBinaryCacheStore binaryCacheStore = new JdbcBinaryCacheStore();
    private JdbcStringBasedCacheStore stringBasedCacheStore = new JdbcStringBasedCacheStore();
@@ -112,6 +116,10 @@
    public Set<InternalCacheEntry> loadAll() throws CacheLoaderException {
       Set<InternalCacheEntry> fromBuckets = binaryCacheStore.loadAll();
       Set<InternalCacheEntry> fromStrings = stringBasedCacheStore.loadAll();
+      if (log.isTraceEnabled()) {
+         log.trace("Loaded from bucket: " + fromBuckets);
+         log.trace("Loaded from string: " + fromStrings);
+      }
       fromBuckets.addAll(fromStrings);
       return fromBuckets;
    }

Modified: branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/DefaultKey2StringMapper.java
===================================================================
--- branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/DefaultKey2StringMapper.java	2010-08-09 21:16:39 UTC (rev 2185)
+++ branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/DefaultKey2StringMapper.java	2010-08-10 16:19:29 UTC (rev 2186)
@@ -26,23 +26,23 @@
  * primitive wrappers(e.g. Integer, Long etc).
  *
  * @author Mircea.Markus at jboss.com
+ * @deprecated since 4.1 when {@link org.infinispan.loaders.jdbc.stringbased.DefaultTwoWayKey2StringMapper}
+ * which is a replacement this implementation. 
  */
-public class DefaultKey2StringMapper implements Key2StringMapper {
+public class DefaultKey2StringMapper implements TwoWayKey2StringMapper {
 
    /**
     * Returns true if this is an primitive wrapper, false otherwise.
     */
    public boolean isSupportedType(Class key) {
-      return key == String.class ||
-            key == Short.class ||
-            key == Byte.class ||
-            key == Long.class ||
-            key == Integer.class ||
-            key == Double.class ||
-            key == Float.class ||
-            key == Boolean.class;
+      return DefaultTwoWayKey2StringMapper.isPrimitive(key);
    }
 
+   @Override
+   public Object getKeyMapping(String key) {
+      return null;
+   }
+
    /**
     * Returns key.toString. As key being a primitive wrapper, this will ensure that it is unique.
     */
@@ -52,4 +52,5 @@
       }
       return key.toString();
    }
+
 }

Added: branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/DefaultTwoWayKey2StringMapper.java
===================================================================
--- branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/DefaultTwoWayKey2StringMapper.java	                        (rev 0)
+++ branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/DefaultTwoWayKey2StringMapper.java	2010-08-10 16:19:29 UTC (rev 2186)
@@ -0,0 +1,91 @@
+package org.infinispan.loaders.jdbc.stringbased;
+
+/**
+ * Default implementation for {@link org.infinispan.loaders.jdbc.stringbased.TwoWayKey2StringMapper} that knows how to
+ * handle all primitive wrapper keys and Strings.
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 4.1
+ */
+public class DefaultTwoWayKey2StringMapper implements TwoWayKey2StringMapper {
+
+   private static final String STRING_IDENTIFIER = "0";
+   private static final String SHORT_IDENTIFIER = "1";
+   private static final String BYTE_IDENTIFIER = "2";
+   private static final String LONG_IDENTIFIER = "3";
+   private static final String INTEGER_IDENTIFIER = "4";
+   private static final String DOUBLE_IDENTIFIER = "5";
+   private static final String FLOAT_IDENTIFIER = "6";
+   private static final String BOOLEAN_IDENTIFIER = "7";
+
+
+   @Override
+   public String getStringMapping(Object key) {
+      String identifier;
+      if (key.getClass().equals(String.class)) {
+         identifier = STRING_IDENTIFIER;
+      } else if (key.getClass().equals(Short.class)) {
+         identifier = SHORT_IDENTIFIER;
+      } else if (key.getClass().equals(Byte.class)) {
+         identifier = BYTE_IDENTIFIER;
+      } else if (key.getClass().equals(Long.class)) {
+         identifier = LONG_IDENTIFIER;
+      } else if (key.getClass().equals(Integer.class)) {
+         identifier = INTEGER_IDENTIFIER;
+      } else if (key.getClass().equals(Double.class)) {
+         identifier = DOUBLE_IDENTIFIER;
+      } else if (key.getClass().equals(Float.class)) {
+         identifier = FLOAT_IDENTIFIER;
+      } else if (key.getClass().equals(Boolean.class)) {
+         identifier = BOOLEAN_IDENTIFIER;
+      } else {
+         throw new IllegalArgumentException("Unsupported key type: " + key.getClass().getName());
+      } 
+      return generateString(identifier, key.toString());
+   }
+
+   @Override
+   public Object getKeyMapping(String key) {
+      String type = String.valueOf(key.charAt(0));
+      String value = key.substring(1);
+      if (type.equals(STRING_IDENTIFIER)) {
+         return value;
+      } else if (type.equals(SHORT_IDENTIFIER)) {
+         return Short.parseShort(value);
+      } else if (type.equals(BYTE_IDENTIFIER)) {
+         return Byte.parseByte(value);
+      } else if (type.equals(LONG_IDENTIFIER)) {
+         return Long.parseLong(value);
+      } else if (type.equals(INTEGER_IDENTIFIER)) {
+         return Integer.parseInt(value);
+      } else if (type.equals(DOUBLE_IDENTIFIER)) {
+         return Double.parseDouble(value);
+      } else if (type.equals(FLOAT_IDENTIFIER)) {
+         return Float.parseFloat(value);
+      } else if (type.equals(BOOLEAN_IDENTIFIER)) {
+         return Boolean.parseBoolean(value);
+      } else {
+         throw new IllegalArgumentException("Unsupported type code: " + type);
+      }
+   }
+
+   @Override
+   public boolean isSupportedType(Class keyType) {
+      return isPrimitive(keyType);
+   }
+
+   private String generateString(String identifier, String s) {
+      return identifier + s;
+   }
+
+   static boolean isPrimitive(Class key) {
+      return key == String.class ||
+            key == Short.class ||
+            key == Byte.class ||
+            key == Long.class ||
+            key == Integer.class ||
+            key == Double.class ||
+            key == Float.class ||
+            key == Boolean.class;
+   }
+}

Modified: branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStore.java
===================================================================
--- branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStore.java	2010-08-09 21:16:39 UTC (rev 2185)
+++ branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStore.java	2010-08-10 16:19:29 UTC (rev 2186)
@@ -22,6 +22,7 @@
 package org.infinispan.loaders.jdbc.stringbased;
 
 import org.infinispan.Cache;
+import org.infinispan.config.Configuration;
 import org.infinispan.container.entries.InternalCacheEntry;
 import org.infinispan.container.entries.InternalCacheValue;
 import org.infinispan.io.ByteBuffer;
@@ -62,10 +63,20 @@
  * {@link org.infinispan.loaders.jdbc.binary.JdbcBinaryCacheStore}} whenever it is possible, as is has a better performance.
  * One scenario in which this is not possible to use it though, is when you can't write an {@link Key2StringMapper}} to map the
  * keys to to string objects (e.g. when you don't have control over the types of the keys, for whatever reason).
+ * <p/>
+ * <b>Preload</b>.In order to support preload functionality the store needs to read the string keys from the database and transform them
+ * into the corresponding key objects. {@link org.infinispan.loaders.jdbc.stringbased.Key2StringMapper} only supports
+ * key to string transformation(one way); in order to be able to use preload one needs to specify an
+ * {@link org.infinispan.loaders.jdbc.stringbased.TwoWayKey2StringMapper}, which extends {@link org.infinispan.loaders.jdbc.stringbased.Key2StringMapper} and
+ * allows bidirectional transformation.
+ * <p/>
+ * <b>Rehashing</b>. When a node leaves/joins, Infinispan moves around persistent state as part of rehashing process.
+ * For this it needs access to the underlaying key objects, so if distribution is used, the mapper needs to be an
+ * {@link org.infinispan.loaders.jdbc.stringbased.TwoWayKey2StringMapper} otherwise the cache won't start (same constraint as with preloading).
  *
  * @author Mircea.Markus at jboss.com
  * @see Key2StringMapper
- * @see DefaultKey2StringMapper
+ * @see DefaultTwoWayKey2StringMapper
  */
 @CacheLoaderMetadata(configurationClass = JdbcStringBasedCacheStoreConfig.class)
 public class JdbcStringBasedCacheStore extends LockSupportCacheStore {
@@ -95,11 +106,19 @@
       super.start();
       if (config.isManageConnectionFactory()) {
          String connectionFactoryClass = config.getConnectionFactoryConfig().getConnectionFactoryClass();
+         if (log.isTraceEnabled()) log.trace("Using managed connection factory: " + connectionFactoryClass);
          ConnectionFactory connectionFactory = ConnectionFactory.getConnectionFactory(connectionFactoryClass);
          connectionFactory.start(config.getConnectionFactoryConfig());
          doConnectionFactoryInitialization(connectionFactory);
       }
       this.key2StringMapper = config.getKey2StringMapper();
+      if (log.isTraceEnabled()) log.trace("Using key2StringMapper: " + key2StringMapper.getClass().getName());
+      if (isUsingPreload()) {
+         enforceTwoWayMapper("preload");
+      } 
+      if (isDistributed()) {
+         enforceTwoWayMapper("distribution/rehashing");
+      }
       dmHelper = new DataManipulationHelper(connectionFactory, tableManipulation, marshaller) {
 
          @Override
@@ -111,31 +130,34 @@
          public void loadAllProcess(ResultSet rs, Set<InternalCacheEntry> result) throws SQLException, CacheLoaderException {
             InputStream inputStream = rs.getBinaryStream(1);
             InternalCacheValue icv = (InternalCacheValue) JdbcUtil.unmarshall(getMarshaller(), inputStream);
-            Object key = rs.getObject(2);
+            String keyStr = rs.getString(2);
+            Object key = ((TwoWayKey2StringMapper) key2StringMapper).getKeyMapping(keyStr);
             result.add(icv.toInternalCacheEntry(key));
          }
 
          @Override
          public void loadAllKeysProcess(ResultSet rs, Set<Object> keys, Set<Object> keysToExclude) throws SQLException, CacheLoaderException {
-            Object k = rs.getObject(1);
-            if (includeKey(k, keysToExclude)) keys.add(k);
+            String keyStr = rs.getString(1);
+            Object key = ((TwoWayKey2StringMapper) key2StringMapper).getKeyMapping(keyStr);
+            if (includeKey(key, keysToExclude)) {
+               keys.add(key);
+            }
          }
 
          @Override
          public void toStreamProcess(ResultSet rs, InputStream is, ObjectOutput objectOutput) throws CacheLoaderException, SQLException, IOException {
             InternalCacheValue icv = (InternalCacheValue) JdbcUtil.unmarshall(getMarshaller(), is);
-            Object key = rs.getObject(2);
+            String key = rs.getString(2);//key is a string
             marshaller.objectToObjectStream(icv.toInternalCacheEntry(key), objectOutput);
          }
 
          public boolean fromStreamProcess(Object objFromStream, PreparedStatement ps, ObjectInput objectInput) throws SQLException, CacheLoaderException {
             if (objFromStream instanceof InternalCacheEntry) {
                InternalCacheEntry se = (InternalCacheEntry) objFromStream;
-               String key = key2StringMapper.getStringMapping(se.getKey());
                ByteBuffer buffer = JdbcUtil.marshall(getMarshaller(), se.toInternalCacheValue());
                ps.setBinaryStream(1, buffer.getStream(), buffer.getLength());
                ps.setLong(2, se.getExpiryTime());
-               ps.setString(3, key);
+               ps.setString(3, (String) se.getKey());
                return true;
             } else {
                return false;
@@ -148,6 +170,7 @@
    public void stop() throws CacheLoaderException {
       tableManipulation.stop();
       if (config.isManageConnectionFactory()) {
+         if (log.isTraceEnabled()) log.trace("Stopping mananged connection factory: " + connectionFactory);
          connectionFactory.stop();
       }
    }
@@ -260,7 +283,6 @@
       }
    }
 
-
    @Override
    protected InternalCacheEntry loadLockSafe(Object key, String lockingKey) throws CacheLoaderException {
       Connection conn = null;
@@ -296,6 +318,7 @@
       }
    }
 
+
    public Class<? extends CacheLoaderConfig> getConfigurationClass() {
       return JdbcStringBasedCacheStoreConfig.class;
    }
@@ -329,4 +352,23 @@
    public TableManipulation getTableManipulation() {
       return tableManipulation;
    }
+
+   private void enforceTwoWayMapper(String where) throws CacheLoaderException {
+      if (!(key2StringMapper instanceof TwoWayKey2StringMapper)) {
+         String message = "In order for JdbcStringBasedCacheStore to support " + where + ", the Key2StringMapper " +
+               "needs to implement TwoWayKey2StringMapper. You should either make " + key2StringMapper.getClass().getName() +
+               " implement TwoWayKey2StringMapper or disable " + where + ". See [https://jira.jboss.org/browse/ISPN-579] for more details.";
+         log.error(message);
+         throw new CacheLoaderException(message);
+      }
+   }
+
+   public boolean isUsingPreload() {
+      return cache.getConfiguration() != null && cache.getConfiguration().getCacheLoaderManagerConfig() != null &&
+            cache.getConfiguration().getCacheLoaderManagerConfig().isPreload();
+   }
+
+   public boolean isDistributed() {
+      return cache.getConfiguration() != null && cache.getConfiguration().getCacheMode().isDistributed();
+   }
 }

Modified: branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStoreConfig.java
===================================================================
--- branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStoreConfig.java	2010-08-09 21:16:39 UTC (rev 2185)
+++ branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStoreConfig.java	2010-08-10 16:19:29 UTC (rev 2186)
@@ -59,7 +59,7 @@
    public Key2StringMapper getKey2StringMapper() {
       if (key2StringMapper == null) {
          try {
-            key2StringMapper = DefaultKey2StringMapper.class.newInstance();
+            key2StringMapper = DefaultTwoWayKey2StringMapper.class.newInstance();
          } catch (Exception e) {
             throw new IllegalStateException("This should never happen", e);
          }
@@ -68,7 +68,7 @@
    }
 
    /**
-    * Name of the class implementing Key2StringMapper. The default value is {@link org.infinispan.loaders.jdbc.stringbased.DefaultKey2StringMapper}
+    * Name of the class implementing Key2StringMapper. The default value is {@link org.infinispan.loaders.jdbc.stringbased.DefaultTwoWayKey2StringMapper}
     *
     * @see org.infinispan.loaders.jdbc.stringbased.Key2StringMapper
     */
@@ -93,4 +93,11 @@
       result.key2StringMapper = key2StringMapper;
       return result;
    }
+
+   @Override
+   public String toString() {
+      return "JdbcStringBasedCacheStoreConfig{" +
+            "key2StringMapper=" + key2StringMapper +
+            "} " + super.toString();
+   }
 }

Added: branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/TwoWayKey2StringMapper.java
===================================================================
--- branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/TwoWayKey2StringMapper.java	                        (rev 0)
+++ branches/4.1.x/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/TwoWayKey2StringMapper.java	2010-08-10 16:19:29 UTC (rev 2186)
@@ -0,0 +1,16 @@
+package org.infinispan.loaders.jdbc.stringbased;
+
+/**
+ * Extends {@link org.infinispan.loaders.jdbc.stringbased.Key2StringMapper} and allows a bidirectional transformation
+ * between keys and strings. This is needed for supporting preload and rehashing during distribution. See {@link
+ * org.infinispan.loaders.jdbc.stringbased.JdbcStringBasedCacheStore} for more info on these limitations. Following
+ * condition should be satisfied by implementations of this interface:
+ * <p/>
+ * <b>k1.equals(getKeyMapping(getStringMapping(k1)))</b>
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 4.1
+ */
+public interface TwoWayKey2StringMapper extends Key2StringMapper {
+   Object getKeyMapping(String key);
+}

Modified: branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/mixed/JdbcMixedCacheStoreConfigTest.java
===================================================================
--- branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/mixed/JdbcMixedCacheStoreConfigTest.java	2010-08-09 21:16:39 UTC (rev 2185)
+++ branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/mixed/JdbcMixedCacheStoreConfigTest.java	2010-08-10 16:19:29 UTC (rev 2186)
@@ -22,7 +22,7 @@
 package org.infinispan.loaders.jdbc.mixed;
 
 import org.infinispan.loaders.LockSupportCacheStoreConfig;
-import org.infinispan.loaders.jdbc.stringbased.PersonKey2StringMapper;
+import org.infinispan.loaders.jdbc.stringbased.DefaultTwoWayKey2StringMapper;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
@@ -83,8 +83,8 @@
    }
 
    public void testKey2StringMapper() {
-      config.setKey2StringMapperClass(PersonKey2StringMapper.class.getName());
-      assert config.getStringCacheStoreConfig().getKey2StringMapper().getClass().equals(PersonKey2StringMapper.class);
+      config.setKey2StringMapperClass(DefaultTwoWayKey2StringMapper.class.getName());
+      assert config.getStringCacheStoreConfig().getKey2StringMapper().getClass().equals(DefaultTwoWayKey2StringMapper.class);
    }
 
    public void testConcurrencyLevel() {

Modified: branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/mixed/JdbcMixedCacheStoreTest.java
===================================================================
--- branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/mixed/JdbcMixedCacheStoreTest.java	2010-08-09 21:16:39 UTC (rev 2185)
+++ branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/mixed/JdbcMixedCacheStoreTest.java	2010-08-10 16:19:29 UTC (rev 2186)
@@ -32,6 +32,7 @@
 import org.infinispan.loaders.jdbc.connectionfactory.ConnectionFactory;
 import org.infinispan.loaders.jdbc.connectionfactory.ConnectionFactoryConfig;
 import org.infinispan.loaders.jdbc.stringbased.DefaultKey2StringMapper;
+import org.infinispan.loaders.jdbc.stringbased.DefaultTwoWayKey2StringMapper;
 import org.infinispan.loaders.jdbc.stringbased.Person;
 import org.infinispan.marshall.StreamingMarshaller;
 import org.infinispan.marshall.TestObjectStreamMarshaller;
@@ -73,7 +74,7 @@
       JdbcMixedCacheStoreConfig cacheStoreConfig = new JdbcMixedCacheStoreConfig(cfc, binaryTm, stringsTm);
       cacheStoreConfig.setPurgeSynchronously(true);
 
-      cacheStoreConfig.setKey2StringMapperClass(DefaultKey2StringMapper.class.getName());
+      cacheStoreConfig.setKey2StringMapperClass(DefaultTwoWayKey2StringMapper.class.getName());
       cacheStore = new JdbcMixedCacheStore();
       cacheStore.init(cacheStoreConfig, new CacheDelegate("aName"), getMarshaller());
       cacheStore.start();
@@ -140,14 +141,14 @@
       } finally {
          marshaller.finishObjectOutput(oo);
          out.close();
-         cacheStore.clear();         
+         cacheStore.clear();
       }
       assertRowCounts(0, 0);
-      
+
       ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
       ObjectInput oi = marshaller.startObjectInput(in, false);
       try {
-         cacheStore.fromStream(new UnclosableObjectInputStream(oi));         
+         cacheStore.fromStream(new UnclosableObjectInputStream(oi));
       } finally {
          marshaller.finishObjectInput(oi);
          in.close();
@@ -170,7 +171,7 @@
       cacheStore.store(forth);
       assertRowCounts(2, 2);
       Set<InternalCacheEntry> entries = cacheStore.loadAll();
-      assert entries.size() == 4;
+      assert entries.size() == 4 : "Expected 4 and got: " + entries;
       assert entries.contains(first);
       assert entries.contains(second);
       assert entries.contains(third);

Added: branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/stringbased/DefaultTwoWayKey2StringMapperTest.java
===================================================================
--- branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/stringbased/DefaultTwoWayKey2StringMapperTest.java	                        (rev 0)
+++ branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/stringbased/DefaultTwoWayKey2StringMapperTest.java	2010-08-10 16:19:29 UTC (rev 2186)
@@ -0,0 +1,67 @@
+package org.infinispan.loaders.jdbc.stringbased;
+
+import org.testng.annotations.Test;
+
+/**
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 4.1
+ */
+ at Test (groups = "functional", testName = "jdbc.stringbased.DefaultTwoWayKey2StringMapperTest")
+public class DefaultTwoWayKey2StringMapperTest {
+
+   DefaultTwoWayKey2StringMapper mapper = new DefaultTwoWayKey2StringMapper();
+
+   public void testAssumption() {
+      //even if they have the same value, they have a different type
+      assert ! new Float(3.0f).equals(new Integer(3));
+   }
+
+   public void testString() {
+      assert mapper.isSupportedType(String.class);
+      assert assertWorks("");
+      assert assertWorks("mircea");
+   }
+
+   public void testShort() {
+      assert mapper.isSupportedType(Short.class);
+      assert assertWorks((short) 2);
+   }
+
+   public void testByte() {
+      assert mapper.isSupportedType(Byte.class);
+      assert assertWorks((byte) 2);
+   }
+
+   public void testLong() {
+      assert mapper.isSupportedType(Long.class);
+      assert assertWorks(new Long(2));
+   }
+
+   public void testInteger() {
+      assert mapper.isSupportedType(Integer.class);
+      assert assertWorks(2);
+   }
+
+   public void testDouble() {
+      assert mapper.isSupportedType(Double.class);
+      assert assertWorks(2.4d);
+
+   }
+
+   public void testFloat() {
+      assert mapper.isSupportedType(Float.class);
+      assert assertWorks(2.1f);
+
+   }
+
+   public void testBoolean() {
+      assert mapper.isSupportedType(Boolean.class);
+      assert assertWorks(true);
+      assert assertWorks(false);
+   }
+
+   private boolean assertWorks(Object key) {
+      return mapper.getKeyMapping(mapper.getStringMapping(key)).equals(key);
+   }
+}

Modified: branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStoreTest.java
===================================================================
--- branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStoreTest.java	2010-08-09 21:16:39 UTC (rev 2185)
+++ branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStoreTest.java	2010-08-10 16:19:29 UTC (rev 2186)
@@ -44,7 +44,8 @@
       TableManipulation tm = UnitTestDatabaseManager.buildDefaultTableManipulation();
       JdbcStringBasedCacheStoreConfig config = new JdbcStringBasedCacheStoreConfig(connectionFactoryConfig, tm);
       JdbcStringBasedCacheStore stringBasedCacheStore = new JdbcStringBasedCacheStore();
-      stringBasedCacheStore.init(config, new CacheDelegate("aName"), getMarshaller());
+      CacheDelegate cache = new CacheDelegate("aName");
+      stringBasedCacheStore.init(config, cache, getMarshaller());
       stringBasedCacheStore.start();
       return stringBasedCacheStore;
    }

Modified: branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStoreTest2.java
===================================================================
--- branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStoreTest2.java	2010-08-09 21:16:39 UTC (rev 2185)
+++ branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStoreTest2.java	2010-08-10 16:19:29 UTC (rev 2186)
@@ -61,7 +61,7 @@
       tableManipulation = UnitTestDatabaseManager.buildDefaultTableManipulation();
       cfc = UnitTestDatabaseManager.getUniqueConnectionFactoryConfig();
       JdbcStringBasedCacheStoreConfig config = new JdbcStringBasedCacheStoreConfig(cfc, tableManipulation);
-      config.setKey2StringMapperClass(PersonKey2StringMapper.class.getName());
+      config.setKey2StringMapperClass(TwoWayKey2StringMapper.class.getName());
       config.setPurgeSynchronously(true);
       cacheStore = new JdbcStringBasedCacheStore();
       Cache<?, ?> mockCache = EasyMock.createNiceMock(Cache.class);

Added: branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/stringbased/NonStringKeyPreloadTest.java
===================================================================
--- branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/stringbased/NonStringKeyPreloadTest.java	                        (rev 0)
+++ branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/stringbased/NonStringKeyPreloadTest.java	2010-08-10 16:19:29 UTC (rev 2186)
@@ -0,0 +1,147 @@
+package org.infinispan.loaders.jdbc.stringbased;
+
+import org.infinispan.AdvancedCache;
+import org.infinispan.Cache;
+import org.infinispan.CacheException;
+import org.infinispan.config.CacheLoaderManagerConfig;
+import org.infinispan.config.Configuration;
+import org.infinispan.eviction.EvictionStrategy;
+import org.infinispan.loaders.CacheLoaderException;
+import org.infinispan.loaders.jdbc.TableManipulation;
+import org.infinispan.loaders.jdbc.connectionfactory.ConnectionFactory;
+import org.infinispan.loaders.jdbc.connectionfactory.ConnectionFactoryConfig;
+import org.infinispan.loaders.jdbc.connectionfactory.PooledConnectionFactory;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.test.AbstractInfinispanTest;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.infinispan.test.fwk.UnitTestDatabaseManager;
+import org.testng.annotations.Test;
+
+import java.sql.Connection;
+
+import static junit.framework.Assert.assertEquals;
+
+/**
+ * Tester for https://jira.jboss.org/browse/ISPN-579.
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 4.1
+ */
+ at Test(groups = "functional", testName = "loaders.jdbc.stringbased.AbstractInfinispanTest")
+public class NonStringKeyPreloadTest extends AbstractInfinispanTest {
+
+   public void testPreloadWithKey2StringMapper() throws Exception {
+      String mapperName = PersonKey2StringMapper.class.getName();
+      Configuration cfg = createCacheStoreConfig(mapperName, false, true);
+
+      EmbeddedCacheManager cacheManager = TestCacheManagerFactory.createCacheManager(cfg);
+      try {
+         cacheManager.getCache();
+         assert false : " Preload with Key2StringMapper is not supported. Specify an TwoWayKey2StringMapper if you want to support it (or disable preload).";
+      } catch (CacheException ce) {
+         //expected
+      } finally {
+         cacheManager.stop();
+      }
+   }
+
+   public void testPreloadWithTwoWayKey2StringMapper() throws Exception {
+      String mapperName = TwoWayPersonKey2StringMapper.class.getName();
+      Configuration config = createCacheStoreConfig(mapperName, true, true);
+      EmbeddedCacheManager cm = TestCacheManagerFactory.createCacheManager(config);
+      Cache<Object, Object> cache = cm.getCache();
+      Person mircea = new Person("Markus", "Mircea", 30);
+      cache.put(mircea, "me");
+      Person dan = new Person("Dan", "Dude", 30);
+      cache.put(dan, "mate");
+      cache.stop();
+      cm.stop();
+
+      cm = TestCacheManagerFactory.createCacheManager(config);
+      try {
+         cache = cm.getCache();
+         assert cache.containsKey(mircea);
+         assert cache.containsKey(dan);
+      } finally {
+         cache.stop();
+         cm.stop();
+      }
+   }
+   public void testPreloadWithTwoWayKey2StringMapperAndBoundedCache() throws Exception {
+      String mapperName = TwoWayPersonKey2StringMapper.class.getName();
+      Configuration config = createCacheStoreConfig(mapperName, true, true);
+      config.setEvictionStrategy(EvictionStrategy.FIFO);
+      config.setEvictionMaxEntries(3);
+      EmbeddedCacheManager cm = TestCacheManagerFactory.createCacheManager(config);
+      AdvancedCache<Object, Object> cache = cm.getCache().getAdvancedCache();
+      for (int i = 0; i < 10; i++) {
+         Person p = new Person("name" + i, "surname" + i, 30);
+         cache.put(p, "" + i);
+      }
+      cache.stop();
+      cm.stop();
+
+      cm = TestCacheManagerFactory.createCacheManager(config);
+      try {
+         cache = cm.getCache().getAdvancedCache();
+         assertEquals(3, cache.size());
+         int found = 0;
+         for (int i = 0; i < 10; i++) {
+            Person p = new Person("name" + i, "surname" + i, 30);
+            if (cache.getDataContainer().containsKey(p)) {
+               found++;
+            }
+         }
+         assertEquals(3, found);
+      } finally {
+         cache.stop();
+         cm.stop();
+      }
+   }
+
+   static Configuration createCacheStoreConfig(String mapperName, boolean wrap, boolean preload) {
+      ConnectionFactoryConfig connectionFactoryConfig = UnitTestDatabaseManager.getUniqueConnectionFactoryConfig();
+      if (wrap) {
+         connectionFactoryConfig.setConnectionFactoryClass(SharedConnectionFactory.class.getName());
+      }
+      TableManipulation tm = UnitTestDatabaseManager.buildDefaultTableManipulation();
+      JdbcStringBasedCacheStoreConfig csConfig = new JdbcStringBasedCacheStoreConfig(connectionFactoryConfig, tm);
+      csConfig.setFetchPersistentState(true);
+      csConfig.setKey2StringMapperClass(mapperName);
+
+      CacheLoaderManagerConfig cacheLoaders = new CacheLoaderManagerConfig();
+      cacheLoaders.setPreload(preload);
+      cacheLoaders.addCacheLoaderConfig(csConfig);
+      Configuration cfg = TestCacheManagerFactory.getDefaultConfiguration(false);
+      cfg.setCacheLoaderManagerConfig(cacheLoaders);
+      return cfg;
+   }
+
+   public static class SharedConnectionFactory extends ConnectionFactory {
+      static PooledConnectionFactory sharedFactory;
+      static boolean started = false;
+
+      @Override
+      public void start(ConnectionFactoryConfig config) throws CacheLoaderException {
+         if (!started) {
+            sharedFactory = new PooledConnectionFactory();
+            sharedFactory.start(config);
+         }
+      }
+
+      @Override
+      public void stop() {
+         //ignore
+      }
+
+      @Override
+      public Connection getConnection() throws CacheLoaderException {
+         return sharedFactory.getConnection();
+      }
+
+      @Override
+      public void releaseConnection(Connection conn) {
+         sharedFactory.releaseConnection(conn);
+      }
+   }
+}

Added: branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/stringbased/NonStringKeyStateTransferTest.java
===================================================================
--- branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/stringbased/NonStringKeyStateTransferTest.java	                        (rev 0)
+++ branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/stringbased/NonStringKeyStateTransferTest.java	2010-08-10 16:19:29 UTC (rev 2186)
@@ -0,0 +1,84 @@
+package org.infinispan.loaders.jdbc.stringbased;
+
+import org.infinispan.Cache;
+import org.infinispan.config.Configuration;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.test.AbstractCacheTest;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.testng.annotations.Test;
+
+import static junit.framework.Assert.assertEquals;
+
+/**
+ * @author Mircea.Markus at jboss.com
+ * @since 4.1
+ */
+ at Test(groups = "functional", testName = "jdbc.stringbased.NonStringKeyStateTransferTest")
+public class NonStringKeyStateTransferTest extends AbstractCacheTest {
+
+   public void testReplicatedStateTransfer() {
+      EmbeddedCacheManager cm1 = null, cm2 = null;
+      try {
+         Configuration conf = NonStringKeyPreloadTest.createCacheStoreConfig(TwoWayPersonKey2StringMapper.class.getName(), false, true);
+         conf.setCacheMode(Configuration.CacheMode.REPL_SYNC);
+
+         cm1 = TestCacheManagerFactory.createClusteredCacheManager(conf);
+         Cache c1 = cm1.getCache();
+         Person mircea = new Person("markus", "mircea", 30);
+         Person mircea2 = new Person("markus2", "mircea2", 30);
+
+         c1.put(mircea, "mircea");
+         c1.put(mircea2, "mircea2");
+
+         cm2 = TestCacheManagerFactory.createClusteredCacheManager(conf);
+         Cache c2 = cm2.getCache();
+         assertEquals("mircea", c2.get(mircea));
+         assertEquals("mircea2", c2.get(mircea2));
+         c2.get(mircea2);
+      } finally {
+         TestingUtil.killCacheManagers(cm1, cm2);
+      }
+   }
+
+   public void testDistributedStateTransfer() {
+      EmbeddedCacheManager cm1 = null, cm2 = null;
+      try {
+         Configuration conf = NonStringKeyPreloadTest.createCacheStoreConfig(TwoWayPersonKey2StringMapper.class.getName(), false, false);
+         conf.setCacheMode(Configuration.CacheMode.DIST_SYNC);
+
+         cm1 = TestCacheManagerFactory.createClusteredCacheManager(conf);
+         Cache c1 = cm1.getCache();
+
+         for (int i = 0; i < 100; i++) {
+            Person mircea = new Person("markus" +i , "mircea"+i, 30);
+            c1.put(mircea, "mircea"+i);
+         }
+
+         cm2 = TestCacheManagerFactory.createClusteredCacheManager(conf);
+         Cache c2 = cm2.getCache();
+         assert c2.size() > 0;
+         for (Object key: c2.getAdvancedCache().getDataContainer().keySet()) {
+            assert key instanceof Person: "expected key to be person but obtained " + key;
+         }
+         
+      } finally {
+         TestingUtil.killCacheManagers(cm1, cm2);
+      }
+   }
+
+   public void testDistributedAndNoTwoWay() {
+      EmbeddedCacheManager cm1 = null;
+
+      Configuration conf = NonStringKeyPreloadTest.createCacheStoreConfig(TwoWayPersonKey2StringMapper.class.getName(), false, false);
+      conf.setCacheMode(Configuration.CacheMode.DIST_SYNC);
+
+      cm1 = TestCacheManagerFactory.createClusteredCacheManager(conf);
+      try {
+         Cache c1 = cm1.getCache();
+      } finally {
+         TestingUtil.killCacheManagers(cm1);
+      }
+
+   }
+}

Added: branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/stringbased/TwoWayPersonKey2StringMapper.java
===================================================================
--- branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/stringbased/TwoWayPersonKey2StringMapper.java	                        (rev 0)
+++ branches/4.1.x/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/stringbased/TwoWayPersonKey2StringMapper.java	2010-08-10 16:19:29 UTC (rev 2186)
@@ -0,0 +1,20 @@
+package org.infinispan.loaders.jdbc.stringbased;
+
+import java.util.StringTokenizer;
+
+/**
+ * @author Mircea.Markus at jboss.com
+ * @since 4.1
+ */
+public class TwoWayPersonKey2StringMapper extends PersonKey2StringMapper implements TwoWayKey2StringMapper {
+
+   @Override
+   public Object getKeyMapping(String key) {
+      //person.getName() + "_" + person.getSurname() + "_" + person.getAge();
+      StringTokenizer tkz = new StringTokenizer(key, "_");
+      String name = tkz.nextToken();
+      String surname = tkz.nextToken();
+      String age = tkz.nextToken();
+      return new Person(name, surname, Integer.parseInt(age));
+   }
+}

Modified: branches/4.1.x/cachestore/jdbc/src/test/resources/log4j.xml
===================================================================
--- branches/4.1.x/cachestore/jdbc/src/test/resources/log4j.xml	2010-08-09 21:16:39 UTC (rev 2185)
+++ branches/4.1.x/cachestore/jdbc/src/test/resources/log4j.xml	2010-08-10 16:19:29 UTC (rev 2186)
@@ -48,6 +48,14 @@
       <priority value="INFO"/>
    </category>
 
+   <category name="org.infinispan.loaders">
+      <priority value="TRACE"/>
+   </category>
+
+   <category name="org.infinispan.loaders.jdbc.connectionfactory.PooledConnectionFactory">
+      <priority value="WARN"/>
+   </category>
+
    <category name="com.mchange">
       <priority value="TRACE"/>
    </category>

Modified: branches/4.1.x/core/src/main/java/org/infinispan/loaders/LockSupportCacheStore.java
===================================================================
--- branches/4.1.x/core/src/main/java/org/infinispan/loaders/LockSupportCacheStore.java	2010-08-09 21:16:39 UTC (rev 2185)
+++ branches/4.1.x/core/src/main/java/org/infinispan/loaders/LockSupportCacheStore.java	2010-08-10 16:19:29 UTC (rev 2186)
@@ -43,6 +43,10 @@
       super.start();
       if (config == null)
          throw new CacheLoaderException("Null config. Possible reason is not calling super.init(...)");
+      if (log.isTraceEnabled()) {
+         log.trace("Starting cache with config:" + config);
+      }
+
       locks = new StripedLock(config.getLockConcurrencyLevel());
       globalLockTimeoutMillis = config.getLockAcquistionTimeout();
    }

Modified: branches/4.1.x/core/src/main/java/org/infinispan/loaders/LockSupportCacheStoreConfig.java
===================================================================
--- branches/4.1.x/core/src/main/java/org/infinispan/loaders/LockSupportCacheStoreConfig.java	2010-08-09 21:16:39 UTC (rev 2185)
+++ branches/4.1.x/core/src/main/java/org/infinispan/loaders/LockSupportCacheStoreConfig.java	2010-08-10 16:19:29 UTC (rev 2186)
@@ -39,4 +39,12 @@
       testImmutability("lockAcquistionTimeout");
       this.lockAcquistionTimeout = lockAcquistionTimeout;
    }
+
+   @Override
+   public String toString() {
+      return "LockSupportCacheStoreConfig{" +
+            "lockConcurrencyLevel=" + lockConcurrencyLevel +
+            ", lockAcquistionTimeout=" + lockAcquistionTimeout +
+            "} " + super.toString();
+   }
 }



More information about the infinispan-commits mailing list