4

The MyBatis Spring Boot Starter documentation lists properties that can be set in the application.properties file, and that list includes:

configuration: A MyBatis Configuration bean. About available properties see the MyBatis reference page

It's not very obvious from there, but what I think it's suggesting is that you can add something like this:

mybatis.configuration.jdbcTypeForNull=VARCHAR

This seems to work; certainly, if I change VARCHAR for something that is not a valid value for the enum JdbcType, I get an error. However, it also doesn't appear to be picking up my setting.

When I use a debugger, I can see that MybatisProperties.setConfiguration() is called, before Configuration.setJdbcTypeForNull(), which means that the default value (JdbcType.OTHER) is used instead of the value I'm trying to set.

Am I misunderstanding how this functionality is supposed to be used, or is this a bug? Is anyone else setting config values like this? Elsewhere I can only see examples using XML files, which I'd rather avoid, if possible.

Well, this is embarrassing

I gave up on trying to use the configuration property in application.properties, and resorted to the XML config that I was trying to avoid, but just now, having seen some useful suggestions here, I went back to my code, changed it from the XML config back to having mybatis.configuration.jdbcTypeForNull=NULL and re-ran my test, which was definitely failing under the same conditions before, but now it passes.

I've no idea what's different from before - debugging I see the same behaviour as mentioned above - the Configuration bean seems to get the jdbcTypeForNull parameter set back to OTHER during startup, but then when it's accessed during a query it's NULL again. I'll leave this question here in case it's a race condition and it starts failing again later, but for now my problem seems to have mysteriously disappeared.

DaveyDaveDave
  • 9,821
  • 11
  • 64
  • 77
  • Have you tried adding this `` to your `mybatis-config.xml` which will allow you to get null or empty values without errors. – SiddP May 03 '16 at 10:55
  • Isn't this setting for when you're getting nulls out of the database? The case I'm looking at is setting columns to null in an insert. – DaveyDaveDave May 04 '16 at 10:50
  • My mistake I was consfused. Are you using bean as the parameterType. – SiddP May 04 '16 at 10:59

3 Answers3

1

If you are going to use mybatis.configuration.jdbcTypeForNull, please remember NOT to specify configLocation property at same time. Otherwise your setting will be erase to default.

As what spring boot do, MybatisProperties.setConfiguration() is called before Configuration.setJdbcTypeForNull() is really right. Because spring boot try to set configuration to MybatisProperties but found its member configuration is null, so spring boot will instantiate a new Configuration and assign it to MybatisProperties immediately. Afterwards, spring boot will try to assign all mybatis.configuration.* to this member of MybatisProperties.

If you are going to use XML to configure mybatis, you need specify <setting name="jdbcTypeForNull" value="VARCHAR"/> under element <settings/> as example.

This would definitely work.

Horsing
  • 1,070
  • 7
  • 22
  • Is this something that you've seen work? I get an error message: "Field error in object 'mybatis' on field 'configuration.jdbcTypeForNull': rejected value [12] ... nested exception is java.lang.IllegalArgumentException: No enum constant org.apache.ibatis.type.JdbcType.12]". – DaveyDaveDave May 03 '16 at 07:58
  • Please check `JdbcType` and find the real value you want. – Horsing May 03 '16 at 08:19
  • No, that's not it. You can see in the error message that it's trying to use the ...ibatis.type.JdbcType. As I say in the question, using VARCHAR does set the value correctly, but it is then re-set with a default after it gets set. – DaveyDaveDave May 03 '16 at 09:20
  • Ok. I got it. I'm on the train and replying you with my phone and it's not easy to read the source. I'll leave any message if I could. – Horsing May 03 '16 at 09:24
  • `Configuration#setJdbcTypeForNull()` has been called after `MybatisProperties#setConfiguration()` is correct. Cause later should be mapped to what you have configured when it is needed . Spring will create a default `Configuration` and assign it to `MybatisProperties` and then set `JdbcTypeForNull` properly. Are you sure the value isn't what you've configured? – Horsing May 03 '16 at 13:03
  • Please see my answer and I've updated it. I think it could help. – Horsing May 05 '16 at 02:19
  • Thanks, that's a helpful answer, and certainly does seem to be the effect I'm seeing, I'm just confused about why the first time I did it the new value didn't seem to be used when it created the query. For now I'll put it down to user error on my part. – DaveyDaveDave May 05 '16 at 10:13
0

Add this <setting name="jdbcTypeForNull" value="OTHER"/> to your mybatis-config.xml it should work fine. Else try this to your query which works perfectly fine for me with oracle/mysql as db

   insert into students 
     (id,name,class,date_of_joining)
     values 
     (#{id,jdbcType=INTEGER},#{class,jdbcType=TIMESTAMP},
     #{class,jdbcType=NVARCHAR},#{date_of_joining,jdbcType=TIMESTAMP})

Here is list of jdbcTypes provided by mybatis. You need to add it to each constraint if you feel the constraint can be empty/null at times.

SiddP
  • 1,603
  • 2
  • 14
  • 36
  • OTHER is the default, and that's what doesn't work (with Oracle). I am currently using this, but setting it to ...value="NULL", which works. The point of the question though was about not using the XML config if possible. My problem seems to have gone away now though - see edit to my post. – DaveyDaveDave May 04 '16 at 12:34
  • Are you using bean as the parameterType in your mapper xml. – SiddP May 04 '16 at 13:00
0

If you are using application.yml try

mybatis:
  configuration:
    jdbc-type-for-null: 'NULL'