1

我正在尝试使用 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); 我收到以下异常。

java.lang.IllegalArgumentException:无法在 com.hazelcast.query.impl.TypeConverters$LongConverter.convert(TypeConverters.java:159) 在 com.hazelcast.query 将 [Tue Jan 01 00:00:00 IST 1980] 转换为 long。 impl.IndexImpl.convert(IndexImpl.java:154) at com.hazelcast.query.impl.IndexImpl.getSubRecords(IndexImpl.java:148) at 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。在 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。在 com.hazelcast.util.executor.HazelcastManagedThread.executeRun(HazelcastManagedThread.java:76) 在 com.hazelcast.util.executor.HazelcastManagedThread.run(HazelcastManagedThread) 的 java.lang.Thread.run(Unknown Source) 运行(Unknown Source) .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.CustomerServiceTest.searchCustomersByDobRange(CustomerServiceTest.java:104) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl。在 org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 在 java.lang.reflect.Method.invoke(Unknown Source) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 调用(Unknown Source) ) 在 org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 在 org.junit.internal.runners 的 org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)。 org.junit.internal 上的 statements.InvokeMethod.evaluate(InvokeMethod.java:17)。在 org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) 在 org.springframework.test.context.junit4.statements 的 runners.statements.RunBefores.evaluate(RunBefores.java:26)。 RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84) at 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。在 org.junit.runners.org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 在 org.junit.runners.schedule(ParentRunner.java:71).runChildren(ParentRunner.java:288)。 org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) 的 ParentRunner$2.evaluate(ParentRunner.java:268) 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。在 org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.runTests(RemoteTestRunner.java:459) 运行(TestExecution.java:38) java:675) 在 org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 在 org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

虽然很明显异常是因为对 Date 的这种特殊处理,但我想知道 TypeConversion 的确切原因。我读到 Hazelcast 以序列化形式维护数据。所以这应该不是问题吧?

另外,我该如何克服这个问题?

编辑:我通过在谓词中传递 date.getTime() 解决了这个问题

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);
}

我猜这是因为 hazelcast 以序列化形式维护数据,因此在尝试将 long 与谓词中的日期进行比较时会感到困惑。

不过,这种方法绝对不干净。有没有更简洁的方法可以在版本便携版中避免这种情况?

4

1 回答 1

2

@vinodhini-chockalingam,Portable旨在使用不同的语言,而不仅仅是 Java。因此,您可以从 NodeJs 写入一个值,然后使用 Portable 从 Java 读取它。这就是为什么您不能java.util.Date直接将对象写入 Portable 的原因。您需要将其转换为支持的类型。

并且由于您将 Date 写的很长,Hazelcast 识别该字段的时间也很长。只有您知道这是一个日期字段。然后当你需要运行一个谓词时,由于你把这个字段写成 long,Hazelcast 期望一个 long 值来比较。这就是原因。

于 2017-10-16T07:17:49.797 回答