适用于 Hazelcast 的可移植版本:将日期转换为长抛出谓词中的异常



我正在尝试使用com.hazelcast.nio.serialization.VersionedPortable进行客户类的序列化。默认情况下,这不支持日期序列化。所以我们需要将其转换为长

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

at idToCustomerMap.values(andPredicate);我收到以下异常。

java.lang.IllegalArgumentException: 无法将 [星期二 Jan 01 00:00:00 IST 1980] 转换为 long at com.hazelcast.query.impl.TypeConverters$LongConverter.convert(TypeConverters.java:159) at com.hazelcast.query.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)at com.hazelcast.query.Predicates$AndPredicate.filter(Predicates.java:477) at com.hazelcast.query.impl.IndexService.query(IndexService.java:97) at com.hazelcast.map.impl.operation.QueryOperation.run(QueryOperation.java:92) at com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.run(OperationRunnerImpl.java:137) at com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.run(OperationRunnerImpl.java:309) at com.hazelcast.spi.impl.operationexecutor.classic.OperationThread.processPacket(OperationThread.java:142) at com.hazelcast.spi.impl.operationexecutor.classic.OperationThread.process(OperationThread.java:115) at com.hazelcast.spi.impl.operationexecutor.classic.OperationThread.doRun(OperationThread.java:101) at com.hazelcast.spi.impl.operationexecutor.classic.OperationThread.run(OperationThread.java:76) 在 ------ 结束远程并开始本地堆栈跟踪------.(来源不明)at com.hazelcast.spi.impl.operationservice.impl.InvocationFuture.resolveApplicationResponse(InvocationFuture.java:384) at com.hazelcast.spi.impl.operationservice.impl.InvocationFuture.resolveApplicationResponseOrThrowException(InvocationFuture.java:334) at com.hazelcast.spi.impl.operationservice.impl.InvocationFuture.get(InvocationFuture.java:225) at com.hazelcast.spi.impl.operationservice.impl.InvocationFuture.get(InvocationFuture.java:204) at com.hazelcast.map.impl.client.AbstractMapQueryRequest.collectResults(AbstractMapQueryRequest.java:103) at com.hazelcast.map.impl.client.AbstractMapQueryRequest.invoke(AbstractMapQueryRequest.java:77) at com.hazelcast.client.impl.client.InvocationClientRequest.process(InvocationClientRequest.java:27) at com.hazelcast.client.impl.ClientEngineImpl$ClientPacketProcessor.processRequest(ClientEngineImpl.java:463) at com.hazelcast.client.impl.ClientEngineImpl$ClientPacketProcessor.run(ClientEngineImpl.java:379)at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(未知来源) at com.hazelcast.util.executor.HazelcastManagedThread.executeRun(HazelcastManagedThread.java:76) at com.hazelcast.util.executor.HazelcastManagedThread.run(HazelcastManagedThread.java:92) 在 ------ 结束远程并开始本地堆栈跟踪------.(来源不明) at com.hazelcast.client.spi.impl.ClientInvocationFuture.resolveResponse(ClientInvocationFuture.java:147) at com.hazelcast.client.spi.impl.ClientInvocationFuture.get(ClientInvocationFuture.java:114) at com.hazelcast.client.spi.impl.ClientInvocationFuture.get(ClientInvocationFuture.java:89) at com.hazelcast.client.spi.ClientProxy.invoke(ClientProxy.java:151) at com.hazelcast.client.proxy.ClientMapProxy.values(ClientMapProxy.java:837) at com.foo.hazelcast.client.services.CustomerServiceImpl.findCustomersByDob(CustomerServiceImpl.java:99)at com.foo.hazelcast.client.services.CustomerServiceTest.searchCustomersByDobRange(CustomerServiceTest.java:104) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(未知来源) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statement.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statement.RunBefores.evaluate(RunBefores.java:26) at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) at org.springframework.test.context.junit4.statement.SpringRepeat.evaluate(SpringRepeat.java:84) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at 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 与谓词中的日期进行比较时会感到困惑。

不过,这种方法绝对不干净。有没有更干净的方法来避免在版本可移植中出现这种情况?

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

由于您写的日期很长,因此 Hazelcast 会识别该字段很长。只有您知道这是一个日期字段。然后,当您需要运行谓词时,由于您编写此字段的长度,Hazelcast 期望比较长值。这就是原因。

最新更新