'JDBC Spring 4 NamedParameterJdbcTemplate with enum

I have been using JdbcTemplate very happyly but then I got convinced to use NamedParameterJdbcTemplate. However not enjoying this so far sometimes or all the times.

Lets say I have a Person class as below :

public class Person implements Serializable {

    private int age;
    private String name;
    private long socialId;
    private Gender gender;
    private String email;

    enum Gender {
        MALE, FEMALE
    }

}

And I am trying to insert the list of person as below:

SqlParameterSource[] params 
= SqlParameterSourceUtils.createBatch(personList.toArray());

            getNamedJdbcTemplate().batchUpdate(insertSql, params);

However it fails with message below

PreparedStatementCallback; uncategorized SQLException for SQL [INSERT INTO

at oracle.jdbc.driver.OraclePreparedStatementWrapper.setObject(OraclePreparedStatementWrapper.java:230)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.setObject(DelegatingPreparedStatement.java:169)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.setObject(DelegatingPreparedStatement.java:169)
    at org.springframework.jdbc.core.StatementCreatorUtils.setValue(StatementCreatorUtils.java:402)
    at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValueInternal(StatementCreatorUtils.java:235)
    at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValue(StatementCreatorUtils.java:166)
    at org.springframework.jdbc.core.BatchUpdateUtils.setStatementParameters(BatchUpdateUtils.java:65)
    at org.springframework.jdbc.core.namedparam.NamedParameterBatchUpdateUtils.access$000(NamedParameterBatchUpdateUtils.java:32)
    at org.springframework.jdbc.core.namedparam.NamedParameterBatchUpdateUtils$1.setValues(NamedParameterBatchUpdateUtils.java:48)
    at org.springframework.jdbc.core.JdbcTemplate$4.doInPreparedStatement(JdbcTemplate.java:999)
    at org.springframework.jdbc.core.JdbcTemplate$4.doInPreparedStatement(JdbcTemplate.java:989)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:644)
    ... 41 more

I debugged and can see that in StatementCreatorUtils class it will always fail if it is of Enum type in method

private static void setValue(PreparedStatement ps, int paramIndex

section of code....

else if (sqlType == SqlTypeValue.TYPE_UNKNOWN) {
            if (isStringValue(inValue.getClass())) {
                ps.setString(paramIndex, inValue.toString());
            }

QUESTION

Can someone please let me know any workaround for this? Or I need to do old way of setting data using placeholders( ?).

Many thanks



Solution 1:[1]

Got this working as below

sqlParameterSource.registerSqlType("gender", Types.VARCHAR);

This is fine but WHAT if we need to call a method on enum. Let's say getValue for enums like Male(10), FEMALE( 20)??

I am not able to use these enums very well with NamedParameterJdbcTemplate

Anyone looking to improve this in future?

Thanks

Solution 2:[2]

The NamedParameterJdbcTemplate accepts SQL with placeholders using nested properties/methods. I don't see that in the documentation, but you can use something like:

namedParameterJdbcTemplate.batchUpdate(
       "INSERT INTO mytable " +
       "(myVarcharColumn, myIntColumn) " +
       "VALUES (:myEnum1.name, :myEnum2.ordinal)", 
       batchArgs);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 user3808335
Solution 2 Italo Borssatto