FAQ

1. Why do Compilation Errors arise When Reading Sources?

The answer is:

Sharding-JDBC uses lombok to implement minimal code. For details, please refer to lombok.

Sharding-JDBC-orchestration module needs to perform MVN install command to generate gRPC-related Java file according to the protobuf file.

2. How to solve the Error of Cloud not resolve placeholder … in string value …?

The answer is:

For the inline expressions the Spring configuration file use a Groovy syntax, whose variable operator is ${} same with Spring default placeholder, so it is necessary to increase something in the configuration file:

<context:property-placeholder location="classpath:conf/conf.properties" ignore-unresolvable="true" />

3. Why does the inline expression return a floating point number as a result?

The answer is:

In Java, the division result of two integers is an integer, but in the inline expression, the division result is a floating point number by using of an integer by using Groovy syntax. To return an integer, you need to change A/B to A.intdiv(B).

4. Why is the result not correct when using Proxool.

The answer is:

使用Proxool配置多个数据源时,应该为每个数据源设置alias,因为Proxool在获取连接时会判断连接池中是否包含已存在的alias,不配置alias会造成每次都只从一个数据源中获取连接。

以下是Proxool源码中ProxoolDataSource类getConnection方法的关键代码:

    if(!ConnectionPoolManager.getInstance().isPoolExists(this.alias)) {
        this.registerPool();
    }

Read more details on alias, refer to Proxool

PS: To visit sourceforge web, you need the VPN。

5. Why is an exception thrown when the aggregate column without an alias is used in SQLSever and PostgreSQL?

The answer is:

SQLServer and PostgreSQL will rename the aggregate column without an alias. For example, the following SQL:

SELECT SUM(num), SUM(num2) FROM table_xxx;

SQLServer gets the column of empty string and (2), and PostgreSQL gets the columns of empty sum and sum(2), which will cause Sharding-JDBC to fail to find the corresponding column when the result is merged.

The correct SQL is:

SELECT SUM(num) AS sum_num, SUM(num2) AS sum_num2 FROM table_xxx;

6. Why does the version prior to 1.5.x support OR and the version after 1.5.x no longer support?

The answer is: OR is not supported perfectly before 1.5.x, there will be some problems in complex cases. Its parsing and routing are bothersome, and is very unsuitable to use in distributed databases, which can greatly affect performance. It is necessary to disassemble the combination of OR and AND into all ANDs to correctly execute the SQL. For example:

WHERE (a=? OR b=?) AND c=?

to be disassemble into:

WHERE a=? AND c=?
WHERE b=? AND c=?

to execute.

Another example:

WHERE id=1 OR status=‘OK’

If the ID is a Sharding column, what should you do with the SQL?

First, we need to route to the DB or table containing the rows of id=1. Second, because of OR, we need to fetch all the rows of status= ‘OK’ from all the databases and tables. Finally, we merge the data sets. Therefore, SQL must be split into two SQLs, one for WHERE id=1, and the other for status= ‘OK’, and their Sharding routing is completely different. If you have more OR and AND combinations, you have to create multidimensional recursion trees.. The distributed database cannot accept this low performance, so Sharding-JDBC prefer to not support OR.

7. How to debug SQL if it is not executed correctly in Sharding-JDBC?

The answer is:

The version after Sharding-JDBC 1.5.0 supports to configure sql.show which can print the parsing of SQL, rewriting of SQL, and final routing information to the info log. The configuration of sql.show is OFF by default. To configure it ON, please refer to the configuration manual for details.

8. Do you need to configure tables without Sharding into sharding rules, if you only have partial databases or tables for Sharding?

The answer is:

Yes. Because Sharding-JDBC combines multiple data sources into a single logical data source. Therefore, Sharding-JDBC can not route those tables not configured in configuration rules.

But Sharding-JDBC provides two other ways to simplify the configuration.

Method 1: To configure default-data-source, thus if Sharding-JDB does not find correct Sharding data source for tables, it will route the tables to the default data source.

