public int bulkUpdateByPrimaryKey( final String entityName, final Map<String, ?> updateValues, final List<Long> keys) { int result = 0; if ((entityName == null) || (updateValues == null) || updateValues.isEmpty() || (keys == null) || keys.isEmpty()) { return 0; } try { final GenericHelper entityHelper = delegatorInterface.getEntityHelper(entityName); final ModelEntity modelEntity = delegatorInterface.getModelEntity(entityName); final List<String> pks = modelEntity.getPkFieldNames(); if (pks.size() != 1) { throw new DataAccessException( "BulkUpdateByPrimaryKey only works for single column keys at this moment."); } final String pkName = pks.get(0); final Updater updater = new Updater( ModelFieldTypeReader.getModelFieldTypeReader(entityHelper.getHelperName()), entityName); final List<Updater.Value> params = new ArrayList<Updater.Value>(); final StringBuilder updateSql = new StringBuilder("UPDATE "); updateSql.append(modelEntity.getTableName(entityHelper.getHelperName())); updateSql.append(" SET "); // generate the update sql for (final Iterator<String> iterator = updateValues.keySet().iterator(); iterator.hasNext(); ) { final String column = iterator.next(); updateSql.append(" "); final ModelField field = modelEntity.getField(column); updateSql.append(field.getColName()); updateSql.append(" = "); params.add(updater.create(field, updateValues.get(column))); updateSql.append("? "); if (iterator.hasNext()) { updateSql.append(", "); } } // generate the where clause updateSql.append(" WHERE "); // batch the update final int batchSize = getQueryBatchSize(); int currentIndex = 0; while (currentIndex < keys.size()) { int i = 0; final StringBuilder idClause = new StringBuilder(); final ArrayList<Long> idParams = new ArrayList<Long>(); for (final Iterator<Long> iterator = keys.subList(currentIndex, keys.size()).iterator(); iterator.hasNext() && (i < batchSize); i++) { final Long key = iterator.next(); idClause.append(" "); idClause.append(pkName); idClause.append(" = "); idParams.add(key); idClause.append("? "); if (iterator.hasNext() && ((i + 1) < batchSize)) { idClause.append(" or "); } } final SQLProcessor processor = new AutoCommitSQLProcessor(entityHelper.getHelperName()); processor.prepareStatement(updateSql.toString() + idClause.toString()); for (final Updater.Value param : params) { param.setValue(processor); } for (final Long idParam : idParams) { processor.setValue(idParam); } try { result = processor.executeUpdate(); } finally { processor.close(); } currentIndex += i; } } catch (final GenericEntityException e) { throw new DataAccessException(e); } catch (final SQLException e) { throw new DataAccessException(e); } catch (final NoClassDefFoundError e) { // under JDK 1.3 unit tests - javax.sql.XADataSource cannot be found. // this shouldn't affect runtime - application servers should ship the jar } return result; }