[ 
https://issues.apache.org/jira/browse/IGNITE-20024?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

bin.yin updated IGNITE-20024:
-----------------------------
    Description: 
h3. Question:

{{First, I use ??IgniteCache#loadCache?? load from RDBMS. When I use 
IgniteCache.get(key) to get the corresponding entity, ignite throws the 
following error "Can not set java.time.LocalDateTime field 
org.apache.ignite.examples.model.Person.createdTime to java.sql .Timestamp"}}
h3. Conditions and usage:
 # This code run in 'ignite-examples' module;
 # In ignite 2.14.0, I use H2 as the underlying storage;
 # In {{{}CacheJdbcPojoStoreFactory{}}}, I configured the mapping between the 
{{datetime type}} of the database and JDK8's {{{}LocalDateTime{}}}:
{{new JdbcTypeField(Types.TIMESTAMP, "created_time", LocalDateTime.class, 
"createdTime")}}

h3. Problem analysis:

By default, {{CacheJdbcPojoStore}} uses 
{{org.apache.ignite.cache.store.jdbc.JdbcTypesTransformer#getColumnValue}} to 
parse jdbc's ResultSet.
For the {{LocalDateTime}} type of JDK8, {{java.sql.ResultSet#getObject(int)}} 
is used to obtain the value of the specified column (here it is read as 
{{{}java.sql.Timestamp{}}}). When the object is finally constructed, the type 
is inconsistent Causes {{sun.reflect.FieldAccessor#set}} assignment to fail.

 

*Java Code:*

CacheJdbcPojoStore.java:

 
{code:java}
package org.apache.ignite.examples.datagrid.store.auto;

import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.Ignition;
import org.apache.ignite.cache.CacheAtomicityMode;
import org.apache.ignite.cache.store.jdbc.CacheJdbcPojoStoreFactory;
import org.apache.ignite.cache.store.jdbc.JdbcType;
import org.apache.ignite.cache.store.jdbc.JdbcTypeField;
import org.apache.ignite.cache.store.jdbc.dialect.H2Dialect;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.examples.model.Person;
import org.apache.ignite.examples.util.DbH2ServerStartup;
import org.h2.jdbcx.JdbcConnectionPool;

import javax.cache.configuration.Factory;
import javax.sql.DataSource;
import java.sql.Types;
import java.time.LocalDateTime;

/**
 * To start the example, you should:
 * <ul>
 *     <li>Start H2 database TCP server using {@link DbH2ServerStartup}.</li>
 *     <li>Start example using {@link CacheAutoStoreExample}.</li>
 * </ul>
 * <p>
 */
public class CacheJdbcPojoStore {

    private static final String CACHE_NAME = 
CacheJdbcPojoStore.class.getSimpleName();

    public static void main(String[] args) throws Exception {
        DbH2ServerStartup.populateDatabase();
        try (Ignite ignite = Ignition.start("example-ignite.xml")) {
            System.out.println();
            System.out.println(">>> Cache store example started.");



            try (IgniteCache<Long, Person> cache = 
ignite.getOrCreateCache(cacheConfiguration())) {
                cache.loadCache(null, Long.class.getName(), "SELECT * FROM 
PERSON WHERE ID = 3");
                System.out.println(cache.get(3L));

            }
            finally {
                ignite.destroyCache(CACHE_NAME);
            }
        }
    }

    private static CacheConfiguration<Long, Person> cacheConfiguration() {
        CacheConfiguration<Long, Person> cacheCfg = new 
CacheConfiguration<>(CACHE_NAME);
        cacheCfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);

        // Configure JDBC store.
        CacheJdbcPojoStoreFactory<Long, Person> factory = new 
CacheJdbcPojoStoreFactory<>();
        factory.setDialect(new H2Dialect());
        factory.setDataSourceFactory((Factory<DataSource>) () -> {
            return 
JdbcConnectionPool.create("jdbc:h2:tcp://localhost/mem:ExampleDb", "sa", "");
        });

        JdbcType jdbcType = new JdbcType();
        jdbcType.setCacheName(CACHE_NAME);
        jdbcType.setDatabaseTable("PERSON");
        jdbcType.setKeyType(Long.class);
        jdbcType.setValueType(Person.class);
        jdbcType.setKeyFields(new JdbcTypeField(Types.BIGINT, "id", Long.class, 
"id"));
        jdbcType.setValueFields(
                new JdbcTypeField(Types.BIGINT, "id", Long.class, "id"),
                new JdbcTypeField(Types.VARCHAR, "first_name", String.class, 
"firstName"),
                new JdbcTypeField(Types.VARCHAR, "last_name", String.class, 
"lastName"),
                new JdbcTypeField(Types.TIMESTAMP, "created_time", 
LocalDateTime.class, "createdTime")
        );

        factory.setTypes(jdbcType);
        cacheCfg.setCacheStoreFactory(factory);

        cacheCfg.setIndexedTypes(Long.class, Person.class);

        return cacheCfg;
    }

}
{code}
Person.java:

 
{code:java}
package org.apache.ignite.examples.model;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.ignite.cache.affinity.AffinityKey;
import org.apache.ignite.cache.query.annotations.QuerySqlField;
import org.apache.ignite.cache.query.annotations.QueryTextField;

/**
 * Person class.
 */
public class Person implements Serializable {
    /** */
    private static final AtomicLong ID_GEN = new AtomicLong();

    /** Name of index by two fields (orgId, salary). */
    public static final String ORG_SALARY_IDX = "ORG_SALARY_IDX";

    /** Person ID (indexed). */
    @QuerySqlField(index = true)
    public Long id;

    /** Organization ID (indexed). */
    @QuerySqlField(index = true, orderedGroups = @QuerySqlField.Group(name = 
ORG_SALARY_IDX, order = 0))
    public Long orgId;

    /** First name (not-indexed). */
    @QuerySqlField
    public String firstName;

    /** Last name (not indexed). */
    @QuerySqlField
    public String lastName;

    @QuerySqlField
    public LocalDateTime createdTime;

    /** Resume text (create LUCENE-based TEXT index for this field). */
    @QueryTextField
    public String resume;

    /** Salary (indexed). */
    @QuerySqlField(index = true, orderedGroups = @QuerySqlField.Group(name = 
ORG_SALARY_IDX, order = 1))
    public double salary;

    /** Custom cache key to guarantee that person is always colocated with its 
organization. */
    private transient AffinityKey<Long> key;

    /**
     * Default constructor.
     */
    public Person() {
        // No-op.
    }

    /**
     * Constructs person record.
     *
     * @param org       Organization.
     * @param firstName First name.
     * @param lastName  Last name.
     * @param salary    Salary.
     * @param resume    Resume text.
     */
    public Person(Organization org, String firstName, String lastName, double 
salary, String resume) {
        // Generate unique ID for this person.
        id = ID_GEN.incrementAndGet();

        orgId = org.id();

        this.firstName = firstName;
        this.lastName = lastName;
        this.createdTime = LocalDateTime.now();
        this.salary = salary;
        this.resume = resume;
    }

    /**
     * Constructs person record.
     *
     * @param id Person ID.
     * @param orgId Organization ID.
     * @param firstName First name.
     * @param lastName Last name.
     * @param salary    Salary.
     * @param resume    Resume text.
     */
    public Person(Long id, Long orgId, String firstName, String lastName, 
double salary, String resume) {
        this.id = id;
        this.orgId = orgId;
        this.firstName = firstName;
        this.lastName = lastName;
        this.createdTime = LocalDateTime.now();
        this.salary = salary;
        this.resume = resume;
    }

    /**
     * Constructs person record.
     *
     * @param id Person ID.
     * @param firstName First name.
     * @param lastName Last name.
     */
    public Person(Long id, String firstName, String lastName) {
        this.id = id;

        this.firstName = firstName;
        this.lastName = lastName;
        this.createdTime = LocalDateTime.now();
    }

    /**
     * Gets cache affinity key. Since in some examples person needs to be 
collocated with organization, we create
     * custom affinity key to guarantee this collocation.
     *
     * @return Custom affinity key to guarantee that person is always 
collocated with organization.
     */
    public AffinityKey<Long> key() {
        if (key == null)
            key = new AffinityKey<>(id, orgId);

        return key;
    }

    /**
     * {@inheritDoc}
     */
    @Override public String toString() {
        return "Person [id=" + id +
                ", orgId=" + orgId +
                ", lastName=" + lastName +
                ", firstName=" + firstName +
                ", createdTime=" + createdTime +
                ", salary=" + salary +
                ", resume=" + resume + ']';
    }
} {code}
DbH2ServerStartup.java:

 

 
{code:java}
package org.apache.ignite.examples.util;

import java.io.IOException;
import java.io.StringReader;
import java.sql.SQLException;
import org.apache.ignite.IgniteException;
import org.h2.jdbcx.JdbcConnectionPool;
import org.h2.tools.RunScript;
import org.h2.tools.Server;

/**
 * Start H2 database TCP server in order to access sample in-memory database 
from other processes.
 */
public class DbH2ServerStartup {
    /** Create table script. */
    private static final String CREATE_PERSON_TABLE =
        "create table if not exists PERSON(id bigint AUTO_INCREMENT PRIMARY 
KEY, first_name varchar(50), last_name varchar(50), created_time TIMESTAMP 
DEFAULT CURRENT_TIMESTAMP);";

    /** Sample data script. */
    private static final String POPULATE_PERSON_TABLE =
        "delete from PERSON;\n" +
        "insert into PERSON(id, first_name, last_name) values(1, 'Johannes', 
'Kepler');\n" +
        "insert into PERSON(id, first_name, last_name) values(2, 'Galileo', 
'Galilei');\n" +
        "insert into PERSON(id, first_name, last_name) values(3, 'Henry', 
'More');\n" +
        "insert into PERSON(id, first_name, last_name) values(4, 'Polish', 
'Brethren');\n" +
        "insert into PERSON(id, first_name, last_name) values(5, 'Robert', 
'Boyle');\n" +
        "insert into PERSON(id, first_name, last_name) values(6, 'Wilhelm', 
'Leibniz');";

    /**
     * 初始化数据库
     *
     * @throws SQLException if
     */
    public static void populateDatabase() throws SQLException {
        // Try to connect to database TCP server.
        JdbcConnectionPool dataSrc = 
JdbcConnectionPool.create("jdbc:h2:tcp://localhost/mem:ExampleDb", "sa", "");

        // Create Person table in database.
        RunScript.execute(dataSrc.getConnection(), new 
StringReader(CREATE_PERSON_TABLE));

        // Populates Person table with sample data in database.
        RunScript.execute(dataSrc.getConnection(), new 
StringReader(POPULATE_PERSON_TABLE));
    }

    /**
     * Start H2 database TCP server.
     *
     * @param args Command line arguments, none required.
     * @throws IgniteException If start H2 database TCP server failed.
     */
    public static void main(String[] args) throws IgniteException {
        try {
            // Start H2 database TCP server in order to access sample in-memory 
database from other processes.
            Server.createTcpServer("-tcpDaemon").start();
            Server.createWebServer("-webDaemon").start();

            populateDatabase();
        }
        catch (SQLException e) {
            throw new IgniteException("Failed to start database TCP server", e);
        }

        try {
            do {
                System.out.println("Type 'q' and press 'Enter' to stop H2 TCP 
server...");
            }
            while ('q' != System.in.read());
        }
        catch (IOException ignored) {
            // No-op.
        }
    }
}
 {code}
 

 

 

  was:
h3. Question:

First, I use ??IgniteCache#loadCache?? load from RDBMS. When I use 
IgniteCache.get(key) to get the corresponding entity, ignite throws the 
following error "Can not set java.time.LocalDateTime field 
org.apache.ignite.examples.model.Person.createdTime to java.sql .Timestamp"
h3. Conditions and usage:
 # This code run in 'ignite-examples' module;
 # In ignite 2.14.0, I use H2 as the underlying storage;
 # In {{{}CacheJdbcPojoStoreFactory{}}}, I configured the mapping between the 
{{datetime type}} of the database and JDK8's {{{}LocalDateTime{}}}:
{{new JdbcTypeField(Types.TIMESTAMP, "created_time", LocalDateTime.class, 
"createdTime")}}

h3. Problem analysis:

By default, {{CacheJdbcPojoStore}} uses 
{{org.apache.ignite.cache.store.jdbc.JdbcTypesTransformer#getColumnValue}} to 
parse jdbc's ResultSet.
For the {{LocalDateTime}} type of JDK8, {{java.sql.ResultSet#getObject(int)}} 
is used to obtain the value of the specified column (here it is read as 
{{{}java.sql.Timestamp{}}}). When the object is finally constructed, the type 
is inconsistent Causes {{sun.reflect.FieldAccessor#set}} assignment to fail.

 

*Java Code:*

CacheJdbcPojoStore.java:

 
{code:java}
package org.apache.ignite.examples.datagrid.store.auto;

import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.Ignition;
import org.apache.ignite.cache.CacheAtomicityMode;
import org.apache.ignite.cache.store.jdbc.CacheJdbcPojoStoreFactory;
import org.apache.ignite.cache.store.jdbc.JdbcType;
import org.apache.ignite.cache.store.jdbc.JdbcTypeField;
import org.apache.ignite.cache.store.jdbc.dialect.H2Dialect;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.examples.model.Person;
import org.apache.ignite.examples.util.DbH2ServerStartup;
import org.h2.jdbcx.JdbcConnectionPool;

import javax.cache.configuration.Factory;
import javax.sql.DataSource;
import java.sql.Types;
import java.time.LocalDateTime;

/**
 * To start the example, you should:
 * <ul>
 *     <li>Start H2 database TCP server using {@link DbH2ServerStartup}.</li>
 *     <li>Start example using {@link CacheAutoStoreExample}.</li>
 * </ul>
 * <p>
 */
public class CacheJdbcPojoStore {

    private static final String CACHE_NAME = 
CacheJdbcPojoStore.class.getSimpleName();

    public static void main(String[] args) throws Exception {
        DbH2ServerStartup.populateDatabase();
        try (Ignite ignite = Ignition.start("example-ignite.xml")) {
            System.out.println();
            System.out.println(">>> Cache store example started.");



            try (IgniteCache<Long, Person> cache = 
ignite.getOrCreateCache(cacheConfiguration())) {
                cache.loadCache(null, Long.class.getName(), "SELECT * FROM 
PERSON WHERE ID = 3");
                System.out.println(cache.get(3L));

            }
            finally {
                ignite.destroyCache(CACHE_NAME);
            }
        }
    }

    private static CacheConfiguration<Long, Person> cacheConfiguration() {
        CacheConfiguration<Long, Person> cacheCfg = new 
CacheConfiguration<>(CACHE_NAME);
        cacheCfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);

        // Configure JDBC store.
        CacheJdbcPojoStoreFactory<Long, Person> factory = new 
CacheJdbcPojoStoreFactory<>();
        factory.setDialect(new H2Dialect());
        factory.setDataSourceFactory((Factory<DataSource>) () -> {
            return 
JdbcConnectionPool.create("jdbc:h2:tcp://localhost/mem:ExampleDb", "sa", "");
        });

        JdbcType jdbcType = new JdbcType();
        jdbcType.setCacheName(CACHE_NAME);
        jdbcType.setDatabaseTable("PERSON");
        jdbcType.setKeyType(Long.class);
        jdbcType.setValueType(Person.class);
        jdbcType.setKeyFields(new JdbcTypeField(Types.BIGINT, "id", Long.class, 
"id"));
        jdbcType.setValueFields(
                new JdbcTypeField(Types.BIGINT, "id", Long.class, "id"),
                new JdbcTypeField(Types.VARCHAR, "first_name", String.class, 
"firstName"),
                new JdbcTypeField(Types.VARCHAR, "last_name", String.class, 
"lastName"),
                new JdbcTypeField(Types.TIMESTAMP, "created_time", 
LocalDateTime.class, "createdTime")
        );

        factory.setTypes(jdbcType);
        cacheCfg.setCacheStoreFactory(factory);

        cacheCfg.setIndexedTypes(Long.class, Person.class);

        return cacheCfg;
    }

}
{code}
Person.java:

 
{code:java}
package org.apache.ignite.examples.model;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.ignite.cache.affinity.AffinityKey;
import org.apache.ignite.cache.query.annotations.QuerySqlField;
import org.apache.ignite.cache.query.annotations.QueryTextField;

/**
 * Person class.
 */
public class Person implements Serializable {
    /** */
    private static final AtomicLong ID_GEN = new AtomicLong();

    /** Name of index by two fields (orgId, salary). */
    public static final String ORG_SALARY_IDX = "ORG_SALARY_IDX";

    /** Person ID (indexed). */
    @QuerySqlField(index = true)
    public Long id;

    /** Organization ID (indexed). */
    @QuerySqlField(index = true, orderedGroups = @QuerySqlField.Group(name = 
ORG_SALARY_IDX, order = 0))
    public Long orgId;

    /** First name (not-indexed). */
    @QuerySqlField
    public String firstName;

    /** Last name (not indexed). */
    @QuerySqlField
    public String lastName;

    @QuerySqlField
    public LocalDateTime createdTime;

    /** Resume text (create LUCENE-based TEXT index for this field). */
    @QueryTextField
    public String resume;

    /** Salary (indexed). */
    @QuerySqlField(index = true, orderedGroups = @QuerySqlField.Group(name = 
ORG_SALARY_IDX, order = 1))
    public double salary;

    /** Custom cache key to guarantee that person is always colocated with its 
organization. */
    private transient AffinityKey<Long> key;

    /**
     * Default constructor.
     */
    public Person() {
        // No-op.
    }

    /**
     * Constructs person record.
     *
     * @param org       Organization.
     * @param firstName First name.
     * @param lastName  Last name.
     * @param salary    Salary.
     * @param resume    Resume text.
     */
    public Person(Organization org, String firstName, String lastName, double 
salary, String resume) {
        // Generate unique ID for this person.
        id = ID_GEN.incrementAndGet();

        orgId = org.id();

        this.firstName = firstName;
        this.lastName = lastName;
        this.createdTime = LocalDateTime.now();
        this.salary = salary;
        this.resume = resume;
    }

    /**
     * Constructs person record.
     *
     * @param id Person ID.
     * @param orgId Organization ID.
     * @param firstName First name.
     * @param lastName Last name.
     * @param salary    Salary.
     * @param resume    Resume text.
     */
    public Person(Long id, Long orgId, String firstName, String lastName, 
double salary, String resume) {
        this.id = id;
        this.orgId = orgId;
        this.firstName = firstName;
        this.lastName = lastName;
        this.createdTime = LocalDateTime.now();
        this.salary = salary;
        this.resume = resume;
    }

    /**
     * Constructs person record.
     *
     * @param id Person ID.
     * @param firstName First name.
     * @param lastName Last name.
     */
    public Person(Long id, String firstName, String lastName) {
        this.id = id;

        this.firstName = firstName;
        this.lastName = lastName;
        this.createdTime = LocalDateTime.now();
    }

    /**
     * Gets cache affinity key. Since in some examples person needs to be 
collocated with organization, we create
     * custom affinity key to guarantee this collocation.
     *
     * @return Custom affinity key to guarantee that person is always 
collocated with organization.
     */
    public AffinityKey<Long> key() {
        if (key == null)
            key = new AffinityKey<>(id, orgId);

        return key;
    }

    /**
     * {@inheritDoc}
     */
    @Override public String toString() {
        return "Person [id=" + id +
                ", orgId=" + orgId +
                ", lastName=" + lastName +
                ", firstName=" + firstName +
                ", createdTime=" + createdTime +
                ", salary=" + salary +
                ", resume=" + resume + ']';
    }
} {code}
DbH2ServerStartup.java:

 

 
{code:java}
package org.apache.ignite.examples.util;

import java.io.IOException;
import java.io.StringReader;
import java.sql.SQLException;
import org.apache.ignite.IgniteException;
import org.h2.jdbcx.JdbcConnectionPool;
import org.h2.tools.RunScript;
import org.h2.tools.Server;

/**
 * Start H2 database TCP server in order to access sample in-memory database 
from other processes.
 */
public class DbH2ServerStartup {
    /** Create table script. */
    private static final String CREATE_PERSON_TABLE =
        "create table if not exists PERSON(id bigint AUTO_INCREMENT PRIMARY 
KEY, first_name varchar(50), last_name varchar(50), created_time TIMESTAMP 
DEFAULT CURRENT_TIMESTAMP);";

    /** Sample data script. */
    private static final String POPULATE_PERSON_TABLE =
        "delete from PERSON;\n" +
        "insert into PERSON(id, first_name, last_name) values(1, 'Johannes', 
'Kepler');\n" +
        "insert into PERSON(id, first_name, last_name) values(2, 'Galileo', 
'Galilei');\n" +
        "insert into PERSON(id, first_name, last_name) values(3, 'Henry', 
'More');\n" +
        "insert into PERSON(id, first_name, last_name) values(4, 'Polish', 
'Brethren');\n" +
        "insert into PERSON(id, first_name, last_name) values(5, 'Robert', 
'Boyle');\n" +
        "insert into PERSON(id, first_name, last_name) values(6, 'Wilhelm', 
'Leibniz');";

    /**
     * 初始化数据库
     *
     * @throws SQLException if
     */
    public static void populateDatabase() throws SQLException {
        // Try to connect to database TCP server.
        JdbcConnectionPool dataSrc = 
JdbcConnectionPool.create("jdbc:h2:tcp://localhost/mem:ExampleDb", "sa", "");

        // Create Person table in database.
        RunScript.execute(dataSrc.getConnection(), new 
StringReader(CREATE_PERSON_TABLE));

        // Populates Person table with sample data in database.
        RunScript.execute(dataSrc.getConnection(), new 
StringReader(POPULATE_PERSON_TABLE));
    }

    /**
     * Start H2 database TCP server.
     *
     * @param args Command line arguments, none required.
     * @throws IgniteException If start H2 database TCP server failed.
     */
    public static void main(String[] args) throws IgniteException {
        try {
            // Start H2 database TCP server in order to access sample in-memory 
database from other processes.
            Server.createTcpServer("-tcpDaemon").start();
            Server.createWebServer("-webDaemon").start();

            populateDatabase();
        }
        catch (SQLException e) {
            throw new IgniteException("Failed to start database TCP server", e);
        }

        try {
            do {
                System.out.println("Type 'q' and press 'Enter' to stop H2 TCP 
server...");
            }
            while ('q' != System.in.read());
        }
        catch (IOException ignored) {
            // No-op.
        }
    }
}
 {code}
 

 

 


> When MySQL is used as the underlying storage, an exception is thrown "Can not 
> set java.time.LocalDateTime field 
> org.apache.ignite.examples.model.Person.createdTime to java.sql.Timestamp"
> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: IGNITE-20024
>                 URL: https://issues.apache.org/jira/browse/IGNITE-20024
>             Project: Ignite
>          Issue Type: Bug
>          Components: persistence
>            Reporter: bin.yin
>            Assignee: bin.yin
>            Priority: Major
>
> h3. Question:
> {{First, I use ??IgniteCache#loadCache?? load from RDBMS. When I use 
> IgniteCache.get(key) to get the corresponding entity, ignite throws the 
> following error "Can not set java.time.LocalDateTime field 
> org.apache.ignite.examples.model.Person.createdTime to java.sql .Timestamp"}}
> h3. Conditions and usage:
>  # This code run in 'ignite-examples' module;
>  # In ignite 2.14.0, I use H2 as the underlying storage;
>  # In {{{}CacheJdbcPojoStoreFactory{}}}, I configured the mapping between the 
> {{datetime type}} of the database and JDK8's {{{}LocalDateTime{}}}:
> {{new JdbcTypeField(Types.TIMESTAMP, "created_time", LocalDateTime.class, 
> "createdTime")}}
> h3. Problem analysis:
> By default, {{CacheJdbcPojoStore}} uses 
> {{org.apache.ignite.cache.store.jdbc.JdbcTypesTransformer#getColumnValue}} to 
> parse jdbc's ResultSet.
> For the {{LocalDateTime}} type of JDK8, {{java.sql.ResultSet#getObject(int)}} 
> is used to obtain the value of the specified column (here it is read as 
> {{{}java.sql.Timestamp{}}}). When the object is finally constructed, the type 
> is inconsistent Causes {{sun.reflect.FieldAccessor#set}} assignment to fail.
>  
> *Java Code:*
> CacheJdbcPojoStore.java:
>  
> {code:java}
> package org.apache.ignite.examples.datagrid.store.auto;
> import org.apache.ignite.Ignite;
> import org.apache.ignite.IgniteCache;
> import org.apache.ignite.Ignition;
> import org.apache.ignite.cache.CacheAtomicityMode;
> import org.apache.ignite.cache.store.jdbc.CacheJdbcPojoStoreFactory;
> import org.apache.ignite.cache.store.jdbc.JdbcType;
> import org.apache.ignite.cache.store.jdbc.JdbcTypeField;
> import org.apache.ignite.cache.store.jdbc.dialect.H2Dialect;
> import org.apache.ignite.configuration.CacheConfiguration;
> import org.apache.ignite.examples.model.Person;
> import org.apache.ignite.examples.util.DbH2ServerStartup;
> import org.h2.jdbcx.JdbcConnectionPool;
> import javax.cache.configuration.Factory;
> import javax.sql.DataSource;
> import java.sql.Types;
> import java.time.LocalDateTime;
> /**
>  * To start the example, you should:
>  * <ul>
>  *     <li>Start H2 database TCP server using {@link DbH2ServerStartup}.</li>
>  *     <li>Start example using {@link CacheAutoStoreExample}.</li>
>  * </ul>
>  * <p>
>  */
> public class CacheJdbcPojoStore {
>     private static final String CACHE_NAME = 
> CacheJdbcPojoStore.class.getSimpleName();
>     public static void main(String[] args) throws Exception {
>         DbH2ServerStartup.populateDatabase();
>         try (Ignite ignite = Ignition.start("example-ignite.xml")) {
>             System.out.println();
>             System.out.println(">>> Cache store example started.");
>             try (IgniteCache<Long, Person> cache = 
> ignite.getOrCreateCache(cacheConfiguration())) {
>                 cache.loadCache(null, Long.class.getName(), "SELECT * FROM 
> PERSON WHERE ID = 3");
>                 System.out.println(cache.get(3L));
>             }
>             finally {
>                 ignite.destroyCache(CACHE_NAME);
>             }
>         }
>     }
>     private static CacheConfiguration<Long, Person> cacheConfiguration() {
>         CacheConfiguration<Long, Person> cacheCfg = new 
> CacheConfiguration<>(CACHE_NAME);
>         cacheCfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
>         // Configure JDBC store.
>         CacheJdbcPojoStoreFactory<Long, Person> factory = new 
> CacheJdbcPojoStoreFactory<>();
>         factory.setDialect(new H2Dialect());
>         factory.setDataSourceFactory((Factory<DataSource>) () -> {
>             return 
> JdbcConnectionPool.create("jdbc:h2:tcp://localhost/mem:ExampleDb", "sa", "");
>         });
>         JdbcType jdbcType = new JdbcType();
>         jdbcType.setCacheName(CACHE_NAME);
>         jdbcType.setDatabaseTable("PERSON");
>         jdbcType.setKeyType(Long.class);
>         jdbcType.setValueType(Person.class);
>         jdbcType.setKeyFields(new JdbcTypeField(Types.BIGINT, "id", 
> Long.class, "id"));
>         jdbcType.setValueFields(
>                 new JdbcTypeField(Types.BIGINT, "id", Long.class, "id"),
>                 new JdbcTypeField(Types.VARCHAR, "first_name", String.class, 
> "firstName"),
>                 new JdbcTypeField(Types.VARCHAR, "last_name", String.class, 
> "lastName"),
>                 new JdbcTypeField(Types.TIMESTAMP, "created_time", 
> LocalDateTime.class, "createdTime")
>         );
>         factory.setTypes(jdbcType);
>         cacheCfg.setCacheStoreFactory(factory);
>         cacheCfg.setIndexedTypes(Long.class, Person.class);
>         return cacheCfg;
>     }
> }
> {code}
> Person.java:
>  
> {code:java}
> package org.apache.ignite.examples.model;
> import java.io.Serializable;
> import java.time.LocalDateTime;
> import java.util.concurrent.atomic.AtomicLong;
> import org.apache.ignite.cache.affinity.AffinityKey;
> import org.apache.ignite.cache.query.annotations.QuerySqlField;
> import org.apache.ignite.cache.query.annotations.QueryTextField;
> /**
>  * Person class.
>  */
> public class Person implements Serializable {
>     /** */
>     private static final AtomicLong ID_GEN = new AtomicLong();
>     /** Name of index by two fields (orgId, salary). */
>     public static final String ORG_SALARY_IDX = "ORG_SALARY_IDX";
>     /** Person ID (indexed). */
>     @QuerySqlField(index = true)
>     public Long id;
>     /** Organization ID (indexed). */
>     @QuerySqlField(index = true, orderedGroups = @QuerySqlField.Group(name = 
> ORG_SALARY_IDX, order = 0))
>     public Long orgId;
>     /** First name (not-indexed). */
>     @QuerySqlField
>     public String firstName;
>     /** Last name (not indexed). */
>     @QuerySqlField
>     public String lastName;
>     @QuerySqlField
>     public LocalDateTime createdTime;
>     /** Resume text (create LUCENE-based TEXT index for this field). */
>     @QueryTextField
>     public String resume;
>     /** Salary (indexed). */
>     @QuerySqlField(index = true, orderedGroups = @QuerySqlField.Group(name = 
> ORG_SALARY_IDX, order = 1))
>     public double salary;
>     /** Custom cache key to guarantee that person is always colocated with 
> its organization. */
>     private transient AffinityKey<Long> key;
>     /**
>      * Default constructor.
>      */
>     public Person() {
>         // No-op.
>     }
>     /**
>      * Constructs person record.
>      *
>      * @param org       Organization.
>      * @param firstName First name.
>      * @param lastName  Last name.
>      * @param salary    Salary.
>      * @param resume    Resume text.
>      */
>     public Person(Organization org, String firstName, String lastName, double 
> salary, String resume) {
>         // Generate unique ID for this person.
>         id = ID_GEN.incrementAndGet();
>         orgId = org.id();
>         this.firstName = firstName;
>         this.lastName = lastName;
>         this.createdTime = LocalDateTime.now();
>         this.salary = salary;
>         this.resume = resume;
>     }
>     /**
>      * Constructs person record.
>      *
>      * @param id Person ID.
>      * @param orgId Organization ID.
>      * @param firstName First name.
>      * @param lastName Last name.
>      * @param salary    Salary.
>      * @param resume    Resume text.
>      */
>     public Person(Long id, Long orgId, String firstName, String lastName, 
> double salary, String resume) {
>         this.id = id;
>         this.orgId = orgId;
>         this.firstName = firstName;
>         this.lastName = lastName;
>         this.createdTime = LocalDateTime.now();
>         this.salary = salary;
>         this.resume = resume;
>     }
>     /**
>      * Constructs person record.
>      *
>      * @param id Person ID.
>      * @param firstName First name.
>      * @param lastName Last name.
>      */
>     public Person(Long id, String firstName, String lastName) {
>         this.id = id;
>         this.firstName = firstName;
>         this.lastName = lastName;
>         this.createdTime = LocalDateTime.now();
>     }
>     /**
>      * Gets cache affinity key. Since in some examples person needs to be 
> collocated with organization, we create
>      * custom affinity key to guarantee this collocation.
>      *
>      * @return Custom affinity key to guarantee that person is always 
> collocated with organization.
>      */
>     public AffinityKey<Long> key() {
>         if (key == null)
>             key = new AffinityKey<>(id, orgId);
>         return key;
>     }
>     /**
>      * {@inheritDoc}
>      */
>     @Override public String toString() {
>         return "Person [id=" + id +
>                 ", orgId=" + orgId +
>                 ", lastName=" + lastName +
>                 ", firstName=" + firstName +
>                 ", createdTime=" + createdTime +
>                 ", salary=" + salary +
>                 ", resume=" + resume + ']';
>     }
> } {code}
> DbH2ServerStartup.java:
>  
>  
> {code:java}
> package org.apache.ignite.examples.util;
> import java.io.IOException;
> import java.io.StringReader;
> import java.sql.SQLException;
> import org.apache.ignite.IgniteException;
> import org.h2.jdbcx.JdbcConnectionPool;
> import org.h2.tools.RunScript;
> import org.h2.tools.Server;
> /**
>  * Start H2 database TCP server in order to access sample in-memory database 
> from other processes.
>  */
> public class DbH2ServerStartup {
>     /** Create table script. */
>     private static final String CREATE_PERSON_TABLE =
>         "create table if not exists PERSON(id bigint AUTO_INCREMENT PRIMARY 
> KEY, first_name varchar(50), last_name varchar(50), created_time TIMESTAMP 
> DEFAULT CURRENT_TIMESTAMP);";
>     /** Sample data script. */
>     private static final String POPULATE_PERSON_TABLE =
>         "delete from PERSON;\n" +
>         "insert into PERSON(id, first_name, last_name) values(1, 'Johannes', 
> 'Kepler');\n" +
>         "insert into PERSON(id, first_name, last_name) values(2, 'Galileo', 
> 'Galilei');\n" +
>         "insert into PERSON(id, first_name, last_name) values(3, 'Henry', 
> 'More');\n" +
>         "insert into PERSON(id, first_name, last_name) values(4, 'Polish', 
> 'Brethren');\n" +
>         "insert into PERSON(id, first_name, last_name) values(5, 'Robert', 
> 'Boyle');\n" +
>         "insert into PERSON(id, first_name, last_name) values(6, 'Wilhelm', 
> 'Leibniz');";
>     /**
>      * 初始化数据库
>      *
>      * @throws SQLException if
>      */
>     public static void populateDatabase() throws SQLException {
>         // Try to connect to database TCP server.
>         JdbcConnectionPool dataSrc = 
> JdbcConnectionPool.create("jdbc:h2:tcp://localhost/mem:ExampleDb", "sa", "");
>         // Create Person table in database.
>         RunScript.execute(dataSrc.getConnection(), new 
> StringReader(CREATE_PERSON_TABLE));
>         // Populates Person table with sample data in database.
>         RunScript.execute(dataSrc.getConnection(), new 
> StringReader(POPULATE_PERSON_TABLE));
>     }
>     /**
>      * Start H2 database TCP server.
>      *
>      * @param args Command line arguments, none required.
>      * @throws IgniteException If start H2 database TCP server failed.
>      */
>     public static void main(String[] args) throws IgniteException {
>         try {
>             // Start H2 database TCP server in order to access sample 
> in-memory database from other processes.
>             Server.createTcpServer("-tcpDaemon").start();
>             Server.createWebServer("-webDaemon").start();
>             populateDatabase();
>         }
>         catch (SQLException e) {
>             throw new IgniteException("Failed to start database TCP server", 
> e);
>         }
>         try {
>             do {
>                 System.out.println("Type 'q' and press 'Enter' to stop H2 TCP 
> server...");
>             }
>             while ('q' != System.in.read());
>         }
>         catch (IOException ignored) {
>             // No-op.
>         }
>     }
> }
>  {code}
>  
>  
>  



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to