Skip to content

Frequently Asked Questions

This documentation collects various common issues encountered when using MyBatis-Plus. If you run into problems while using MyBatis-Plus, please check this documentation first.

How to Exclude Non-Table Fields?

Choose one of the following three methods:

  • Use the transient modifier

    private transient String noColumn;
  • Use the static modifier

    private static String noColumn;
  • Use the TableField annotation

    @TableField(exist=false)
    private String noColumn;

How to Exclude Entity Superclass Properties?

Use the transient modifier for the superclass properties you want to exclude.

/**
* Ignore superclass createTime field mapping
*/
private transient String createTime;

Resolving Invalid bound statement (not found) Exception

This exception typically occurs due to incorrect configuration or Mapper classes not being properly scanned. Use the following solutions:

  • Check for potential JAR package conflicts.

  • Verify the Mapper.java scan path:

    • Method 1: Use the @MapperScan annotation on your Configuration class

      @Configuration
      @MapperScan("com.yourpackage.*.mapper")
      public class YourConfigClass{
      ...
      }
    • Method 2: Configure MapperScannerConfigurer in your Configuration class (View example)

      @Bean
      public MapperScannerConfigurer mapperScannerConfigurer(){
      MapperScannerConfigurer scannerConfigurer = new MapperScannerConfigurer();
      // You can get your mapper path through environment variables, allowing mapper scanning to be configured via configuration files
      scannerConfigurer.setBasePackage("com.yourpackage.*.mapper");
      return scannerConfigurer;
      }
  • Check if you’ve specified a primary key. If not specified, selectById and related ID operations will fail. Use the @TableId annotation to mark your table’s primary key. Note: While the @TableId annotation can be omitted, your primary key column must be named ‘id’ (case-insensitive).

  • Do not use the native SqlSessionFactory; use MybatisSqlSessionFactory instead.

  • Check if you’ve customized SqlInjector and overridden the getMethodList() method. Ensure this method injects all the methods you need (refer to DefaultSqlInjector for guidance).

  • IDEA’s default build process might prevent mapper XML files from being compiled to the corresponding resources folder. Check if the XML files exist in the relevant resources folders after building. If not, adjust IDEA’s build settings. We recommend using Maven or Gradle for building instead.

Custom SQL Not Executing

Problem Description: This refers to custom SQL defined in XML files that cannot be invoked. This feature, like MyBatis, requires configuring the XML scan path:

