我使用 apache ignite 的 import-schema 工具创建了一个 mysql 数据库(数据库为 PERSON,表名为 person,与 H2 示例中给出的类似)并生成 java 文件(CacheConfig.java、PersonKey.java , Person.java) 和 ignite-type-metadata.xml 文件。我编写了一个类似的程序(如自动持久性主题 - Demo.java 中给出的),如下所示。但是当我运行它时,我得到了错误:
Failed to execute job [jobId=37be440c351-3d8e0b33-f744-4765-8c96-962dbe0248ad, ses=GridJobSessionImpl [ses=GridTaskSessionImpl [taskName=o.a.i.i.processors.cache.GridCacheAdapter$LoadCacheJob, dep=GridDeployment [ts=1459219659857, depMode=SHARED, clsLdr=sun.misc.Launcher$AppClassLoader@23137792, clsLdrId=27be440c351-3d8e0b33-f744-4765-8c96-962dbe0248ad, userVer=0, loc=true, sampleClsName=o.a.i.i.processors.cache.GridCacheAdapter$LoadCacheJob, pendingUndeploy=false, undeployed=false, usage=2], taskClsName=o.a.i.i.processors.cache.GridCacheAdapter$LoadCacheJob, sesId=17be440c351-3d8e0b33-f744-4765-8c96-962dbe0248ad, startTime=1459219659857, endTime=9223372036854775807, taskNodeId=3d8e0b33-f744-4765-8c96-962dbe0248ad, clsLdr=sun.misc.Launcher$AppClassLoader@23137792, closed=false, cpSpi=null, failSpi=null, loadSpi=null, usage=1, fullSup=false, subjId=3d8e0b33-f744-4765-8c96-962dbe0248ad, mapFut=IgniteFuture [orig=GridFutureAdapter [resFlag=0, res=null, startTime=1459219659938, endTime=0, ignoreInterrupts=false, lsnr=null, state=INIT]]], jobId=37be440c351-3d8e0b33-f744-4765-8c96-962dbe0248ad]]
class org.apache.ignite.IgniteException: javax.cache.CacheException: Failed to find mapping description [cache=PersonCache, typeId=class apache.ignite.schemas.PersonKey]. Please configure JdbcType to associate cache 'PersonCache' with JdbcPojoStore.
如何解决?
这是运行示例的 DemoDemo.java:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.cache.Cache;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.IgniteException;
import org.apache.ignite.Ignition;
import org.apache.ignite.cache.store.jdbc.CacheJdbcPojoStore;
import org.apache.ignite.cache.store.jdbc.CacheJdbcPojoStoreFactory;
import org.apache.ignite.cache.store.jdbc.dialect.MySQLDialect;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.transactions.Transaction;
import org.h2.jdbcx.JdbcConnectionPool;
/**
* This demo demonstrates the use of cache with {@link CacheJdbcPojoStore}
* together with automatic Ignite schema-import utility.
* <p>
* This Demo can work stand-alone. You can also choose to start
* several {@link DemoNode} instances as well to form a cluster.
*/
public class DemoDemo {
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://localhost/PERSON";
static final String USER = "root";
static final String PASS = "mysql";
/**
* Constructs and returns a fully configured instance of a {@link CacheJdbcPojoStoreFactory}.
*/
private static class MySQLDemoStoreFactory<K, V> extends CacheJdbcPojoStoreFactory<K, V> {
// {@inheritDoc}
@Override public CacheJdbcPojoStore<K, V> create() {
setDialect(new MySQLDialect());
setDataSource(JdbcConnectionPool.create("jdbc:mysql://localhost/PERSON", "root", "mysql"));
return super.create();
}
}
/**
* Executes demo.
*
* @param args Command line arguments, none required.
* @throws IgniteException If example execution failed.
*/
public static void main(String[] args) throws IgniteException {
System.out.println(">>> Start demo...");
Connection conn = null;
Statement stmt = null;
//STEP 2: Register JDBC driver
try {
Class.forName("com.mysql.jdbc.Driver");
//STEP 3: Open a connection
System.out.println("Connecting to database...");
conn = DriverManager.getConnection(DB_URL,USER,PASS);
//STEP 4: Execute a query
System.out.println("Creating statement...");
stmt = conn.createStatement();
String sql;
sql = "SELECT id, first_name, last_name FROM PERSON";
ResultSet rs = stmt.executeQuery(sql);
//STEP 5: Extract data from result set
while(rs.next()){
//Retrieve by column name
int id = rs.getInt("id");
String firstName = rs.getString("first_name");
String lastName = rs.getString("last_name");
//Display values
System.out.print("ID: " + id);
System.out.print(", First: " + firstName);
System.out.println(", Last: " + lastName);
}
}catch(SQLException se){
//Handle errors for JDBC
se.printStackTrace();
}catch(Exception e){
//Handle errors for Class.forName
e.printStackTrace();
}finally{
//finally block used to close resources
try{
if(stmt!=null)
stmt.close();
}catch(SQLException se2){
}// nothing we can do
try{
if(conn!=null)
conn.close();
}catch(SQLException se){
se.printStackTrace();
}
}
// Start Ignite node.
try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) {
// Configure cache store.
CacheConfiguration<PersonKey, Person> cfg =
CacheConfig.cache("PersonCache", new MySQLDemoStoreFactory<PersonKey, Person>());
try (IgniteCache<PersonKey, Person> cache = ignite.getOrCreateCache(cfg)) {
// Preload cache from database.
preload(cache);
// Read-through from database
// and store in cache.
readThrough(cache);
// Perform transaction and
// write-through to database.
transaction(ignite, cache);
}
}
}
/**
* Demonstrates cache preload from database.
*/
private static void preload(IgniteCache<PersonKey, Person> cache) {
System.out.println();
System.out.println(">>> Loading entries from database.");
// Preload all person keys that are less than or equal to 3.
cache.loadCache(null, PersonKey.class.getName(), "select * from PERSON where ID <= 3");
for (Cache.Entry<PersonKey, Person> person : cache)
System.out.println(">>> Loaded Person: " + person);
}
/**
* Demonstrates cache read through from database.
*/
private static void readThrough(IgniteCache<PersonKey, Person> cache) {
PersonKey key = new PersonKey(4);
System.out.println();
System.out.println(">>> Read-through person from database for ID: " + key.getId());
// Check that person with ID=4 is not in cache.
Person p = cache.localPeek(key);
assert p == null;
// Read-through form database.
p = cache.get(new PersonKey(4));
System.out.println(">>> Loaded person from database: " + p);
}
/**
* Demonstrates cache transaction joining database transaction.
*/
private static void transaction(Ignite ignite, IgniteCache<PersonKey, Person> cache) {
PersonKey key = new PersonKey(5);
System.out.println();
System.out.println(">>> Update salary and write-through to database for person with ID: " + key.getId());
try (Transaction tx = ignite.transactions().txStart()) {
// Read-through from database.
Person p = cache.get(key);
System.out.println(">>> Loaded person from database: " + p);
double salary = p.getSalary();
// Raise salary by 20%.
p.setSalary(salary * 1.2);
// Write-through to database
// and store in cache.
cache.put(key, p);
tx.commit();
}
System.out.println(">>> Updated person: " + cache.get(key));
}
}
这是我的 CacheConfig.java :
package apache.ignite.schemas;
import java.sql.*;
import java.util.*;
import org.apache.ignite.cache.*;
import org.apache.ignite.cache.store.jdbc.*;
import org.apache.ignite.configuration.*;
/**
* CacheConfig definition.
*
* Code generated by Apache Ignite Schema Import utility: 03/28/2016.
*/
public class CacheConfig {
/**
* Create JDBC type for Person.
*
* @param cacheName Cache name.
* @return Configured JDBC type.
*/
private static JdbcType jdbcTypePerson(String cacheName) {
JdbcType jdbcType = new JdbcType();
jdbcType.setCacheName(cacheName);
jdbcType.setDatabaseSchema("PERSON");
jdbcType.setDatabaseTable("Person");
jdbcType.setKeyType("org.apache.ignite.schema.PersonKey");
jdbcType.setValueType("org.apache.ignite.schema.Person");
// Key fields for Person.
Collection<JdbcTypeField> keys = new ArrayList<>();
keys.add(new JdbcTypeField(Types.INTEGER, "id", int.class, "id"));
jdbcType.setKeyFields(keys.toArray(new JdbcTypeField[keys.size()]));
// Value fields for Person.
Collection<JdbcTypeField> vals = new ArrayList<>();
vals.add(new JdbcTypeField(Types.INTEGER, "id", int.class, "id"));
vals.add(new JdbcTypeField(Types.VARCHAR, "first_name", String.class, "firstName"));
vals.add(new JdbcTypeField(Types.VARCHAR, "last_name", String.class, "lastName"));
vals.add(new JdbcTypeField(Types.DOUBLE, "salary", double.class, "salary"));
jdbcType.setValueFields(vals.toArray(new JdbcTypeField[vals.size()]));
return jdbcType;
}
/**
* Create SQL Query descriptor for Person.
*
* @return Configured query entity.
*/
private static QueryEntity queryEntityPerson() {
QueryEntity qryEntity = new QueryEntity();
qryEntity.setKeyType("org.apache.ignite.schema.PersonKey");
qryEntity.setValueType("org.apache.ignite.schema.Person");
// Query fields for Person.
LinkedHashMap<String, String> fields = new LinkedHashMap<>();
fields.put("id", "int");
fields.put("firstName", "String");
fields.put("lastName", "String");
fields.put("salary", "double");
qryEntity.setFields(fields);
// Indexes for Person.
Collection<QueryIndex> idxs = new ArrayList<>();
idxs.add(new QueryIndex("id", true, "PRIMARY"));
qryEntity.setIndexes(idxs);
return qryEntity;
}
/**
* Configure cache.
*
* @param cacheName Cache name.
* @param storeFactory Cache store factory.
* @return Cache configuration.
*/
public static <K, V> CacheConfiguration<K, V> cache(String cacheName, CacheJdbcPojoStoreFactory<K, V> storeFactory) {
if (storeFactory == null)
throw new IllegalArgumentException("Cache store factory cannot be null.");
CacheConfiguration<K, V> ccfg = new CacheConfiguration<>(cacheName);
ccfg.setCacheStoreFactory(storeFactory);
ccfg.setReadThrough(true);
ccfg.setWriteThrough(true);
// Configure JDBC types.
Collection<JdbcType> jdbcTypes = new ArrayList<>();
jdbcTypes.add(jdbcTypePerson(cacheName));
storeFactory.setTypes(jdbcTypes.toArray(new JdbcType[jdbcTypes.size()]));
// Configure query entities.
Collection<QueryEntity> qryEntities = new ArrayList<>();
qryEntities.add(queryEntityPerson());
ccfg.setQueryEntities(qryEntities);
return ccfg;
}
}
这是 Person.java :
package apache.ignite.schemas;
import java.io.*;
/**
* Person definition.
*
* Code generated by Apache Ignite Schema Import utility: 03/28/2016.
*/
public class Person implements Serializable {
/** */
private static final long serialVersionUID = 0L;
/** Value for id. */
private int id;
/** Value for firstName. */
private String firstName;
/** Value for lastName. */
private String lastName;
/** Value for salary. */
private double salary;
/**
* Empty constructor.
*/
public Person() {
// No-op.
}
/**
* Full constructor.
*/
public Person(
int id,
String firstName,
String lastName,
double salary
) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.salary = salary;
}
/**
* Gets id.
*
* @return Value for id.
*/
public int getId() {
return id;
}
/**
* Sets id.
*
* @param id New value for id.
*/
public void setId(int id) {
this.id = id;
}
/**
* Gets firstName.
*
* @return Value for firstName.
*/
public String getFirstName() {
return firstName;
}
/**
* Sets firstName.
*
* @param firstName New value for firstName.
*/
public void setFirstName(String firstName) {
this.firstName = firstName;
}
/**
* Gets lastName.
*
* @return Value for lastName.
*/
public String getLastName() {
return lastName;
}
/**
* Sets lastName.
*
* @param lastName New value for lastName.
*/
public void setLastName(String lastName) {
this.lastName = lastName;
}
/**
* Gets salary.
*
* @return Value for salary.
*/
public double getSalary() {
return salary;
}
/**
* Sets salary.
*
* @param salary New value for salary.
*/
public void setSalary(double salary) {
this.salary = salary;
}
/** {@inheritDoc} */
@Override public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof Person))
return false;
Person that = (Person)o;
if (id != that.id)
return false;
if (firstName != null ? !firstName.equals(that.firstName) : that.firstName != null)
return false;
if (lastName != null ? !lastName.equals(that.lastName) : that.lastName != null)
return false;
if (Double.compare(salary, that.salary) != 0)
return false;
return true;
}
/** {@inheritDoc} */
@Override public int hashCode() {
int res = id;
res = 31 * res + (firstName != null ? firstName.hashCode() : 0);
res = 31 * res + (lastName != null ? lastName.hashCode() : 0);
long ig_hash_temp = Double.doubleToLongBits(salary);
res = 31 * res + (int)(ig_hash_temp ^ (ig_hash_temp >>> 32));
return res;
}
/** {@inheritDoc} */
@Override public String toString() {
return "Person [id=" + id +
", firstName=" + firstName +
", lastName=" + lastName +
", salary=" + salary +
"]";
}
}
这是 PersonKey.java :
package apache.ignite.schemas;
import java.io.*;
/**
* PersonKey definition.
*
* Code generated by Apache Ignite Schema Import utility: 03/28/2016.
*/
public class PersonKey implements Serializable {
/** */
private static final long serialVersionUID = 0L;
/** Value for id. */
private int id;
/**
* Empty constructor.
*/
public PersonKey() {
// No-op.
}
/**
* Full constructor.
*/
public PersonKey(
int id
) {
this.id = id;
}
/**
* Gets id.
*
* @return Value for id.
*/
public int getId() {
return id;
}
/**
* Sets id.
*
* @param id New value for id.
*/
public void setId(int id) {
this.id = id;
}
/** {@inheritDoc} */
@Override public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof PersonKey))
return false;
PersonKey that = (PersonKey)o;
if (id != that.id)
return false;
return true;
}
/** {@inheritDoc} */
@Override public int hashCode() {
int res = id;
return res;
}
/** {@inheritDoc} */
@Override public String toString() {
return "PersonKey [id=" + id +
"]";
}
}