Create two table with the same VALUE_TYPE

classic Classic list List threaded Threaded
5 messages Options
Surkov.Aleksandr Surkov.Aleksandr
Reply | Threaded
Open this post in threaded view
|

Create two table with the same VALUE_TYPE

This post was updated on .
I have a class MyObj. I want to use it for multiple tables. In the class
MyObj there is a field value whose type will be known at runtime, therefore
the type of this field is Object. I try to create two tables using the MyObj
class, but when an insert occurs in the second table, an exception occurs.

Ignite version 2.8.1

public class CreateTwoTablesWithDifferentSchemaTest extends
GridCommonAbstractTest {
    /** Create two tables/caches with the same VALUE_TYPE*/
    @Test
    public void executeTest() throws Exception {
        try (final Ignite server =
Ignition.start(Config.getServerConfiguration());
             final IgniteClient client = Ignition.startClient(new
ClientConfiguration()
                 .setAddresses(Config.SERVER)
                 .setBinaryConfiguration(new
BinaryConfiguration().setCompactFooter(true)))) {

            createTableAndInsert(client, "MyTable1", "int");
            createTableAndInsert(client, "MyTable2", "varchar");
        }
    }

    private void createTableAndInsert(IgniteClient client, String tableName,
String typeField) {
        /**
         * Can use tableName instead of MyObj.class.getName(), but then you
can’t use the {@link ClientCache#get(Object)} method.
         * */
        client.query(new SqlFieldsQuery("CREATE TABLE IF NOT EXISTS " +
tableName + " (id int primary key, value " + typeField + ") " +
            "WITH \"VALUE_TYPE=" + MyObj.class.getName() + ",CACHE_NAME=" +
tableName + ",atomicity=transactional,template=partitioned\"")
        ).getAll();

        final Object value = "int".equals(typeField) ? 1 : "value_1";

        try {
            client.query(new SqlFieldsQuery("INSERT INTO " + tableName + "
(id, value) values(?,?)")
                .setArgs(1, value)
            ).getAll();
        } catch (Exception e) {
            e.printStackTrace();
            fail();
        }
    }

    static class MyObj {
        private Integer id;
        //It is assumed that the type of this property will depend on the
type of field in the table.
        private Object value;

        public MyObj(Integer id, Object value) {
            this.id = id;
            this.value = value;
        }
    }
}

Can I somehow solve this problem?



--
Sent from: http://apache-ignite-users.70518.x6.nabble.com/
Surkov.Aleksandr Surkov.Aleksandr
Reply | Threaded
Open this post in threaded view
|

Re: Create two table with the same VALUE_TYPE

Exception:
[14:34:21,079][SEVERE][client-connector-#81%7e375abc-4354-4c8d-a9e1-d193171826c0%][ClientListenerNioListener]
Failed to process client request
[req=o.a.i.i.processors.platform.client.cache.ClientCacheSqlFieldsQueryRequest@78f07b83]
class org.apache.ignite.binary.BinaryObjectException: Wrong value has been
set
[typeName=org.apache.ignite.internal.processors.cache.CreateTwoTablesWithDifferentSchemaTest$MyObj,
fieldName=VALUE, fieldType=int, assignedValueType=String]
        at
org.apache.ignite.internal.binary.builder.BinaryObjectBuilderImpl.checkMetadata(BinaryObjectBuilderImpl.java:433)
        at
org.apache.ignite.internal.binary.builder.BinaryObjectBuilderImpl.serializeTo(BinaryObjectBuilderImpl.java:321)
        at
org.apache.ignite.internal.binary.builder.BinaryObjectBuilderImpl.build(BinaryObjectBuilderImpl.java:188)
        at
org.apache.ignite.internal.processors.query.h2.dml.UpdatePlan.processRow(UpdatePlan.java:279)
        at
org.apache.ignite.internal.processors.query.h2.dml.DmlUtils.dmlDoInsert(DmlUtils.java:195)
        at
org.apache.ignite.internal.processors.query.h2.dml.DmlUtils.processSelectResult(DmlUtils.java:168)
        at
org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.executeUpdateNonTransactional(IgniteH2Indexing.java:2899)
        at
org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.executeUpdate(IgniteH2Indexing.java:2753)
        at
org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.executeUpdateDistributed(IgniteH2Indexing.java:2683)
        at
org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.executeDml(IgniteH2Indexing.java:1186)
        at
org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.querySqlFields(IgniteH2Indexing.java:1112)
        at
org.apache.ignite.internal.processors.query.GridQueryProcessor$4.applyx(GridQueryProcessor.java:2574)
        at
org.apache.ignite.internal.processors.query.GridQueryProcessor$4.applyx(GridQueryProcessor.java:2570)
        at
org.apache.ignite.internal.util.lang.IgniteOutClosureX.apply(IgniteOutClosureX.java:36)
        at
org.apache.ignite.internal.processors.query.GridQueryProcessor.executeQuery(GridQueryProcessor.java:3097)
        at
org.apache.ignite.internal.processors.query.GridQueryProcessor.lambda$querySqlFields$1(GridQueryProcessor.java:2590)
        at
org.apache.ignite.internal.processors.query.GridQueryProcessor.executeQuerySafe(GridQueryProcessor.java:2628)
        at
org.apache.ignite.internal.processors.query.GridQueryProcessor.querySqlFields(GridQueryProcessor.java:2564)
        at
org.apache.ignite.internal.processors.query.GridQueryProcessor.querySqlFields(GridQueryProcessor.java:2491)
        at
org.apache.ignite.internal.processors.query.GridQueryProcessor.querySqlFields(GridQueryProcessor.java:2447)
        at
org.apache.ignite.internal.processors.platform.client.cache.ClientCacheSqlFieldsQueryRequest.process(ClientCacheSqlFieldsQueryRequest.java:110)
        at
org.apache.ignite.internal.processors.platform.client.ClientRequestHandler.handle(ClientRequestHandler.java:99)
        at
org.apache.ignite.internal.processors.odbc.ClientListenerNioListener.onMessage(ClientListenerNioListener.java:200)
        at
org.apache.ignite.internal.processors.odbc.ClientListenerNioListener.onMessage(ClientListenerNioListener.java:54)
        at
org.apache.ignite.internal.util.nio.GridNioFilterChain$TailFilter.onMessageReceived(GridNioFilterChain.java:279)
        at
org.apache.ignite.internal.util.nio.GridNioFilterAdapter.proceedMessageReceived(GridNioFilterAdapter.java:109)
        at
org.apache.ignite.internal.util.nio.GridNioAsyncNotifyFilter$3.body(GridNioAsyncNotifyFilter.java:97)
        at
org.apache.ignite.internal.util.worker.GridWorker.run(GridWorker.java:120)
        at
org.apache.ignite.internal.util.worker.GridWorkerPool$1.run(GridWorkerPool.java:70)
        at
java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at
java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.base/java.lang.Thread.run(Thread.java:834)
org.apache.ignite.internal.client.thin.ClientServerError: Ignite failed to
process request [4]: Wrong value has been set
[typeName=org.apache.ignite.internal.processors.cache.CreateTwoTablesWithDifferentSchemaTest$MyObj,
fieldName=VALUE, fieldType=int, assignedValueType=String] (server status
code [1])
        at
org.apache.ignite.internal.client.thin.TcpClientChannel.processNextMessage(TcpClientChannel.java:390)
        at
org.apache.ignite.internal.client.thin.TcpClientChannel.lambda$initReceiverThread$0(TcpClientChannel.java:314)
        at java.base/java.lang.Thread.run(Thread.java:834)



--
Sent from: http://apache-ignite-users.70518.x6.nabble.com/
Nikolay Izhikov Nikolay Izhikov
Reply | Threaded
Open this post in threaded view
|

Re: Create two table with the same VALUE_TYPE

Hello, Alexander.

> Can I somehow solve this problem?

You can't use same VALUE_TYPE for two tables with inconsistent field type.
This happens because VALUE_TYPE name actually used to specify `BinaryObjectType` name.

After it all rows with the same VALUE_TYPE name checked according to the first created row.
Please, note, that `VALUE_TYPE` can be a random string, not a java class name:

"The name should correspond to a Java, .NET or C++ class, or it can be a random one if BinaryObjects is used instead of a custom class"





вт, 7 июл. 2020 г. в 15:31, Surkov.Aleksandr <[hidden email]>:
Exception:
[14:34:21,079][SEVERE][client-connector-#81%7e375abc-4354-4c8d-a9e1-d193171826c0%][ClientListenerNioListener]
Failed to process client request
[req=o.a.i.i.processors.platform.client.cache.ClientCacheSqlFieldsQueryRequest@78f07b83]
class org.apache.ignite.binary.BinaryObjectException: Wrong value has been
set
[typeName=org.apache.ignite.internal.processors.cache.CreateTwoTablesWithDifferentSchemaTest$MyObj,
fieldName=VALUE, fieldType=int, assignedValueType=String]
        at
org.apache.ignite.internal.binary.builder.BinaryObjectBuilderImpl.checkMetadata(BinaryObjectBuilderImpl.java:433)
        at
org.apache.ignite.internal.binary.builder.BinaryObjectBuilderImpl.serializeTo(BinaryObjectBuilderImpl.java:321)
        at
org.apache.ignite.internal.binary.builder.BinaryObjectBuilderImpl.build(BinaryObjectBuilderImpl.java:188)
        at
org.apache.ignite.internal.processors.query.h2.dml.UpdatePlan.processRow(UpdatePlan.java:279)
        at
org.apache.ignite.internal.processors.query.h2.dml.DmlUtils.dmlDoInsert(DmlUtils.java:195)
        at
org.apache.ignite.internal.processors.query.h2.dml.DmlUtils.processSelectResult(DmlUtils.java:168)
        at
org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.executeUpdateNonTransactional(IgniteH2Indexing.java:2899)
        at
org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.executeUpdate(IgniteH2Indexing.java:2753)
        at
org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.executeUpdateDistributed(IgniteH2Indexing.java:2683)
        at
org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.executeDml(IgniteH2Indexing.java:1186)
        at
org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.querySqlFields(IgniteH2Indexing.java:1112)
        at
org.apache.ignite.internal.processors.query.GridQueryProcessor$4.applyx(GridQueryProcessor.java:2574)
        at
org.apache.ignite.internal.processors.query.GridQueryProcessor$4.applyx(GridQueryProcessor.java:2570)
        at
org.apache.ignite.internal.util.lang.IgniteOutClosureX.apply(IgniteOutClosureX.java:36)
        at
org.apache.ignite.internal.processors.query.GridQueryProcessor.executeQuery(GridQueryProcessor.java:3097)
        at
org.apache.ignite.internal.processors.query.GridQueryProcessor.lambda$querySqlFields$1(GridQueryProcessor.java:2590)
        at
org.apache.ignite.internal.processors.query.GridQueryProcessor.executeQuerySafe(GridQueryProcessor.java:2628)
        at
org.apache.ignite.internal.processors.query.GridQueryProcessor.querySqlFields(GridQueryProcessor.java:2564)
        at
org.apache.ignite.internal.processors.query.GridQueryProcessor.querySqlFields(GridQueryProcessor.java:2491)
        at
org.apache.ignite.internal.processors.query.GridQueryProcessor.querySqlFields(GridQueryProcessor.java:2447)
        at
org.apache.ignite.internal.processors.platform.client.cache.ClientCacheSqlFieldsQueryRequest.process(ClientCacheSqlFieldsQueryRequest.java:110)
        at
org.apache.ignite.internal.processors.platform.client.ClientRequestHandler.handle(ClientRequestHandler.java:99)
        at
org.apache.ignite.internal.processors.odbc.ClientListenerNioListener.onMessage(ClientListenerNioListener.java:200)
        at
org.apache.ignite.internal.processors.odbc.ClientListenerNioListener.onMessage(ClientListenerNioListener.java:54)
        at
org.apache.ignite.internal.util.nio.GridNioFilterChain$TailFilter.onMessageReceived(GridNioFilterChain.java:279)
        at
org.apache.ignite.internal.util.nio.GridNioFilterAdapter.proceedMessageReceived(GridNioFilterAdapter.java:109)
        at
org.apache.ignite.internal.util.nio.GridNioAsyncNotifyFilter$3.body(GridNioAsyncNotifyFilter.java:97)
        at
org.apache.ignite.internal.util.worker.GridWorker.run(GridWorker.java:120)
        at
org.apache.ignite.internal.util.worker.GridWorkerPool$1.run(GridWorkerPool.java:70)
        at
java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at
java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.base/java.lang.Thread.run(Thread.java:834)
org.apache.ignite.internal.client.thin.ClientServerError: Ignite failed to
process request [4]: Wrong value has been set
[typeName=org.apache.ignite.internal.processors.cache.CreateTwoTablesWithDifferentSchemaTest$MyObj,
fieldName=VALUE, fieldType=int, assignedValueType=String] (server status
code [1])
        at
org.apache.ignite.internal.client.thin.TcpClientChannel.processNextMessage(TcpClientChannel.java:390)
        at
org.apache.ignite.internal.client.thin.TcpClientChannel.lambda$initReceiverThread$0(TcpClientChannel.java:314)
        at java.base/java.lang.Thread.run(Thread.java:834)



--
Sent from: http://apache-ignite-users.70518.x6.nabble.com/
Surkov.Aleksandr Surkov.Aleksandr
Reply | Threaded
Open this post in threaded view
|

Re: Create two table with the same VALUE_TYPE

Surkov.Aleksandr Surkov.Aleksandr
Reply | Threaded
Open this post in threaded view
|

Re: Create two table with the same VALUE_TYPE

This post was updated on .
In reply to this post by Nikolay Izhikov
Nikolay, I think that one of the solutions could be to create the
corresponding classes:

class MyObjInteger {
        private Integer id;
        private Integer value;
}

class MyObjString {
        private Integer id;
        private String value;
}

Maybe there is another solution? Because I look org.apache.ignite.internal.binary.BinaryMetadata # schemaIds - this is Set.
There may be situations when there will be several schemes for the same type?



--
Sent from: http://apache-ignite-users.70518.x6.nabble.com/