Ignite Sping + Ignite SQL ClassCastException - PullRequest
0 голосов
/ 17 декабря 2018

Каждый раз, когда я пытаюсь использовать Ignite Spring API и Ignite SQL API взаимозаменяемо, я получаю исключения приведения к классу или «таблица sql не найдена для xxxx»

Это произошло потому, что я создал кеш, используя ignite spring ипытался использовать данные с помощью Ignite SQL API или наоборот:

@Configuration
@EnableIgniteRepositories("local.teste.is.api.repositories")
public class SpringAppCfg {

    @Bean
    public Ignite igniteInstance() {
        IgniteConfiguration cfg = new IgniteConfiguration();

        cfg.setIgniteInstanceName("springDataNode");
        cfg.setPeerClassLoadingEnabled(true);
        cfg.setClientMode(true);

        ...

        // Defining and creating a new cache to be used by Ignite Spring Data
        // repository.
        CacheConfiguration ccfg = new CacheConfiguration("SQL_PUBLIC_SAMPLETYPE3");

        // Setting SQL schema for the cache.
        ccfg.setIndexedTypes(Integer.class, SampleType.class);

        cfg.setCacheConfiguration(ccfg);

        Ignite ignite = Ignition.start(cfg);

        IgniteCache cache = ignite.getOrCreateCache(ccfg);

        SqlQuery sql = new SqlQuery(SampleType.class, "true");

        try (QueryCursor<Entry<Integer, SampleType>> cursor = cache.query(sql)) {
              for (Entry<Integer, SampleType> e : cursor)
                System.out.println(e.getValue().toString());
            }


        return ignite;
    }

SampleTypeRepository:

package local.teste.is.api.repositories;

import org.apache.ignite.springdata.repository.IgniteRepository;
import org.apache.ignite.springdata.repository.config.RepositoryConfig;

import local.al40.is.api.entities.SampleType;

@RepositoryConfig(cacheName = "SQL_PUBLIC_SAMPLETYPE")
public interface SampleTypeRepository extends IgniteRepository<SampleType, Integer>  {

    public SampleType getSampleTypeBySampleTypeId(Integer id);

}

Все, что использует ignite Spring, работает,включая сохранение и чтение данных:

public class Application {

private static AnnotationConfigApplicationContext dataCtx;
private static SampleTypeRepository repo;

public static void main(String[] args) throws Exception {

    dataCtx = new AnnotationConfigApplicationContext();

    // Explicitly registering Spring configuration.
    dataCtx.register(SpringAppCfg.class);
    dataCtx.refresh();

    repo = dataCtx.getBean(SampleTypeRepository.class);

    System.out.println(repo);

    SampleType s = new SampleType(1, "teste");

    repo.save(s.getSampleTypeId(), s);

    System.out.println(repo.getSampleTypeBySampleTypeId(1).getSampleTypeName());

Это происходит, если я создаю таблицу Ignite SQL через DDL и пытаюсь использовать ее через Ignite Spring, предоставляя мне ClassCastException вроде "... ignite.IgniteRepositoryImpl# 123456 невозможно привести к SampleType.class ".Это приводит меня к мысли, что это проблема, связанная с сериализацией.Это также дает мне «таблица SQL не найдена для xxxx», если я создаю таблицу с помощью Ignite Spring и пытаюсь запросить ее.Кто-то пытался объединить эти две перспективы?Примеры, которые я нашел в Интернете, предполагают только кеши, созданные с помощью Ignite Spring, а документация Ignite дает понять, что такой обмен возможен и прозрачен.Однако, по-видимому, это не так, если я не забуду кое-что.

С уважением,

Карлос Коста

Ответы [ 2 ]

0 голосов
/ 17 декабря 2018

Хорошо, я решил свою проблему.Спасибо всем за вашу помощь.В целях дальнейшего разъяснения моего довольно сложного сомнения я напишу следующие рекомендации, которые следует учитывать при взаимозаменяемости попыток использовать Ignite SQL и Ignite Spring:

Вариант 1) Создание кэшейчерез Ignite Spring:

a) Четко определите имя кэша в классе репозитория:

...
@RepositoryConfig(cacheName = "My Cache Name")
public interface SampleTypeRepository extends IgniteRepository<SampleType, Integer>  {

    public SampleType getSampleTypeBySampleTypeId(Integer id);

}

b) Определите кэш и индексируйте его при настройке экземпляра Ignite в приложении Spring:

...
CacheConfiguration ccfg = new CacheConfiguration("My Chache Name");

// Setting SQL schema for the cache.
ccfg.setIndexedTypes(Integer.class, SampleType.class);

config.setCacheConfiguration(ccfg);

Ignite ignite = Ignition.start(config);
...

c) Сделайте запрос, но имейте в виду, что по какой-то причине имя таблицы SQL - "SampleType", а не "My Cache Name".Я не знаю, ehy, но, похоже, это поведение по умолчанию, которое я не нашел явно в документации Ignite Spring.В противном случае вы можете получить «таблица SQL не найдена для»:

...
IgniteCache cache = ignite.cache("My Chache Name");

        SqlFieldsQuery  sql = new SqlFieldsQuery("select * from SampleType");
        try (QueryCursor<List<?>> cursor = cache.query(sql)) {
              for (List<?> e : cursor)
                System.out.println(e.get(1));
            }

Вариант 2) Создание кешей с помощью DDL SQL:

a) Создайте таблицу / кеш SQLпутем четкого определения cache_name, key_type и value_type, используя полные имена пакетов для классов, соответствующих ключу и типам значений:

CREATE TABLE IF NOT EXISTS SampleType(SampleTypeID int, SampleTypeName varchar, PRIMARY KEY (SampleTypeID)) WITH "cache_name=mycachename, key_type=java.lang.Integer, value_type=local.teste.is.api.entities.SampleType";

b) Для вставки данных с помощью ignite Spring работает как шарм, используяМетоды API показаны в документации.Однако, вставляя через DDL или JDBC, вы должны четко определить атрибут _KEY (скрытый атрибут: P):

INSERT INTO SampleType(_KEY, SAMPLETYPEID, SAMPLETYPENAME) VALUES(?,?,?)

Затем, я думаю, вы можете использовать эти API взаимозаменяемо.

С уважением, Карлос Коста

0 голосов
/ 17 декабря 2018

Вы пробовали импортировать Cache.Entry вместо Map.Entry?К сожалению, я не вижу ваши списки импорта, но я подозреваю, что вы можете заменить последние на прежние, чтобы ваш код заработал.

...