Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mybatis should determine javaType via reflection #3072

Open
uklance opened this issue Jan 22, 2024 · 5 comments
Open

Mybatis should determine javaType via reflection #3072

uklance opened this issue Jan 22, 2024 · 5 comments

Comments

@uklance
Copy link

uklance commented Jan 22, 2024

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.

@harawata
Copy link
Member

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.

@uklance
Copy link
Author

uklance commented Jan 23, 2024

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.

@harawata
Copy link
Member

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.

@uklance
Copy link
Author

uklance commented Jan 23, 2024

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

@harawata
Copy link
Member

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants