Портативная версия для Hazelcast: преобразование даты в длинное исключение в предикатах

Я пытаюсь использовать com.hazelcast.nio.serialization.VersionedPortable для сериализации для класса Customer. Это не поддерживает сериализацию даты по умолчанию. Поэтому нам нужно преобразовать его в Long

@Override
public void writePortable(PortableWriter writer) throws IOException {
    if (dob != null) {
        Long dobLong = dob.getTime();
        writer.writeLong(DOB_FIELD, dobLong);
    } else {
        writer.writeLong(DOB_FIELD, -1);
    }
}

@Override
public void readPortable(PortableReader reader) throws IOException {
    if (reader.hasField(DOB_FIELD)) {
        Long dobLong = reader.readLong(DOB_FIELD);
        dob = dobLong == -1 ? null : new Date(dobLong);
    }
}

В CustomerService у меня есть findCustomersByDob, который использует com.hazelcast.query.Predicate.

public Collection<Customer> findCustomersByDob(Date dobStart, Date dobEnd) {
    Predicate dobStartPredicate = Predicates.greaterEqual("dob", dobStart);
    Predicate dobEndPredicate = Predicates.lessThan("dob", dobEnd);
    Predicate andPredicate = Predicates.and(dobStartPredicate, dobEndPredicate);
    return idToCustomerMap.values(andPredicate);
}

в idToCustomerMap.values(andPredicate); Я получаю следующее исключение.

Хотя ясно, что исключение связано с этой специальной обработкой даты, я хотел бы знать точную причину преобразования типа здесь. Я читал, что Hazelcast поддерживает данные в сериализованной форме. Так что это не должно быть проблемой, верно?

РЕДАКТИРОВАТЬ: я исправил эту проблему, передав date.getTime() также в предикатах

@vinodhini-chockalingam,
@Override
public void writePortable(PortableWriter writer) throws IOException {
    if (dob != null) {
        Long dobLong = dob.getTime();
        writer.writeLong(DOB_FIELD, dobLong);
    } else {
        writer.writeLong(DOB_FIELD, -1);
    }
}

@Override
public void readPortable(PortableReader reader) throws IOException {
    if (reader.hasField(DOB_FIELD)) {
        Long dobLong = reader.readLong(DOB_FIELD);
        dob = dobLong == -1 ? null : new Date(dobLong);
    }
}
предназначен для работы с разными языками, а не только с Java. Таким образом, вы можете записать значение из NodeJs и прочитать его из Java с помощью Portable. Вот почему вы не можете напрямую записать объект
public Collection<Customer> findCustomersByDob(Date dobStart, Date dobEnd) {
    Predicate dobStartPredicate = Predicates.greaterEqual("dob", dobStart);
    Predicate dobEndPredicate = Predicates.lessThan("dob", dobEnd);
    Predicate andPredicate = Predicates.and(dobStartPredicate, dobEndPredicate);
    return idToCustomerMap.values(andPredicate);
}
в Portable. Вам нужно преобразовать его в поддерживаемый тип.

Я предполагаю, что это связано с тем, что hazelcast поддерживает данные в сериализованной форме и, следовательно, путается, когда пытается сравнить long с датой в предикате.

public Collection<Customer> findCustomersByDob(Date dobStart, Date dobEnd) {
    Predicate dobStartPredicate = Predicates.greaterEqual("dob", dobStart.getTime());
    Predicate dobEndPredicate = Predicates.lessThan("dob", dobEnd.getTime());
    Predicate andPredicate = Predicates.and(dobStartPredicate, dobEndPredicate);
    return idToCustomerMap.values(andPredicate);
}

Тем не менее, этот подход определенно не чище. Есть ли более чистый способ избежать этого в версии Portable?

Кроме того, как мне преодолеть эту проблему?


person Vinodhini Chockalingam    schedule 20.07.2017    source источник


Ответы (1)


И поскольку вы пишете дату такой длины, Hazelcast распознает это поле как длинное. Только вы знаете, что это поле даты. Затем, когда вам нужно запустить предикат, поскольку вы пишете это поле как длинное, Hazelcast ожидает длинное значение для сравнения. Это причина.