<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="typeAliasesPackage" value="xxx.entity" />
<property name="mapperLocations" value="classpath*:/mybatis/*/*.xml"/>
...
</bean>
mybatis-plus:
mapper-locations: classpath*:/mapper/**/*.xml
  • For IDEA series editors, XML files cannot be placed in the java folder because IDEA does not compile XML files in the source code folders by default. You can resolve this using the following methods:

    • Place configuration files in the resource folder
    • For Maven projects, specify the resource in the POM file
    <build>
    <resources>
    <resource>
    <!-- xml placed in the java directory -->
    <directory>src/main/java</directory>
    <includes>
    <include>**/*.xml</include>
    </includes>
    </resource>
    <!-- Specify the resource location (not necessary if xml is placed under resources) -->
    <resource>
    <directory>src/main/resources</directory>
    </resource>
    </resources>
    </build>

Troubleshooting Startup Exceptions

  • Exception 1:

    java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class

    MapperScan needs to exclude the com.baomidou.mybatisplus.mapper.BaseMapper class and its subclasses (custom public Mappers). For example:

    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    public interface SuperMapper<T> extends BaseMapper<T> {
    // your methods
    }
  • Exception 2:

    Injection of autowired

    Cause: Lower versions do not support generic injection. Please upgrade your Spring version to 4 or higher.

  • Exception 3:

    java.lang.NoSuchMethodError: org.apache.ibatis.session.Configuration.getDefaultScriptingLanguageInstance() Lorg/apache/ibatis/scripting/LanguageDriver

    Version introduction issue: This method is not available in version 3.4.1, but was introduced in version 3.4.2!

About Long Type Primary Key Auto-fill Not Taking Effect

Check if you are using long instead of Long!

Generated Primary Key Too Long Causes JS Precision Loss

JavaScript cannot handle Java’s Long data type, which results in precision loss. The specific symptom is that the last two digits of the primary key are always 0. Solution: Convert Long to String when returning data.

  • FastJson Approach

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    FastJsonHttpMessageConverter fastJsonConverter = new FastJsonHttpMessageConverter();
    FastJsonConfig fjc = new FastJsonConfig();
    // Configure serialization strategy
    fjc.setSerializerFeatures(SerializerFeature.BrowserCompatible);
    fastJsonConverter.setFastJsonConfig(fjc);
    converters.add(fastJsonConverter);
    }
  • Jackson Approach

    • Method One

      // Annotation approach - you can configure this in a common baseEntity
      @JsonSerialize(using=ToStringSerializer.class)
      public long getId() {
      return id;
      }
    • Method Two

      // Global configuration for JSON serialization
      final ObjectMapper objectMapper = new ObjectMapper();
      SimpleModule simpleModule = new SimpleModule();
      simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
      objectMapper.registerModule(simpleModule);
  • More General Approach: Add a public String getIdStr() method and let the frontend get idStr

Inserting or Updating Fields with Empty Strings or null

FieldStrategy has three policies:

  • IGNORED: Ignore checks
  • NOT_NULL: Non-NULL, the default policy
  • NOT_EMPTY: Non-empty

When you need to update fields to empty strings or null, you need to adjust the FieldStrategy policy:

  • Method 1: Adjust the global validation strategy

    Inject the GlobalConfiguration and set the fieldStrategy property

  • Method 2: Adjust field validation annotations

    Based on your specific needs, adjust the validation annotation on fields that require updating. For example, to validate non-empty:

    @TableField(strategy=FieldStrategy.NOT_EMPTY)
  • Method 3: Use UpdateWrapper (3.x)

    Use the following methods for update or insert operations:

    //updateAllColumnById(entity) // update all columns: removed in 3.0
    mapper.update(
    new User().setName("mp").setAge(3),
    Wrappers.<User>lambdaUpdate()
    .set(User::getEmail, null) // set email to null
    .eq(User::getId, 2)
    );
    // Alternatively, you can use this approach
    mapper.update(
    null,
    Wrappers.<User>lambdaUpdate()
    .set(User::getAge, 3)
    .set(User::getName, "mp")
    .set(User::getEmail, null) // set email to null
    .eq(User::getId, 2)
    );

Fields with bit or tinyint(1) Types Map to boolean Type

By default, the MySQL driver maps tinyint(1) fields to boolean: 0=false, non-zero=true.

MyBatis does not handle this mapping automatically. If you don’t want to map tinyint(1) to boolean type:

  • Change the type from tinyint(1) to tinyint(2) or int
  • Add the parameter tinyInt1isBit=false to your connection string, as shown below:
jdbc:mysql://127.0.0.1:3306/mp?tinyInt1isBit=false

Multiple limit Statements Appear

Cause: Two pagination interceptors are configured! Check your configuration file or code and keep only one!

How to Return the Primary Key After Insert

After an insert operation, the primary key is automatically set to the entity’s ID field, so you only need to call getId().

How to Query Specific Fields in MP

Use EntityWrapper.sqlSelect to configure the fields you want to query

2.x
EntityWrapper<H2User> ew = new EntityWrapper<>();
ew.setSqlSelect("test_id as id, name, age");//Query only 3 fields
List<H2User> list = userService.selectList(ew);
for(H2User u:list){
Assert.assertNotNull(u.getId());
Assert.assertNotNull(u.getName());
Assert.assertNull(u.getPrice()); // This field was not queried
}
//3.x
mapper.selectList(
Wrappers.<User>lambdaQuery()
.select(User::getId, User::getName)
);
//Or use QueryWrapper
mapper.selectList(
new QueryWrapper<User>()
.select("id","name")
);

Mapper Layer Second-Level Cache Issues

We recommend placing the cache at the service layer. You can customize your own BaseServiceImpl to override parent class methods with annotations and inherit your own implementation.

Mapper Layer Second-Level Cache Refresh Issue

If you configure a third-party second-level cache following the MyBatis approach and use version 2.0.9 or higher, you may find that the built-in methods cannot update the cache content. To resolve this issue, choose one of the following solutions:

  1. Add a cache annotation to the MyBatis mapper layer in your code, specifying the implementation or eviction value as the cache interface implementation class:
@CacheNamespace(implementation=MybatisRedisCache.class,eviction=MybatisRedisCache.class)
public interface DataResourceMapper extends BaseMapper<DataResource>{}
  1. Modify the original annotation in the corresponding mapper.xml file to a linked declaration, ensuring the cache in the XML file works properly:
<cache-ref namespace="com.mst.cms.dao.DataResourceMapper"></cache-ref>

Cause: org.apache.ibatis.type.TypeException:Error setting null for parameter #1 with JdbcType OTHER

In MyBatis-Plus, the jdbcTypeForNull configuration option determines how Java null values are mapped to the database.

By default, when a field is null in Java, MyBatis-Plus maps it to the JdbcType.OTHER value in the database. However, some JDBC drivers (such as Oracle) do not support JdbcType.OTHER, which causes the error: Cause: org.apache.ibatis.type.TypeException:Error setting null for parameter #1 with JdbcType OTHER . Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. Cause: java.sql.SQLException: Invalid column type: 1111.

To configure jdbcTypeForNull, add the following code to your MyBatis-Plus configuration class (choose one option):

Spring Bean Configuration

MybatisConfiguration configuration = new MybatisConfiguration();
configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
configuration.setJdbcTypeForNull(JdbcType.NULL);
sqlSessionFactory.setConfiguration(configuration);

YAML Configuration

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

Properties Configuration

mybatis-plus.configuration.jdbc-type-for-null=NULL

XML Configuration

<configuration>
<settings>
<setting name="jdbcTypeForNull" value="NULL" />
</settings>
</configuration>

Note: If you customize the SqlSessionFactory in your project, the jdbc-type-for-null configuration might not take effect.

Cannot Pass Parameters Through Page Object in Custom SQL

In custom SQL, since the Page object inherits from RowBounds, it cannot be directly retrieved in the Mapper. To solve this problem, consider the following alternatives:

  • Use a custom Map object or a regular Java object to pass parameters.
  • Pass the page number and page size by using @Param("page") int page, @Param("size") int size in your method parameters.

These methods can help you correctly pass parameters in custom SQL, ensuring your code runs smoothly.

How to Automatically Convert Underscores to Camel Case in Map

When using resultType="java.util.Map", you can implement automatic underscore-to-camel-case conversion in Spring Boot by following these steps:

Create a configuration class in your Spring Boot project.

@Configuration
public class MybatisConfigurationCustomizer {
@Bean
public ConfigurationCustomizer configurationCustomizer() {
return configuration -> configuration.setObjectWrapperFactory(new MybatisMapWrapperFactory());
}
}

With this configuration, you can automatically convert underscores to camel case in Map objects. When MyBatis query results are mapped to Map objects, the key names will be automatically converted, allowing you to access data more conveniently in your code.

How to Use limit in Wrapper to Restrict SQL

You can use the following approach to limit SQL result sets with limit in Wrapper:

// Get only one record
wrapper.last("limit 1");

This code appends limit 1 to the end of the SQL statement, restricting the result set to return only one row.

Why Generic Batch Insert Operations are Handled at the Service Layer

Placing generic batch insert operations in the Service layer offers the following advantages:

  • SQL length limitations: When processing massive amounts of data, a single SQL statement might fail to execute or could easily cause memory leaks, JDBC connection timeouts, and other issues.
  • Database syntax variations: Different databases have inconsistent syntax for single-statement batch operations, which hinders generalizability.
  • Solution: Use a loop-based approach with prepared statements and batch commits. While slightly slower than single-SQL insertion, this method resolves the issues mentioned above.

If you prefer the single-SQL insertion approach, you can manually inject the optional method insertbatchsomecolumn, or check the methods available in the SQL Injector.

Database Keyword Handling Methods in 3.x Version

In MyBatis-Plus 3.x, automatic keyword recognition and processing functionality is no longer provided. Here are the methods for handling database keywords:

  1. Different databases handle keywords differently, making maintenance difficult. During database design, we recommend avoiding the use of keywords as field names or table names.

  2. If you must use keywords, you can handle them by adding backticks (`) before and after the field or table name, as shown below:

    @TableField(value = "`status`")
    private Boolean status;

In summary, to avoid issues, we recommend avoiding the use of keywords in your database design whenever possible.

MybatisPlusException: Your property named “xxx” cannot find the corresponding database column name!

Issue occurring in MyBatis Plus 3.1.1 and later versions:

Symptom: The unit tests pass without issues, but this exception occurs when you start the server for debugging.

Cause: In version 3.1.1 and later, field caching was optimized by using .class as the key instead of the original class name (className). However, when using dev-tools, .class might be loaded by different class loaders, which can cause properties to not be found.

Solution: Remove the dev-tools plugin. This prevents .class from being loaded by different class loaders, resolving the exception.

Error attempting to get column “create_time” from result set. Cause: java.sql.SQLFeatureNotSupportedException

Issue affecting MyBatis-Plus 3.1.1 and later versions:

Symptom: When integrating with Druid data source, after upgrading to version 3.1.1 or later, you encounter the error: java.sql.SQLFeatureNotSupportedException. This issue does not occur in versions prior to 3.1.0.

Cause: MyBatis-Plus versions 3.1.1 and later use a newer JDBC implementation that includes upgraded handling for new date types (such as LocalDateTime). However, Druid versions prior to 1.1.21 do not support this feature, causing this exception. For more details, refer to the related issue.

Solutions:

  1. Upgrade the Druid data source to version 1.1.21 or later to resolve this issue.
  2. If you cannot upgrade the Druid data source, you can keep using MyBatis-Plus version 3.1.0 or earlier.
  3. If you want to continue using the latest MyBatis-Plus version, consider switching to another data source that is compatible with the new JDBC features to avoid this exception.

New Date Types Fail to Map After Upgrading to MyBatis Plus 3.1.1 or Later

If you upgrade MyBatis Plus from version 3.1.0 or earlier to a higher version and encounter mapping errors with new date types (such as LocalDateTime), this may be due to the following reasons:

MP_3.1.0 and earlier versions depend on MyBatis 3.5.0. MP_3.1.1 upgrades the MyBatis dependency to 3.5.1, and in MyBatis 3.5.1, the new date types require JDBC driver support for the JDBC 4.2 API.

If your JDBC driver version does not support the JDBC 4.2 API, you will encounter mapping errors with the new date types.

Referencing the content from the MyBatis official blog:

There is one backward incompatible changes since 3.5.0.
Because of the fix for #1478 , LocalDateTypeHandler, LocalTimeTypeHandler and LocalDateTimeTypeHandler now require a JDBC driver that supports JDBC 4.2 API.
[EDIT] These type handlers no longer work with Druid. Please see #1516 .

Solutions:

  • Upgrade your JDBC driver to a version that supports the JDBC 4.2 API.
  • If you cannot upgrade the JDBC driver, consider rolling back your MyBatis Plus version to 3.1.0 or earlier.

Failed to bind properties under “mybatis-plus.configuration.incomplete-result-maps[0].assistant.configuration.mapped-statements[0].parameter-map.parameter-mappings[0]” to org.apache.ibatis.mapping.ParameterMapping

If you encounter this issue when upgrading your Spring Boot version from 2.2.0 to a later version, it may be due to the following reasons:

Symptom: The application starts without issues locally, but this problem occurs when you deploy it as a WAR package to a server.

Cause: Spring Boot 2.2.0 had an issue with constructor injection that prevented MyBatis’s private constructor from properly binding properties. This caused dependent frameworks like MyBatis-Plus to throw errors. For detailed information, refer to the related issue. This issue was fixed in Spring Boot 2.2.1.

Solution:

  1. Downgrade Spring Boot to version 2.1.x, or upgrade to version 2.2.1 or later. We recommend upgrading directly to Spring Boot 2.2.2 for better stability and fixes.

ClassNotFoundException During Separate Packaging and Deployment

Symptom: The application runs without issues in your development environment, but after packaging and deploying to the server, a ClassNotFoundException occurs when executing Lambda expressions.

For MyBatis-Plus versions below 3.3.2, if you encounter ClassNotFoundException issues during separate packaging and deployment, it might be caused by incorrect class loader behavior during deserialization operations.

Solutions:

  1. Remove the spring-boot-maven-plugin from your packaging process, or
  2. Upgrade to MyBatis-Plus version 3.3.2. You can refer to the separate packaging example for implementation guidance.

Enable MyBatis Internal Logging

You can enable MyBatis internal logging using either of the following two methods:

Method 1: Add the following configuration to your application.yml or application.properties file:

mybatis-plus:
configuration:
# If your project doesn't have a logging framework, consider specifying org.apache.ibatis.logging.stdout.StdOutImpl (do not use in actual production).
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

This uses MyBatis’s built-in StdOutImpl logging implementation to output logs to the console.

Method 2: Add logging level configuration to your application.yml or application.properties file to specify the log level for specific packages. For example:

logging:
level:
com.baomidou.example.mapper: debug

This sets the log level to debug for the com.baomidou.example.mapper package. You can adjust the level according to your needs.

With the above configurations, you can enable MyBatis internal logging and adjust the log levels as required.

How to Perform Field Auto-Increment Operations During Update

If you want to perform an auto-increment operation on a field during an update, you can use the Wrapper provided by MyBatis Plus. Here is a feasible solution:

UpdateWrapper<Entity> wrapper = new UpdateWrapper<>();
wrapper.setSql("column = column + 1");
// Or use Lambda expressions
UpdateWrapper<Entity> wrapper = new UpdateWrapper<>();
wrapper.setSql("column = column + 1");
// Call the update method
baseMapper.update(null, wrapper);

This allows you to perform field auto-increment operations during updates. Note that you need to directly specify the SQL update statement in the setSql method.

How to Handle Database Keywords Globally

If you want to handle database keywords globally, you can use the global configuration provided by MyBatis Plus. Here’s a configuration example (using MySQL):

mybatis-plus:
global-config:
db-config:
column-format: "`%s`"

After applying this configuration, MyBatis Plus will wrap database column names with backticks (`) when generating SQL statements, ensuring they don’t conflict with database keywords.

Important notes:

  • If you use the @TableField annotation and want to maintain global formatting, you need to set the parameter keepGlobalFormat=true.
  • You can also directly specify fixed-format database keywords in the @TableField annotation, for example @TableField("'status'").

With the above configuration, you can handle database keywords globally, ensuring that your generated SQL statements aren’t affected by keyword conflicts.

How to Select Different SQL Fragments Based on Database Type in XML

If you want to select different SQL fragments in XML based on the database type, you can use the database-id parameter provided by MyBatis Plus. Here’s a configuration example (using MySQL):

mybatis-plus:
configuration:
database-id: mysql

After configuring this, MyBatis Plus will select different SQL fragments based on the database-id parameter when executing SQL statements.

You can implement conditional logic in XML using different approaches:

  1. Using the _databaseId variable:
<select id="selectAllNames" resultType="java.lang.String">
select
<choose>
<when test="_databaseId == 'mysql'">
GROUP_CONCAT(name SEPARATOR ',')
</when>
<otherwise>
array_to_string(ARRAY_AGG(name), ',')
</otherwise>
</choose>
from user
</select>
  1. Using the databaseId tag attribute:
<select id="selectAllNames" databaseId="mysql" resultType="java.lang.String">
select GROUP_CONCAT(name SEPARATOR ',') from user
</select>
<select id="selectAllNames" databaseId="pgsql" resultType="java.lang.String">
select array_to_string(ARRAY_AGG(name), ',') from user
</select>

With the above configurations, you can select different SQL fragments based on different database types.

Why MyBatis Plus Doesn’t Support Composite Primary Keys and Enforces Unique ID

MyBatis Plus doesn’t support composite primary keys and enforces the use of a unique ID for the following reasons:

  1. Increased interdependency between tables: Using composite primary keys makes relationships between tables more complex, increasing maintenance and management difficulty.

  2. Added complexity for data constraints and rules: Composite primary keys introduce additional data constraints and rules, such as requiring uniqueness constraints, which can be achieved using composite indexes instead.

  3. Increased limitations for data updates: When updating data, you need to update all values of the composite primary key, which adds restrictions and complexity to update operations.

  4. Serious data redundancy and update anomaly issues: Composite primary keys can lead to data redundancy and update anomalies, particularly in large systems where update anomalies may occur.

  5. Performance issues: When using composite primary keys, queries for specific IDs cannot utilize indexes effectively, resulting in performance degradation.

In summary, while using composite primary keys can eliminate the need for an ID field, the disadvantages of this approach outweigh the advantages. MyBatis Plus insists on using a unique ID to ensure simplicity in data management, maintainability, and performance.

Slow Project Startup

  • Caused by initializing default Snowflake ID

    1. Check your local hostname
    2. Edit the system hosts file and add your local hostname to it
    # Example: If my hostname is nieqiurong-PC, I would configure the hosts file as follows
    127.0.0.1 localhost nieqiurong-PC
  • Check database connection pool initialization

    We’ve encountered cases where using HikariCP causes slow startup on Linux systems

    Solution:

    Specify -Djava.security.egd=file:/dev/urandom in the Java startup command to change the random number generation method from /dev/random to /dev/urandom

    Example: java -Djava.security.egd=file:/dev/urandom -jar xxxx.jar

3.5.7+ Version Db.saveBatch Return Value Always False

  • Cause: Driver configuration incompatibility

Solution: Remove the rewriteBatchedStatements=true configuration from the driver connection

Page or List Returns null Result Set or Contains Some null Elements

  • Cause: By default in MyBatis, when all columns of a returned row are empty (including properties that cannot be automatically mapped), it returns null by default.

Solution: Configure returnInstanceForEmptyRow to true

mybatis-plus:
configuration:
return-instance-for-empty-row: true

When Return Value is Map or List<Map>, Keys Corresponding to null Values Are Not Added to the Map

  • Reason: By default in MyBatis, when a value is null, the put method is not called

Solution: Configure callSettersOnNulls to true

mybatis-plus:
configuration:
call-setters-on-nulls: true

How to Override BaseMapper Methods

When overriding interface methods, distinguish between default methods and abstract interface methods. The overridden method should ultimately call the actual method that will be executed.

Abstract interface methods: You can override these methods directly in XML.

Default methods: Either override the actual method being called directly, or rewrite the original default method as a real interface method, then override the execution statement using XML or annotations.

// Method 1: Override the selectPage method in BaseMapper using annotations (may be an interface method in older versions, using new version default as example here)
@Override
@Select("select * from h2user")
<P extends IPage<H2User>> P selectPage(P page, @Param(Constants.WRAPPER) Wrapper<H2User> queryWrapper);
// Method 2: Override the selectPage method in BaseMapper using XML (may be an interface method in older versions, using new version default as example here)
@Override
<P extends IPage<H2User>> P selectPage(P page, @Param(Constants.WRAPPER) Wrapper<H2User> queryWrapper);
// You need to rewrite the selectPage query statement in XML yourself
// Method 3: Override the selectPage method in BaseMapper
@Override
default <P extends IPage<User>> P selectPage(P page, @Param(Constants.WRAPPER) Wrapper<User> queryWrapper) {
return xxxx(); // The actual custom interface method being called
}

Invalid bound statement (not found) when calling interface default methods in Kotlin

Solution: Configure the compiler argument -Xjvm-default=all for the compilation plugin

<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<configuration>
<args>
<arg>-Xjsr305=strict</arg>
<arg>-Xjvm-default=all</arg>
</args>
</configuration>
</plugin>
compileKotlin {
kotlinOptions {
freeCompilerArgs = ['-Xjvm-default=all']
}
}

Encountered unexpected token: “\n\n\n” or Could not set parameters for mapping

  • Cause: In jsqlParser 4.9, consecutive line breaks are interpreted as the end of a statement, throwing an “Encountered unexpected token” parsing error. Starting from version 5.0, when encountering consecutive \n\n, the subsequent statements are truncated, leading to a “Could not set parameters for mapping” error at the MyBatis layer.

    Reference link: https://github.com/JSQLParser/JSqlParser/issues/1988

    Starting from version 3.5.3.2, MyBatis-Plus handles line breaks for SQL statements injected by the framework itself. However, you need to handle line breaks in SQL statements you write within your project.

  • Note: Versions 3.5.10 and 3.5.10.1 handle line breaks in project SQL, but they cannot support single-line comments (-- or #) within these statements. Starting from version 3.5.11, this handling will be removed. If you need to process statements with consecutive line breaks, use one of the following methods.

Method 1:

static {
JsqlParserGlobal.setParserMultiFunc((sql)-> {
String formatSql = CCJSqlParserUtil.sanitizeSingleSql(sql);
return CCJSqlParserUtil.parseStatements(formatSql, JsqlParserGlobal.getExecutorService(), null);
});
JsqlParserGlobal.setParserSingleFunc((sql)-> {
String formatSql = CCJSqlParserUtil.sanitizeSingleSql(sql);
return CCJSqlParserUtil.parse(formatSql, JsqlParserGlobal.getExecutorService(), null);
});
}
// If your jsqlParser version is lower than 5.0, copy the following method into your project. The code is sourced from JsqlParser version 5.0.
public static String sanitizeSingleSql(String sqlStr) {
Pattern SQL_DELIMITER_SPLIT = Pattern.compile("((?:'[^']*+'|[^\\n])*+)");
StringBuilder builder = new StringBuilder();
Matcher matcher = SQL_DELIMITER_SPLIT.matcher(sqlStr);
while(matcher.find()) {
for(int i = 1; i <= matcher.groupCount(); ++i) {
if (!matcher.group(i).isEmpty()) {
builder.append("\n").append(matcher.group(i));
}
}
}
return builder.toString();
}

Method 2: Enable MyBatis’ whitespace removal in SQL (may be less versatile and cannot handle single-line comments like -- or #)

mybatis-plus:
configuration:
shrink-whitespaces-in-sql: true

How to Configure the Code Generator to Generate XXXRepository

Service and Repository will no longer be maintained going forward. We recommend you discontinue their use. If you need to generate them, follow these steps to convert the service to a repository.

AutoGenerator generator = new AutoGenerator(DATA_SOURCE_CONFIG);
generator.packageInfo(new PackageConfig.Builder()
//-- Conversion Start----
.service("repository")
.serviceImpl("repository.impl")
//-- Conversion End----
.build());
generator.strategy(
new StrategyConfig.Builder()
//-- Conversion Start----
.serviceBuilder().convertServiceFileName(entityName -> "I" + entityName + "Repository")
.superServiceClass(IRepository.class).convertServiceImplFileName(entityName -> entityName + "Repository")
.superServiceImplClass(CrudRepository.class)
//-- Conversion End----
.build());
generator.execute();
Baomidou

© 2016-2025 Baomidou™. All Rights Reserved.

Power by Astro Starlight | Sponsored by JetBrains

渝ICP备2021000141号-1 | 渝公网安备50011302222097