New to Spring, I am trying to insert a List<Map<String, Object>>
into a table. Until now I have been using the SqlParameterSource
for batch update, which works fine when a java bean is supplied to them. Something like this:
@Autowired private NamedParameterJDBCTemplate v2_template; public int[] bulkInsertIntoSiteTable(List<SiteBean> list){ SqlParameterSource[] batch = SqlParameterSourceUtils .createBatch(list.toArray()); int[] updateCounts = v2_template .batchUpdate( "insert into sitestatus (website, status, createdby) values (:website, :status, :username)", batch); return updateCounts; }
However, I tried the same technique with a list of maps in place of a bean, it failed (rightly so).
public int[] bulkInsertIntoSiteTable(List<Map<String, Object>> list){ SqlParameterSource[] batch = SqlParameterSourceUtils .createBatch(list.toArray()); int[] updateCounts = v2_template .batchUpdate( "insert into sitestatus (website, status, createdby) values (:website, :status, :username)", batch); return updateCounts; }
The above code failed with the following exception:
Exception in thread "main" org.springframework.dao.InvalidDataAccessApiUsageException: No value supplied for the SQL parameter 'website': Invalid property 'website' of bean class [org.springframework.util.LinkedCaseInsensitiveMap]: Bean property 'website' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter? at org.springframework.jdbc.core.namedparam.NamedParameterUtils.buildValueArray(NamedParameterUtils.java:322) at org.springframework.jdbc.core.namedparam.NamedParameterBatchUpdateUtils$1.setValues(NamedParameterBatchUpdateUtils.java:45) at org.springframework.jdbc.core.JdbcTemplate$4.doInPreparedStatement(JdbcTemplate.java:893) at org.springframework.jdbc.core.JdbcTemplate$4.doInPreparedStatement(JdbcTemplate.java:1) at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:587) at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:615) at org.springframework.jdbc.core.JdbcTemplate.batchUpdate(JdbcTemplate.java:884) at org.springframework.jdbc.core.namedparam.NamedParameterBatchUpdateUtils.executeBatchUpdateWithNamedParameters(NamedParameterBatchUpdateUtils.java:40) at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.batchUpdate(NamedParameterJdbcTemplate.java:303) at tester.utitlies.dao.VersionTwoDao.bulkInsertIntoSites(VersionTwoDao.java:21) at tester.utitlies.runner.Main.main(Main.java:28)
It fails as it considers the list to be a batch of beans, I guess. I cannot find a way to perform a batch update in Spring with a list of maps and using NamedParameterJDBCTemplate
. Please advice.
Advertisement
Answer
As per Spring NamedParameterJDBCTemplate
docs, found here, this method can be used for batch updating with maps.
int[] batchUpdate(String sql, Map<String,?>[] batchValues)
The real challange was to a get an array of Map<String, Object>
from a corresponding List<Map<String, Object>>
. I used the following code to get the array and perform the batch update.
public static Map<String, Object>[] getArrayData(List<Map<String, Object>> list){ @SuppressWarnings("unchecked") Map<String, Object>[] maps = new HashMap[list.size()]; Iterator<Map<String, Object>> iterator = list.iterator(); int i = 0; while (iterator.hasNext()) { Map<java.lang.String, java.lang.Object> map = (Map<java.lang.String, java.lang.Object>) iterator .next(); maps[i++] = map; } return maps; }