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.