Databases 5 min read

Why ShardingSphere Encryption Blocks ShardingDataSource Creation and How to Fix It

This article explains how, in a Spring Boot 2.2.13 environment with ShardingSphere 4.0.1, enabling data encryption causes the expected ShardingDataSource bean not to be created, walks through the configuration and source code analysis, and provides a custom bean solution to resolve the issue.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Why ShardingSphere Encryption Blocks ShardingDataSource Creation and How to Fix It

Environment

Spring Boot 2.2.13.RELEASE combined with ShardingSphere 4.0.1.

Configuration Files

<code>spring:
  shardingsphere:
    sharding:
      defaultDataSourceName: ds0 # data source for tables without sharding
      tables:
        t_order: # logical table name
          logic-table: t_order
          actualDataNodes: ds$->{0}.t_order_$->{2020..2020}0$->{1..2} # actual tables
          tableStrategy:
            standard:
              shardingColumn: order_date # sharding column
              preciseAlgorithmClassName: net.greatsoft.mapper.base.DateTableShardingAlgorithm
              rangeAlgorithmClassName: net.greatsoft.mapper.base.DataTabeRangeShardingAlgorithm2
    encrypt-rule:
      encryptors:
        encryptor_id_no:
          type: aes
          props:
            aes.key.value: 123123
      tables:
        bc_users:
          columns:
            ID_NO:
              cipher-column: ID_NO
              encryptor: encryptor_id_no
            id_no:
              cipher-column: ID_NO
              encryptor: encryptor_id_no</code>

Testing shows that queries on the sharded table follow the encryption rule, and encryption/decryption works correctly.

Official Documentation

The section describes how to use data masking (encryption) together with sharding. When both are used, a ShardingDataSource is created; when used alone, an EncryptDataSource is created.

In practice, enabling both sharding and encryption creates an EncryptDataSource instead of the expected ShardingDataSource.

Source Code Inspection

The bean that should create the ShardingDataSource is defined as:

<code>@Bean
@Conditional(ShardingRuleCondition.class)
public DataSource shardingDataSource() throws SQLException {
    return ShardingDataSourceFactory.createDataSource(dataSourceMap, new ShardingRuleConfigurationYamlSwapper().swap(shardingRule), props.getProps());
}</code>

The condition class checks for master‑slave or encrypt rules:

<code>@Override
public ConditionOutcome getMatchOutcome(final ConditionContext conditionContext, final AnnotatedTypeMetadata annotatedTypeMetadata) {
    boolean isMasterSlaveRule = new MasterSlaveRuleCondition().getMatchOutcome(conditionContext, annotatedTypeMetadata).isMatch();
    boolean isEncryptRule = new EncryptRuleCondition().getMatchOutcome(conditionContext, annotatedTypeMetadata).isMatch();
    return isMasterSlaveRule || isEncryptRule ? ConditionOutcome.noMatch("Have found master-slave or encrypt rule in environment") : ConditionOutcome.match();
}</code>

Because the encrypt rule is present,

isEncryptRule

returns true, causing the condition to return

noMatch

and preventing the ShardingDataSource bean from being created, which contradicts the documentation.

Solution

Two approaches are possible:

Modify the framework source code (complex and not recommended).

Define a custom DataSource bean that bypasses the condition. Example:

<code>@Bean
@Primary
public DataSource dataSource(AbstractRoutingDataSource routingDataSource) throws SQLException {
    SpringBootPropertiesConfigurationProperties props = this.ctx.getBean(SpringBootPropertiesConfigurationProperties.class);
    SpringBootShardingRuleConfigurationProperties shardingRule = this.ctx.getBean(SpringBootShardingRuleConfigurationProperties.class);
    List<String> names = getDataSourceNames(environment, "spring.shardingsphere.datasource.");
    Map<String, DataSource> dataSourceMap = new HashMap<>();
    names.forEach(name -> dataSourceMap.put(name, routingDataSource));
    DataSource shardingDataSource = ShardingDataSourceFactory.createDataSource(dataSourceMap, new ShardingRuleConfigurationYamlSwapper().swap(shardingRule), props.getProps());
    return shardingDataSource;
}
</code>

In practice you should also check

spring.shardingsphere.enable

before creating the bean.

After adding the custom bean, the application starts correctly and the sharding and encryption features work together as expected.

Related Topics

sharding-jdbc oracle pitfalls, SpringBoot sharding‑sphere tutorials, data masking custom algorithms, Spring Cloud Sentinel, Nacos security, Gateway predicates, etc.

JavaSpring BootShardingSpheredatabase shardingdata encryption
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.