如何使用Spring在Postgresql中存储java.util.ArrayList [英] How to store java.util.ArrayList in Postgresql using Spring

查看:342
本文介绍了如何使用Spring在Postgresql中存储java.util.ArrayList的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试对一组bean进行批量插入.Bean的属性之一是ArrayList.批处理更新失败,但以下情况除外:

I am trying to do a batch-insert of a collection of beans. One of the properties of the bean is an ArrayList. The batch update fails with the exception:

 Can't infer the SQL type to use for an instance of java.util.ArrayList. Use setObject() with an explicit Types value to specify the type to use.

我不知道要使用哪种Postgresql数据类型来兼容ArrayList.有没有办法可以在不更改其属性的数据类型的情况下对Bean进行批量更新?

I don't know which Postgresql data type to use for the ArrayList to be compatible. Is there a way I can do the batch update of the beans without changing the data type of its properties?

豆:

    import java.util.List;

    public class SomeBean {
        private int id;
        private List<String> names;

        @Override
        public String toString() {
            return "SomeBean [id=" + id + ", names=" + names + "]";
        }
        //Setters and getters

表架构:

CREATE TABLE arraylistexample
(
  id serial NOT NULL,
  names character varying[]
)

插入数据的方法:

    public void insert(List<SomeBean> beans){
        String sql = "INSERT INTO ARRAYLISTEXAMPLE (NAMES) VALUES (:names)";

        SqlParameterSource[] data = SqlParameterSourceUtils.createBatch(beans.toArray());
        pgTemplate.batchUpdate(sql, data);
    }

例外:

Exception in thread "main" org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [INSERT INTO ARRAYLISTEXAMPLE (NAMES) VALUES (?, ?)]; nested exception is org.postgresql.util.PSQLException: Can't infer the SQL type to use for an instance of java.util.ArrayList. Use setObject() with an explicit Types value to specify the type to use.
    at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:98)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:603)
    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 some.package.dao.GenericDao.insert(GenericDao.java:45)
    at some.package.runner.FileLogicTester.storingArrayListInDb(FileLogicTester.java:220)
    at some.package.runner.FileLogicTester.main(FileLogicTester.java:86)
Caused by: org.postgresql.util.PSQLException: Can't infer the SQL type to use for an instance of java.util.ArrayList. Use setObject() with an explicit Types value to specify the type to use.
    at org.postgresql.jdbc2.AbstractJdbc2Statement.setObject(AbstractJdbc2Statement.java:1801)
    at org.postgresql.jdbc3g.AbstractJdbc3gStatement.setObject(AbstractJdbc3gStatement.java:37)
    at org.postgresql.jdbc4.AbstractJdbc4Statement.setObject(AbstractJdbc4Statement.java:46)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.setObject(DelegatingPreparedStatement.java:255)
    at org.springframework.jdbc.core.StatementCreatorUtils.setValue(StatementCreatorUtils.java:351)
    at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValueInternal(StatementCreatorUtils.java:216)
    at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValue(StatementCreatorUtils.java:144)
    at org.springframework.jdbc.core.BatchUpdateUtils.setStatementParameters(BatchUpdateUtils.java:63)
    at org.springframework.jdbc.core.namedparam.NamedParameterBatchUpdateUtils.access$000(NamedParameterBatchUpdateUtils.java:32)
    at org.springframework.jdbc.core.namedparam.NamedParameterBatchUpdateUtils$1.setValues(NamedParameterBatchUpdateUtils.java:47)
    at org.springframework.jdbc.core.JdbcTemplate$4.doInPreparedStatement(JdbcTemplate.java:893)
    at org.springframework.jdbc.core.JdbcTemplate$4.doInPreparedStatement(JdbcTemplate.java:884)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:587)
    ... 7 more

有什么建议吗?

推荐答案

我遇到了同样的问题.这里人们对此进行了讨论.看起来这是JDBC驱动程序或PostgeSQL本身的问题,因此您不能仅将数组传递给DB.作为一种解决方法,我不得不手动创建SQL(我具有整数值,因此不在乎sql注入;您可能想动态地准备 SELECT * FROM MYTABLE WHERE ID IN(?,?,?)首先,然后处理该语句).

I was facing the same problem. Here people discussed about that. Looks like it's the fault of the JDBC driver or PostgeSQL itself, so you can't just pass an array to the DB. As a workaround I had to manually create SQL (I had integer values, so didn't care about sql injections; you may want to prepare dynamically SELECT * FROM MYTABLE WHERE ID IN (?,?,?) first and then process the statement).

private static final String SQL_FIND_GOAL = "SELECT * FROM MYTABLE WHERE ID IN (:ids)";

public List<MyGoal> getAllMyGoals(Set<Integer> ids) {
// Work around of issue.
int i=0;
String mockInStatement = "";
for (int type: ids){
  if (i < ids.size()-1){
    mockInStatement = mockInStatement + type + ",";
  }
  else {
    mockInStatement = mockInStatement + type;
  }
  i++;
}
String refinedSQL = SQL_FIND_GOAL.replace(":ids",mockInStatement);

List<MyGoal> result = jdbcTemplate.query(
    refinedSQL, 
    new RowMapper<MyGoal>() {
      @Override
      public MyGoal mapRow(ResultSet rs, int rowNum) throws SQLException {
        MyGoal myGoal = new MyGoal();
        myGoal.setCode(rowNum);
        myGoal.setName(rs.getString("name"));
        return myGoal;
      }
    });
return result;  }

这篇关于如何使用Spring在Postgresql中存储java.util.ArrayList的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