java - 找不到映射描述。请配置 JdbcType 将缓存 'PersonCache' 与 JdbcPojoStore 关联 ERROR

标签 java mysql caching gridgain ignite

我使用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 + 
        "]"; 
} 
} 

最佳答案

看起来缓存的类型元数据未配置。

请检查CacheConfiguration类。它应该包含下一个方法:

/**
 * 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("PUBLIC");
    jdbcType.setDatabaseTable("PERSON");
    jdbcType.setKeyType("org.apache.ignite.PersonKey");
    jdbcType.setValueType("org.apache.ignite.Person");
    jdbcType.setKeyFields(
            new JdbcTypeField(Types.NUMERIC, "ID", long.class, "id")
    );
    jdbcType.setValueFields(
            new JdbcTypeField(Types.VARCHAR, "FIRST_NAME", String.class, "firstName"),
            new JdbcTypeField(Types.VARCHAR, "LAST_NAME", String.class, "lastName"),
            new JdbcTypeField(Types.DOUBLE, "SALARY", Double.class, "salary")
    );
    return jdbcType;
}

按以下方式在“缓存”方法中使用:

// Configure JDBC types.
Collection<JdbcType> jdbcTypes = new ArrayList<>();
jdbcTypes.add(jdbcTypePerson(cacheName));
storeFactory.setTypes(jdbcTypes.toArray(new JdbcType[jdbcTypes.size()]));

该配置非常适合我使用 H2 数据库。

如果我的回答对您没有帮助,请提供您的示例的完整源代码。

编辑:

您在 JdbcType 和 QueryEntity 配置中错误配置了键类型和值类型。

所描述的配置和 POJO 类具有不同的包。

更改以下描述:

jdbcType.setKeyType("org.apache.ignite.schema.PersonKey"); 
jdbcType.setValueType("org.apache.ignite.schema.Person"); 

jdbcType.setKeyType("apache.ignite.schemas.PersonKey"); 
jdbcType.setValueType("apache.ignite.schemas.Person"); 

qryEntity.setKeyType("org.apache.ignite.schema.PersonKey"); 
qryEntity.setValueType("org.apache.ignite.schema.Person"); 

qryEntity.setKeyType("apache.ignite.schemas.PersonKey"); 
qryEntity.setValueType("apache.ignite.schemas.Person"); 

关于java - 找不到映射描述。请配置 JdbcType 将缓存 'PersonCache' 与 JdbcPojoStore 关联 ERROR,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36274636/

相关文章:

php - Vagrant : Unable to create sessions, 缓存中的 Cakephp,缓存模型

java - 尽管值正确,JSpinner 显示的时间仍具有恒定的小时偏移量

java - 反序列化对象 - 类已更改

java - SoftReference<String> 内存不足时未进行垃圾回收

mysql - SQL 分组项的最大平均值

mysql 最大严格模式

c++ - 您如何解释缓存未命中的 cachegrind 输出?

java - 将 2 个反斜杠替换为一个

mysql - 在对索引列进行排序时,如何避免在具有大表的 MySQL 中选择糟糕的执行计划?

caching - CSS 文件未在 Azure 部署/发布上更新