6

I usually use the lobHandler + JdbcTemplate + PreparedStatementSetter triplet to insert my Clob into the database, as I saw on http://www.java2s.com/Code/Java/Spring/InsertClobData.htm

My question is how to do this with a NamedParameterJdbcTemplate? It has no methods accepting the mysterious PreparedStatementSetter interface as a parameter.

jabal
  • 11,987
  • 12
  • 51
  • 99
  • nothing to your topic but BLOB/CLOB have methods for stream too, by using FileInputStream/FileOutputStream – mKorbel Apr 26 '11 at 16:19
  • thanks, but really unrelated.. :-( I know how to handle them by old-fashioned JDBC boilerplate code. – jabal Apr 29 '11 at 12:43

3 Answers3

11

This works without using the PreparedStatementCallback and lobHandler, at least when inserting a string.

NamedParameterJdbcTemplate template; //= new NamedParameterJdbcTemplate(pDs);
String INSERT_STMT = "INSERT INTO MYTABLE (ID, LONG_TEXT) VALUES (:id, :clob)";
MapSqlParameterSource paramSource = new MapSqlParameterSource();
paramSource.addValue("id", 1L, Types.NUMERIC);
paramSource.addValue("clob", "a long long text", Types.CLOB);
template.update(INSERT_STMT, paramSource);
Jonas
  • 678
  • 4
  • 11
  • as for me it doesn't work (Oracle 9.2, Java 6), throws exception: 'java.lang.ClassCastException: java.lang.String at oracle.jdbc.driver.OraclePreparedStatement.setObjectCritical(OraclePreparedStatement.java:7898) at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:7511) at oracle.jdbc.driver.OraclePreparedStatement.setObject(OraclePreparedStatement.java:7984) at oracle.jdbc.driver.OraclePreparedStatementWrapper.setObject(OraclePreparedStatementWrapper.java:237)' – jabal Apr 29 '11 at 12:35
  • Sorry, I verified against HSQL. What version of Spring are you using? I think it's [this bug](https://jira.springsource.org/browse/SPR-4508?page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#issue-tabs) that causes your problem, it should have been resolved in 2.5.2. – Jonas Apr 30 '11 at 16:31
  • OMG, well we have to use Spring 2.0 in this project... :-( Thank you very much for pointing this out – jabal May 02 '11 at 12:53
  • 2
    Resurrecting this, I'm using Spring 3.0 here and this works. It's not really documented anywhere how or why, but it does. I like this solution better because SqlLobValue doesn't implement toString() so reading it required a bit more work. – Nicholas Aug 24 '11 at 17:57
  • Yeah, this seems pretty nice. – CorayThan Apr 22 '13 at 18:39
  • This is the only solution that worked for me when inserting a clob into an Oracle dB, with Java & Spring Boot, and i've looked everywhere. I was using Map paramSource = new HashMap(); so no Typing allowed. When I changed to MapSqlParameterSource and added Types.CLOB everything worked fine. – DS. Feb 11 '20 at 12:59
1

I'm using Spring 2.5.6 + Oracle and for me it worked straight away.

// Inserts file into DB and returns the key for the new row
public Number insert(String filename, byte[] data) {
    MapSqlParameterSource params = new MapSqlParameterSource();
    params.addValue("filename", filename);
    params.addValue("data", data);

    // Returns the autogenerated ID
    KeyHolder keyHolder = new GeneratedKeyHolder();
    String[] columnNames = {"ID"};

    // This is a NamedParameterJdbcTemplate
    jdbcTemplate.update(INSERT_SQL, params, keyHolder, columnNames);

    return keyHolder.getKey();
}
Jordan Silva
  • 833
  • 8
  • 18
0

I do something like this, obviously we use an Oracle database if you use something else you will have to fiddle with some of the parameter. The getJdbcTemplate method is a helper method of JdbcDaoSupport (a spring helper class.)

getJdbcTemplate().execute(new ConnectionCallback() {

        public Object doInConnection(Connection con) throws SQLException, DataAccessException {

            PublishResponseObject responseObject = new PublishResponseObject();
            OracleCallableStatement ocstmt = null;
            CLOB clob = null;

            try {
                clob = createCLOB(xmlString, con);
                ocstmt = (OracleCallableStatement) con.prepareCall("{call schmea.publish(?)}");
                //When in insert mode and update By Pk is specified updates are possible and version numbers will be returned.
                ocstmt.setCLOB(1, clob);
             ...
             }
             finally {
               clob.close()
               stmt.close
            }
Karthik Ramachandran
  • 11,925
  • 10
  • 45
  • 53
  • 1
    thanks, but my question was how to do this with namedparameterjdbctemplate, and your solution uses a jdbctemplate and is oracle specific – jabal Apr 29 '11 at 12:37