mybatis-plus icon indicating copy to clipboard operation
mybatis-plus copied to clipboard

Mybatis-plus插入时insertStrategy对id字段无效.

Open tonysmz opened this issue 2 years ago • 5 comments

当前使用版本(必填,否则不予处理)

v 3.5.2

该问题是如何引起的?(确定最新版也有问题再提!!!)

经过反复测试, mybatis-plus似乎对于id字段会固定放到insert语句中,不管字段是否为null, 也不管insertStrategy设置成什么都一样,也不管tableid设置成什么,其他字段不会, 因为本来mybatis-plus不支持SAP HANA ID自增, 那么我希望通过将id设置为null的方式,让mybatis-plus生成insert语句的时候不要包含id字段,但最终发现mybatis-plus不管如何都会在insert语句中加上id这个字段,而SAP HANA又不允许对自增字段插入内容, 这下尴尬了:

  1. SAP不允许对自增ID插入内容.
  2. Mybatis-plus又会对ID这个字符自动添加到insert语句中.
  3. 试过唯有将TableField(exists=false), 这样插入的时候不会插入ID, 但是Select的时候又不会查询该字段.

我可以理解id这个字段是个特别的字段, 但是不是主键不应该是我用@TableID来标识么? MyBatis-plus为什么要特别处理ID这个字段名?这样就丧失了系统的灵活性.

重现步骤(如果有就写完整)

报错信息

Caused by: com.sap.db.jdbc.exceptions.JDBCDriverException: SAP DBTech JDBC: [406]: INSERT, UPDATE and UPSERT are disallowed on the generated field: cannot insert into generated identity column field ID: line 1 col 30 (at pos 29) at com.sap.db.jdbc.exceptions.SQLExceptionSapDB._newInstance(SQLExceptionSapDB.java:209) at com.sap.db.jdbc.exceptions.SQLExceptionSapDB.newInstance(SQLExceptionSapDB.java:42) at com.sap.db.jdbc.packet.HReplyPacket._buildExceptionChain(HReplyPacket.java:841) at com.sap.db.jdbc.packet.HReplyPacket.getSQLExceptionChain(HReplyPacket.java:195) at com.sap.db.jdbc.packet.HPartInfo.getSQLExceptionChain(HPartInfo.java:39) at com.sap.db.jdbc.ConnectionSapDB._receive(ConnectionSapDB.java:4901) at com.sap.db.jdbc.ConnectionSapDB.exchange(ConnectionSapDB.java:2026) at com.sap.db.jdbc.PreparedStatementSapDB._prepare(PreparedStatementSapDB.java:2961) at com.sap.db.jdbc.PreparedStatementSapDB._doParse(PreparedStatementSapDB.java:2854) at com.sap.db.jdbc.PreparedStatementSapDB.(PreparedStatementSapDB.java:166) at com.sap.db.jdbc.PreparedStatementSapDB9.(Unknown Source) at com.sap.db.jdbc.HanaPreparedStatement.(Unknown Source) at com.sap.db.jdbc.HanaPreparedStatementClean.(Unknown Source) at com.sap.db.jdbc.HanaPreparedStatementClean.newInstance(Unknown Source) at com.sap.db.jdbc.ConnectionSapDB9._prepareStatement(Unknown Source) at com.sap.db.jdbc.ConnectionSapDB.prepareStatement(ConnectionSapDB.java:369) at com.alibaba.druid.filter.FilterChainImpl.connection_prepareStatement(FilterChainImpl.java:572) at com.alibaba.druid.filter.FilterAdapter.connection_prepareStatement(FilterAdapter.java:930) at com.alibaba.druid.filter.FilterEventAdapter.connection_prepareStatement(FilterEventAdapter.java:122) at com.alibaba.druid.filter.FilterChainImpl.connection_prepareStatement(FilterChainImpl.java:568) at com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl.prepareStatement(ConnectionProxyImpl.java:341) at com.alibaba.druid.pool.DruidPooledConnection.prepareStatement(DruidPooledConnection.java:351) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.apache.ibatis.logging.jdbc.ConnectionLogger.invoke(ConnectionLogger.java:55) at com.sun.proxy.$Proxy182.prepareStatement(Unknown Source) at org.apache.ibatis.executor.statement.PreparedStatementHandler.instantiateStatement(PreparedStatementHandler.java:86) at org.apache.ibatis.executor.statement.BaseStatementHandler.prepare(BaseStatementHandler.java:88) at org.apache.ibatis.executor.statement.RoutingStatementHandler.prepare(RoutingStatementHandler.java:59) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.apache.ibatis.plugin.Invocation.proceed(Invocation.java:49) at com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor.intercept(MybatisPlusInterceptor.java:83) at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:61) at com.sun.proxy.$Proxy181.prepare(Unknown Source) at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:87) at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:49) at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117) at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.apache.ibatis.plugin.Invocation.proceed(Invocation.java:49) at com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor.intercept(MybatisPlusInterceptor.java:83) at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:61) at com.sun.proxy.$Proxy180.update(Unknown Source) at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:197) at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:184) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:426) ... 90 more

tonysmz avatar Jun 07 '22 11:06 tonysmz

你的entity的id难道用的int类型而不是Integer?

miemieYaho avatar Jun 08 '22 07:06 miemieYaho

我当然用的是Integer, 但是Mybatis-plus还是会给它一个值,而且这个值是超出Integer范围的, 如下, 这个ID字段在实体类中是null, 但在Mybatis-plus生成SQL插入数据库的时候,依然给了它一个值1540237890110394369,如果id被当成一个普通字段来处理的话,在insert的字段中不应该出现ID字段,更不应该出现这个值才对.

SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@579d9fdb] was not registered for synchronization because synchronization is not active JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@12de2ca] will not be managed by Spring ==> Preparing: INSERT INTO errorcode ( id, codeType, errorCode, errorName ) VALUES ( ?, ?, ?, ? ) ==> Parameters: 1540237890110394369(Long), TONY(String), A023(String), smzdgmail(String)

tonysmz avatar Jun 24 '22 07:06 tonysmz

TableId 注解指定 type=auto

miemieYaho avatar Jun 24 '22 07:06 miemieYaho

准确的来讲,看起来Mybatis-plus对于ID这个字段, 即使没有指定@TableID,注解, 也会默认它的类型为ASSIGN_ID(源自全局配置中的DbConfig.idType), 给它指定一个值.

tonysmz avatar Jun 24 '22 08:06 tonysmz

然后呢

miemieYaho avatar Jun 24 '22 09:06 miemieYaho

我遇到了相似的问题, @TableId(value = "id", type = IdType.ASSIGN_UUID) private String id; insertStrategy为not_null 在save时即使id为null 也会被生成UUID

llanc avatar Oct 12 '22 12:10 llanc

SAP 问题这边无法处理,欢迎分享你的解决办法 PR 暂时关闭

qmdx avatar Dec 16 '22 02:12 qmdx