Let's assume I have the following bean / mapper interface.

@Mapper
public interface MyBeanMapper {
   int updateMyBean(MyBean bean);
}

public interface MyBean {
   Long getId();
   String getString();
   OffsetDateTime getDate();
}

With the following mapper xml

<update id="updateMyBean">
   update my_table set 
      string = #{string}, 
      date = #{date} 
   where id = #{id}
</update>

Oracle will fail if MyBean.getDate() or MyBean.getString() return null. I'm forced to pass the javaType in the parameter declaration so that mybatis can pass the jdbcType to Oracle

<update id="updateMyBean">
   update my_table set 
      string = #{string,javaType=java.lang.String}, 
      date = #{date,javaType=java.time.OffsetDateTime} 
   where id = #{id}
</update>

I think that Mybatis should be able to use reflection on MyBean.getDate() and MyBean.getString() to determine the javaType of each property. It could then use this information to pass the correct jdbcType to oracle.

Comment From: harawata

Hello @uklance ,

Are you sure the second version works? Specifying jdbcType should work, but specifying javaType should make no difference in that scenario.

Mappings between Java type and JDBC type is not 1:1 and is DB/driver dependent, so in general, it is not possible to determine JDBC type from Java type.

I already commented on the SO question, but the solution is to set jdbcTypeForNull=NULL. The default value OTHER works with many DBs like H2 or HSQLDB, but not with Oracle. Specifying jdbcType, as I mentioned, could improve performance under certain conditions.

Comment From: uklance

Are you sure the second version works?

I know it works with jdbcType and assumed it also works with javaType.

I can now see that each type handler only implements setNonNullParameter(...) which is a shame. It would be better if each TypeHandler provided a custom implementation for null.

Comment From: harawata

MyBatis cannot assume SQL type in the built-in type handlers.

For example, users store java.lang.Boolean in various column types in their DB (CHAR(1), BIT, NUMBER(1,0), etc.). If MyBatis specifies java.sql.Types.BOOLEAN when setting null in the built-in BooleanTypeHandler, it fails in many cases.

Comment From: uklance

I'd expect to contribute a custom TypeHandler for java.lang.Boolean in this instance to suit the needs of my application

Comment From: harawata

I just did a quick test and specifying Types.NULL didn't make significant difference if the column type is NUMBER(1,0) or CHAR(1), so you don't have to worry about the performance issue I mentioned. In that case, you can write/register the custom type handler as explained in the doc. https://mybatis.org/mybatis-3/configuration.html#typehandlers

Please let me know if you need further help.