Method 2: We can configure the datasources with Sharding and without Sharding in Sharding-JDBC, and to use different data sources in the application to handle the case of Sharding or not.

9. Why does Sharding-JDBC provide the primary key generated by the default distributed auto-increment primary strategy is not continuous, and its mantissa mostly is even?

The answer is:

Sharding-JDBC uses the snowflake algorithm as the default distributed self-increasing primary key strategy to decentralized compute the unique self-increment primary key. Therefore, self-increment primary key can be increasing but not sequential.

The last four bits of the primary key computed by the snowflake algorithm represent the incremental values in one millisecond. Therefore, if the concurrency of applications is not high in one millisecond, the chance of the last four being zero are high.

10. Why does a ClassCastException: Integer can not cast to Long arise where i specify a SingleKeyTableShardingAlgorithm generic for Long Type ?

The answer is:

To ensure that the type of Sharding column in the database are consistent with the type of columns in the Sharding algorithm. For example, the column type in the database is int(11) and the Sharding column is Integer. If the Sharding column is Long, the column type in the database is bigint.

11. Does Sharding-JDBC support native self-incrementing primary keys in addition to supporting distributed self-incrementing primary keys?

The answer is:

Yes. However, there are restrictions on the use of native self-increment primary keys, which means that you cannot use native self-increment primary keys as Sharding columns at the same time.

Because Sharding-JDBC does not know the table structure, and native self-increment primary key is not included in the original SQL, so that Sharding-JDBC cannot parse the key into Sharding column, resulting in SQL being routed to multiple tables. When the INSERT SQL is routed to one table, the native self-increment primary key has a value; When the INSERT SQL is routed to more than one table, it will be 0.

12. Why does the Oracle throw an exception “Order by value must implements Comparable” when you use the Order By statement including Timestamp column?

The answer is:

Two solutions: 1. Configure JVM parameters “-oracle.jdbc.J2EE13Compliant=true” 2. Set System.getProperties().setProperty(“oracle.jdbc.J2EE13Compliant”, “true”) in the project initial step;

The reason is:

com.dangdang.ddframe.rdb.sharding.merger.orderby.OrderByValue#getOrderValues():

    private List<Comparable<?>> getOrderValues() throws SQLException {
        List<Comparable<?>> result = new ArrayList<>(orderByItems.size());
        for (OrderItem each : orderByItems) {
            Object value = resultSet.getObject(each.getIndex());
            Preconditions.checkState(null == value || value instanceof Comparable, "Order by value must implements Comparable");
            result.add((Comparable<?>) value);
        }
        return result;
    }

Because of using resultSet.getObject(int index),TimeStamp oracle will decide to return java.sql.TimeStamp or oralce.sql.TIMESTAMP according to oracle.jdbc.J2EE13Compliant.

More detail, please refer to the ojdb sourcecode of coracle.jdbc.driver.TimestampAccessor#getObject(int var1):

    Object getObject(int var1) throws SQLException {
        Object var2 = null;
        if(this.rowSpaceIndicator == null) {
            DatabaseError.throwSqlException(21);
        }

        if(this.rowSpaceIndicator[this.indicatorIndex + var1] != -1) {
            if(this.externalType != 0) {
                switch(this.externalType) {
                case 93:
                    return this.getTimestamp(var1);
                default:
                    DatabaseError.throwSqlException(4);
                    return null;
                }
            }

            if(this.statement.connection.j2ee13Compliant) {
                var2 = this.getTimestamp(var1);
            } else {
                var2 = this.getTIMESTAMP(var1);
            }
        }

        return var2;
    }

13. Why can not find xsd when using Spring namespace?

The answer is:

Deploying an XSD file to a public web address is not the requirement of the Spring namespace usage specification, but some users have such requirements, so we deploy the XSD file to the Sharding-JDBC website. In fact, META-INF\spring.schemas in the jar package of sharding-jdbc-core-config-spring configures the position of xsd file:META-INF\namespace\sharding.xsd和META-INF\namespace\master-slave.xsd.