Ignite使用Date类型作为主键创建表失败问题求助
Let’s break down the issue and walk through the solutions to get your table creation working with a DATE primary key.
First, Recap the Test Scenarios
Working Case: TIMESTAMP as Primary Key
I started by testing a table with a TIMESTAMP primary key, which executed without any hiccups:
0: jdbc:ignite:thin://127.0.0.1/> create table t2(i timestamp primary key, i2 date); No rows affected (0.099 seconds) 0: jdbc:ignite:thin://127.0.0.1/> INSERT INTO T2 (I, I2) VALUES (timestamp '2017-10-12 21:22:24',timestamp '2017-10-12 21:22:23'); 1 row affected (0.009 seconds) 0: jdbc:ignite:thin://127.0.0.1/> select * from t2; +--------------------------------+--------------------------------+ | I | I2 | +--------------------------------+--------------------------------+ | 2017-10-12 21:22:23.0 | Fri Nov 11 00:00:00 MSK 2011 | | 2017-10-12 21:22:24.0 | Thu Oct 12 00:00:00 MSK 2017 | +--------------------------------+--------------------------------+
Failed Case: DATE as Primary Key
When switching to DATE as the primary key, we hit this error during table creation:
0: jdbc:ignite:thin://127.0.0.1/> create table t3 (i date primary key, i2 int); Error: class org.apache.ignite.IgniteCheckedException: Failed to find value class in the node classpath (use default marshaller to enable binary objects) : SQL_PUBLIC_T3_203867a5_800b_4821_9690_e8902ca7b8e1 (state=50000,code=0) java.sql.SQLException: class org.apache.ignite.IgniteCheckedException: Failed to find value class in the node classpath (use default marshaller to enable binary objects) : SQL_PUBLIC_T3_203867a5_800b_4821_9690_e8902ca7b8e1 at org.apache.ignite.internal.jdbc.thin.JdbcThinConnection.sendRequest(JdbcThinConnection.java:648) at org.apache.ignite.internal.jdbc.thin.JdbcThinStatement.execute0(JdbcThinStatement.java:130) at org.apache.ignite.internal.jdbc.thin.JdbcThinStatement.execute(JdbcThinStatement.java:299) at sqlline.Commands.execute(Commands.java:823) at sqlline.Commands.sql(Commands.java:733) at sqlline.SqlLine.dispatch(SqlLine.java:795) at sqlline.SqlLine.begin(SqlLine.java:668) at sqlline.SqlLine.start(SqlLine.java:373) at sqlline.SqlLine.main(SqlLine.java:265)
Why This Happens
The error boils down to how Ignite handles non-standard primary key types. When you use DATE as a primary key, Ignite dynamically generates a value class for the table. But if your Ignite node isn’t configured to use the Binary Marshaller, it can’t load this dynamically generated class because it’s not present in the node’s classpath. TIMESTAMP works because it’s handled as a primitive-like type in Ignite’s SQL layer, avoiding this class generation step.
Proven Solutions
1. Enable the Binary Marshaller (Recommended Fix)
The simplest and most robust fix is to configure your Ignite node to use the Binary Marshaller, which is designed to handle these dynamically generated classes. Update your ignite-config.xml with these settings:
<bean class="org.apache.ignite.configuration.IgniteConfiguration"> <!-- Enable Binary Marshaller to handle dynamic classes --> <property name="marshaller"> <bean class="org.apache.ignite.binary.BinaryMarshaller"/> </property> <!-- Optional: Optimize binary type handling --> <property name="binaryConfiguration"> <bean class="org.apache.ignite.configuration.BinaryConfiguration"> <property name="compactFooter" value="true"/> </bean> </property> </bean>
After updating the config, restart your Ignite nodes, and you should be able to create the table with a DATE primary key without issues.
2. Use TIMESTAMP as a Workaround
If you can’t modify the Ignite configuration right away, you can switch to using TIMESTAMP as the primary key instead of DATE, as shown in the working test case. This avoids the class generation problem entirely.
3. Define a Custom Value Class (Advanced)
For more control, you can create a custom Java class that represents your table’s structure, then reference it when creating the table. This ensures the class is present in the node’s classpath.
First, create the class:
import org.apache.ignite.cache.query.annotations.QuerySqlField; public class T3Record { @QuerySqlField(primaryKey = true) private java.sql.Date i; @QuerySqlField private int i2; // Add constructors, getters, and setters here }
Then, create the table using this class:
CREATE TABLE t3 WITH "valueType=com.your.package.T3Record";
内容的提问来源于stack exchange,提问作者aryndin