java.lang.IllegalArgumentException: невозможно преобразовать [вт, 01 января, 00:00:00 IST 1980] в long на com.hazelcast.query.impl.TypeConverters$LongConverter.convert(TypeConverters.java:159) на com.hazelcast.query. impl.IndexImpl.convert(IndexImpl.java:154) в com.hazelcast.query.impl.IndexImpl.getSubRecords(IndexImpl.java:148) в com.hazelcast.query.Predicates$GreaterLessPredicate.filter(Predicates.java:691) в com.hazelcast.query.Predicates$AndPredicate.filter(Predicates.java:477) в com.hazelcast.query.impl.IndexService.query(IndexService.java:97) в com.hazelcast.map.impl.operation.QueryOperation .run(QueryOperation.java:92) в com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.run(OperationRunnerImpl.java:137) в com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.run(OperationRunnerImpl .java:309) в com.hazelcast.spi.impl.operationexecutor.classic.OperationThread.processPacket(OperationThread.java:142) в com.hazelcast.spi.impl.operationexecutor.classic.OperationThread.process(OperationThread.java:115) в com.hazelcast.spi.impl.operationexecutor.classic.OperationThread.doRun(OperationThread.java:101) в com.hazelcast .spi.impl.operationexecutor.classic.OperationThread.run(OperationThread.java:76) в ------ Завершение удаленного и начало локальной трассировки стека ------.(Неизвестный источник) в com.hazelcast. spi.impl.operationservice.impl.InvocationFuture.resolveApplicationResponse(InvocationFuture.java:384) в com.hazelcast.spi.impl.operationservice.impl.InvocationFuture.resolveApplicationResponseOrThrowException(InvocationFuture.java:334) в com.hazelcast.spi.impl. operationservice.impl.InvocationFuture.get(InvocationFuture.java:225) в com.hazelcast.spi.impl.operationservice.impl.InvocationFuture.get(InvocationFuture.java:204) в com.hazelcast.map.impl.client.AbstractMapQueryRequest. collectResults(AbstractMapQueryRequest.java:103) на com.hazelcast.map .impl.client.AbstractMapQueryRequest.invoke(AbstractMapQueryRequest.java:77) в com.hazelcast.client.impl.client.InvocationClientRequest.process(InvocationClientRequest.java:27) в com.hazelcast.client.impl.ClientEngineImpl$ClientPacketProcessor.processRequest (ClientEngineImpl.java:463) в com.hazelcast.client.impl.ClientEngineImpl$ClientPacketProcessor.run(ClientEngineImpl.java:379) в java.util.concurrent.ThreadPoolExecutor.runWorker(неизвестный источник) в java.util.concurrent. ThreadPoolExecutor$Worker.run(неизвестный источник) на java.lang.Thread.run(неизвестный источник) на com.hazelcast.util.executor.HazelcastManagedThread.executeRun(HazelcastManagedThread.java:76) на com.hazelcast.util.executor.HazelcastManagedThread .run(HazelcastManagedThread.java:92) в ------ Завершение удаленного и начало локальной трассировки стека ------.(Неизвестный источник) в com.hazelcast.client.spi.impl.ClientInvocationFuture.resolveResponse( ClientInvocationFuture.java:147) по адресу com.hazelcast.client.spi.impl.ClientInvocationFuture.get(ClientInvocationFuture.java:114) по адресу com.hazelcast.client.spi.impl.ClientInvocationFuture.get(ClientInvocationFuture.java:89) по адресу com .hazelcast.client.spi.ClientProxy.invoke(ClientProxy.java:151) в com.hazelcast.client.proxy.ClientMapProxy.values(ClientMapProxy.java:837) в com.foo.hazelcast.client.services.CustomerServiceImpl.findCustomersByDob (CustomerServiceImpl.java:99) на com.foo.hazelcast.client.services.CustomerSe rviceTest.searchCustomersByDobRange(CustomerServiceTest.java:104) в sun.reflect.NativeMethodAccessorImpl.invoke0(собственный метод) в sun.reflect.NativeMethodAccessorImpl.invoke(неизвестный источник) в sun.reflect.DelegatingMethodAccessorImpl.invoke(неизвестный источник) в java.lang .reflect.Method.invoke(неизвестный источник) в org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) в org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) ) в org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) в org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) в org.junit.internal.runners. Statements.RunBefores.evaluate(RunBefores.java:26) в org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) в org.springframework.test.context.junit4.statements.RunAfterTestM ethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) в org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84) в org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) в org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252) в org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94) в org.junit.runners. ParentRunner$3.run(ParentRunner.java:290) в org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) в org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) в org.junit .runners.ParentRunner.access$000(ParentRunner.java:58) в org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) в org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks .java:61) в org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) в org.junit.runners.ParentRunner.run(ParentRunner.java:363) в org.springframework. test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191) в org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) в org.eclipse.jdt.internal.junit. runner.TestExecution.run(TestExecution.java:38) на org.eclipse.jdt.inter nal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) в org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) в org.eclipse.jdt.internal.junit. runner.RemoteTestRunner.run(RemoteTestRunner.java:382) в org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

person Gokhan Oner    schedule 16.10.2017